diff options
Diffstat (limited to 'src/core/initrd')
221 files changed, 5181 insertions, 0 deletions
diff --git a/src/core/initrd/meson.build b/src/core/initrd/meson.build new file mode 100644 index 00000000..bd590e8c --- /dev/null +++ b/src/core/initrd/meson.build @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +libnmi_core = static_library( + 'nmi-core', + sources: files( + 'nmi-cmdline-reader.c', + 'nmi-dt-reader.c', + 'nmi-ibft-reader.c', + ), + dependencies: core_default_dep, + c_args: daemon_c_flags, +) + +executable( + 'nm-initrd-generator', + 'nm-initrd-generator.c', + dependencies: core_default_dep, + c_args: daemon_c_flags, + link_with: [ + libNetworkManagerBase, + libnmi_core, + ], + link_args: ldflags_linker_script_binary, + link_depends: linker_script_binary, + install: true, + install_dir: nm_libexecdir, +) + +if enable_tests + subdir('tests') +endif diff --git a/src/core/initrd/nm-initrd-generator.c b/src/core/initrd/nm-initrd-generator.c new file mode 100644 index 00000000..18c7258a --- /dev/null +++ b/src/core/initrd/nm-initrd-generator.c @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "src/core/nm-default-daemon.h" +#include "nm-core-utils.h" +#include "nm-core-internal.h" +#include "nm-keyfile-internal.h" +#include "nm-initrd-generator.h" +#include "nm-glib-aux/nm-io-utils.h" +#include "nm-config.h" + +/*****************************************************************************/ + +#define _NMLOG(level, domain, ...) \ + nm_log((level), \ + (domain), \ + NULL, \ + NULL, \ + "initrd-generator: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +/*****************************************************************************/ + +static void +output_conn(gpointer key, gpointer value, gpointer user_data) +{ + const char * basename = key; + NMConnection * connection = value; + char * connections_dir = user_data; + nm_auto_unref_keyfile GKeyFile *file = NULL; + gs_free char * data = NULL; + gs_free_error GError *error = NULL; + gsize len; + + if (!nm_connection_normalize(connection, NULL, NULL, &error)) + goto err_out; + + file = nm_keyfile_write(connection, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); + if (file == NULL) + goto err_out; + + data = g_key_file_to_data(file, &len, &error); + if (!data) + goto err_out; + + if (connections_dir) { + gs_free char *filename = NULL; + gs_free char *full_filename = NULL; + + filename = nm_keyfile_utils_create_filename(basename, TRUE); + full_filename = g_build_filename(connections_dir, filename, NULL); + + if (!nm_utils_file_set_contents(full_filename, data, len, 0600, NULL, &error)) + goto err_out; + } else + g_print("\n*** Connection '%s' ***\n\n%s", basename, data); + + return; +err_out: + g_print("%s\n", error->message); +} + +#define DEFAULT_SYSFS_DIR "/sys" +#define DEFAULT_INITRD_DATA_DIR NMRUNDIR "/initrd" +#define DEFAULT_RUN_CONFIG_DIR NMRUNDIR "/conf.d" + +int +main(int argc, char *argv[]) +{ + GHashTable * connections; + gs_free char * connections_dir = NULL; + gs_free char * initrd_dir = NULL; + gs_free char * sysfs_dir = NULL; + gs_free char * run_config_dir = NULL; + gboolean dump_to_stdout = FALSE; + gs_strfreev char **remaining = NULL; + GOptionEntry option_entries[] = { + {"connections-dir", + 'c', + 0, + G_OPTION_ARG_FILENAME, + &connections_dir, + "Output connection directory", + NM_KEYFILE_PATH_NAME_RUN}, + {"initrd-data-dir", + 'i', + 0, + G_OPTION_ARG_FILENAME, + &initrd_dir, + "Output initrd data directory", + DEFAULT_INITRD_DATA_DIR}, + {"sysfs-dir", + 'd', + 0, + G_OPTION_ARG_FILENAME, + &sysfs_dir, + "The sysfs mount point", + DEFAULT_SYSFS_DIR}, + {"run-config-dir", + 'r', + 0, + G_OPTION_ARG_FILENAME, + &run_config_dir, + "Output config directory", + DEFAULT_RUN_CONFIG_DIR}, + {"stdout", + 's', + 0, + G_OPTION_ARG_NONE, + &dump_to_stdout, + "Dump connections to standard output", + NULL}, + {G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &remaining, NULL, NULL}, + {NULL}}; + nm_auto_free_option_context GOptionContext *option_context = NULL; + gs_free_error GError *error = NULL; + gs_free char * hostname = NULL; + int errsv; + gint64 carrier_timeout_sec = 0; + + option_context = g_option_context_new( + "-- [ip=...] [rd.route=...] [bridge=...] [bond=...] [team=...] [vlan=...] " + "[bootdev=...] [nameserver=...] [rd.peerdns=...] [rd.bootif=...] [BOOTIF=...] " + "[rd.znet=...] [rd.net.timeout.carrier=...] ... "); + + g_option_context_set_summary(option_context, "Generate early NetworkManager configuration."); + g_option_context_set_description( + option_context, + "This tool scans the command line for options relevant to network\n" + "configuration and creates configuration files for an early instance\n" + "of NetworkManager run from the initial ramdisk during early boot."); + g_option_context_add_main_entries(option_context, option_entries, GETTEXT_PACKAGE); + + if (!g_option_context_parse(option_context, &argc, &argv, &error)) { + _LOGW(LOGD_CORE, "%s", error->message); + return 1; + } + + if (!remaining) { + /* No arguments, no networking. Don't bother. */ + return 0; + } + + if (!connections_dir) + connections_dir = g_strdup(NM_KEYFILE_PATH_NAME_RUN); + if (!sysfs_dir) + sysfs_dir = g_strdup(DEFAULT_SYSFS_DIR); + if (!initrd_dir) + initrd_dir = g_strdup(DEFAULT_INITRD_DATA_DIR); + if (!run_config_dir) + run_config_dir = g_strdup(DEFAULT_RUN_CONFIG_DIR); + + connections = nmi_cmdline_reader_parse(sysfs_dir, + (const char *const *) remaining, + &hostname, + &carrier_timeout_sec); + + if (dump_to_stdout) { + nm_clear_g_free(&connections_dir); + nm_clear_g_free(&initrd_dir); + nm_clear_g_free(&run_config_dir); + if (hostname) + g_print("\n*** Hostname '%s' ***\n", hostname); + if (carrier_timeout_sec != 0) + g_print("\n*** Carrier Wait Timeout %" G_GINT64_FORMAT " sec ***\n", + carrier_timeout_sec); + } else { + if (g_mkdir_with_parents(connections_dir, 0755) != 0) { + errsv = errno; + _LOGW(LOGD_CORE, "%s: %s", connections_dir, nm_strerror_native(errsv)); + return 1; + } + if (g_mkdir_with_parents(initrd_dir, 0755) != 0) { + errsv = errno; + _LOGW(LOGD_CORE, "%s: %s", initrd_dir, nm_strerror_native(errsv)); + return 1; + } + if (g_mkdir_with_parents(run_config_dir, 0755) != 0) { + errsv = errno; + _LOGW(LOGD_CORE, "%s: %s", run_config_dir, nm_strerror_native(errsv)); + return 1; + } + + if (hostname) { + gs_free char *hostname_file = NULL; + gs_free char *data = NULL; + + hostname_file = g_strdup_printf("%s/hostname", initrd_dir); + data = g_strdup_printf("%s\n", hostname); + + if (!g_file_set_contents(hostname_file, data, strlen(data), &error)) { + _LOGW(LOGD_CORE, "%s: %s", hostname_file, error->message); + return 1; + } + } + if (carrier_timeout_sec != 0) { + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + gs_free char * filename = NULL; + + keyfile = g_key_file_new(); + g_key_file_set_list_separator(keyfile, NM_CONFIG_KEYFILE_LIST_SEPARATOR); + filename = g_strdup_printf("%s/15-carrier-timeout.conf", run_config_dir); + + g_key_file_set_value(keyfile, + NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE "-15-carrier-timeout", + NM_CONFIG_KEYFILE_KEY_MATCH_DEVICE, + "*"); + g_key_file_set_int64(keyfile, + NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE "-15-carrier-timeout", + NM_CONFIG_KEYFILE_KEY_DEVICE_CARRIER_WAIT_TIMEOUT, + carrier_timeout_sec * 1000); + + if (!g_key_file_save_to_file(keyfile, filename, &error)) { + _LOGW(LOGD_CORE, "%s: %s", filename, error->message); + return 1; + } + } + } + + g_hash_table_foreach(connections, output_conn, connections_dir); + g_hash_table_destroy(connections); + + return 0; +} diff --git a/src/core/initrd/nm-initrd-generator.h b/src/core/initrd/nm-initrd-generator.h new file mode 100644 index 00000000..56dcfd68 --- /dev/null +++ b/src/core/initrd/nm-initrd-generator.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014, 2018 Red Hat, Inc. + */ + +#ifndef __NM_INITRD_GENERATOR_H__ +#define __NM_INITRD_GENERATOR_H__ + +#include "nm-connection.h" +#include "nm-utils.h" + +#define NMI_WAIT_DEVICE_TIMEOUT_MS 60000 + +static inline int +get_ip_address_family(const char *str, gboolean with_prefix) +{ + int addr_family; + + if (!str) + return AF_UNSPEC; + + if (with_prefix) { + if (nm_utils_parse_inaddr_prefix_bin(AF_UNSPEC, str, &addr_family, NULL, NULL)) + return addr_family; + } else { + if (nm_utils_parse_inaddr_bin(AF_UNSPEC, str, &addr_family, NULL)) + return addr_family; + } + + return AF_UNSPEC; +} + +GHashTable *nmi_ibft_read(const char *sysfs_dir); + +gboolean +nmi_ibft_update_connection_from_nic(NMConnection *connection, GHashTable *nic, GError **error); + +NMConnection *nmi_dt_reader_parse(const char *sysfs_dir); + +GHashTable *nmi_cmdline_reader_parse(const char * sysfs_dir, + const char *const *argv, + char ** hostname, + gint64 * carrier_timeout_sec); + +#endif /* __NM_INITRD_GENERATOR_H__ */ diff --git a/src/core/initrd/nmi-cmdline-reader.c b/src/core/initrd/nmi-cmdline-reader.c new file mode 100644 index 00000000..d95b0f9b --- /dev/null +++ b/src/core/initrd/nmi-cmdline-reader.c @@ -0,0 +1,1255 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "src/core/nm-default-daemon.h" + +#include <linux/if_ether.h> +#include <linux/if_infiniband.h> + +#include "nm-core-internal.h" +#include "nm-initrd-generator.h" +#include "systemd/nm-sd-utils-shared.h" + +/*****************************************************************************/ + +#define _NMLOG(level, domain, ...) \ + nm_log((level), \ + (domain), \ + NULL, \ + NULL, \ + "cmdline-reader: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +/*****************************************************************************/ + +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; + + /* Parameters to be set for all connections */ + gboolean ignore_auto_dns; + int dhcp_timeout; + char * dhcp4_vci; + + gint64 carrier_timeout_sec; +} Reader; + +static Reader * +reader_new(void) +{ + Reader *reader; + + reader = g_slice_new(Reader); + *reader = (Reader){ + .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; +} + +static GHashTable * +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); + 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 * +reader_create_connection(Reader * reader, + const char * basename, + const char * id, + const char * ifname, + const char * mac, + const char * type_name, + NMConnectionMultiConnect multi_connect) +{ + NMConnection *connection; + NMSetting * setting; + + connection = reader_add_connection(reader, basename, nm_simple_connection_new()); + + /* Start off assuming dynamic IP configurations. */ + + setting = nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, setting); + g_object_set(setting, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, + reader->ignore_auto_dns, + NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, + reader->dhcp_timeout, + NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER, + reader->dhcp4_vci, + NULL); + + setting = nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, setting); + g_object_set(setting, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, + TRUE, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, + (int) NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, + reader->ignore_auto_dns, + NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, + reader->dhcp_timeout, + NULL); + + setting = nm_setting_connection_new(); + nm_connection_add_setting(connection, setting); + g_object_set(setting, + NM_SETTING_CONNECTION_ID, + id, + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_a(), + NM_SETTING_CONNECTION_INTERFACE_NAME, + ifname, + NM_SETTING_CONNECTION_TYPE, + type_name, + NM_SETTING_CONNECTION_MULTI_CONNECT, + multi_connect, + NULL); + + if (nm_streq0(type_name, NM_SETTING_INFINIBAND_SETTING_NAME)) { + setting = nm_setting_infiniband_new(); + nm_connection_add_setting(connection, setting); + g_object_set(setting, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL); + } + + if (mac) { + if (nm_streq0(type_name, NM_SETTING_INFINIBAND_SETTING_NAME)) { + setting = (NMSetting *) nm_connection_get_setting_infiniband(connection); + g_object_set(setting, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL); + } else { + setting = nm_setting_wired_new(); + nm_connection_add_setting(connection, setting); + g_object_set(setting, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); + } + } + + return connection; +} + +static NMConnection * +reader_get_default_connection(Reader *reader) +{ + NMConnection *con; + + if (!reader->default_connection) { + con = reader_create_connection(reader, + "default_connection", + "Wired Connection", + NULL, + NULL, + NM_SETTING_WIRED_SETTING_NAME, + NM_CONNECTION_MULTI_CONNECT_MULTIPLE); + nm_connection_add_setting(con, nm_setting_wired_new()); + reader->default_connection = con; + } + return reader->default_connection; +} + +static NMConnection * +reader_get_connection(Reader * reader, + const char *iface_spec, + const char *type_name, + gboolean create_if_missing) +{ + NMConnection *connection = NULL; + NMSetting * setting; + const char * ifname = NULL; + gs_free char *mac = NULL; + + if (iface_spec) { + if (nm_utils_is_valid_iface_name(iface_spec, NULL)) + ifname = iface_spec; + else { + mac = nm_utils_hwaddr_canonical(iface_spec, -1); + if (!mac) + _LOGW(LOGD_CORE, "invalid interface '%s'", iface_spec); + } + } + + if (!ifname && !mac) { + NMConnection * candidate; + NMSettingConnection *s_con; + guint i; + + /* + * 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). + */ + 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 ?: mac); + + if (!connection) { + if (!create_if_missing) + return NULL; + + if (!type_name) { + if (NM_STR_HAS_PREFIX(ifname, "ib") + || (mac && nm_utils_hwaddr_valid(mac, INFINIBAND_ALEN))) + type_name = NM_SETTING_INFINIBAND_SETTING_NAME; + else + type_name = NM_SETTING_WIRED_SETTING_NAME; + } + + connection = reader_create_connection(reader, + ifname ?: mac, + ifname ?: (mac ?: "Wired Connection"), + ifname, + mac, + type_name, + NM_CONNECTION_MULTI_CONNECT_SINGLE); + } + setting = (NMSetting *) nm_connection_get_setting_connection(connection); + + if (type_name) { + g_object_set(setting, NM_SETTING_CONNECTION_TYPE, type_name, NULL); + if (!nm_connection_get_setting_by_name(connection, type_name)) { + setting = g_object_new(nm_setting_lookup_type(type_name), NULL); + nm_connection_add_setting(connection, setting); + } + } + + return connection; +} + +static char * +get_word(char **argument, const char separator) +{ + char *word; + int nest = 0; + + if (*argument == NULL) + return NULL; + + if (**argument == '[') { + nest++; + (*argument)++; + } + + word = *argument; + + while (**argument != '\0') { + if (nest && **argument == ']') { + **argument = '\0'; + (*argument)++; + nest--; + continue; + } + + if (nest == 0 && **argument == separator) { + **argument = '\0'; + (*argument)++; + break; + } + (*argument)++; + } + + return *word ? word : NULL; +} + +static void +connection_set(NMConnection *connection, + const char * setting_name, + const char * property, + const char * value) +{ + NMSetting * setting; + GType setting_type; + nm_auto_unref_gtypeclass GObjectClass *object_class = NULL; + GParamSpec * spec; + + setting_type = nm_setting_lookup_type(setting_name); + object_class = g_type_class_ref(setting_type); + spec = g_object_class_find_property(object_class, property); + nm_assert(spec); + + setting = nm_connection_get_setting_by_name(connection, setting_name); + if (!setting) { + setting = g_object_new(setting_type, NULL); + nm_connection_add_setting(connection, setting); + } + + if (G_IS_PARAM_SPEC_UINT(spec)) { + guint v; + + v = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT, 0); + if (errno || !nm_g_object_set_property_uint(G_OBJECT(setting), property, v, NULL)) { + _LOGW(LOGD_CORE, + "Could not set property '%s.%s' to '%s'", + setting_name, + property, + value); + } + } else if (G_IS_PARAM_SPEC_STRING(spec)) + g_object_set(setting, property, value, NULL); + else + _LOGW(LOGD_CORE, "Don't know how to set '%s' of %s", property, setting_name); +} + +static void +reader_read_all_connections_from_fw(Reader *reader, const char *sysfs_dir) +{ + gs_unref_hashtable GHashTable *ibft = NULL; + 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); + + 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"); + continue; + } + + 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; + } + + name = g_strdup_printf("ibft%s", index); + reader_add_connection(reader, name, g_steal_pointer(&connection)); + } + + dt_connection = nmi_dt_reader_parse(sysfs_dir); + if (dt_connection) + reader_add_connection(reader, "ofw", dt_connection); +} + +static void +reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument) +{ + NMConnection * connection; + 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; + const char * gateway_ip = NULL; + const char * netmask = NULL; + const char * client_hostname = NULL; + const char * iface_spec = NULL; + const char * mtu = NULL; + const char * macaddr = NULL; + int client_ip_family = AF_UNSPEC; + int client_ip_prefix = -1; + const char * dns[2] = { + 0, + }; + int dns_addr_family[2] = { + 0, + }; + int i; + GError *error = NULL; + + if (!*argument) + return; + + tmp = get_word(&argument, ':'); + if (!*argument) { + /* ip={dhcp|on|any|dhcp6|auto6|link6|ibft} */ + kind = tmp; + } else { + tmp2 = get_word(&argument, ':'); + if (NM_IN_STRSET(tmp2, + "none", + "off", + "dhcp", + "on" + "any", + "dhcp6", + "auto", + "auto6", + "link6", + "ibft")) { + /* <ifname>:{none|off|dhcp|on|any|dhcp6|auto|auto6|link6|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, ':'); + kind = get_word(&argument, ':'); + } + + if (client_hostname && !nm_sd_hostname_is_valid(client_hostname, FALSE)) + client_hostname = NULL; + + if (client_hostname) { + g_free(reader->hostname); + reader->hostname = g_strdup(client_hostname); + } + + tmp = get_word(&argument, ':'); + 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] = get_ip_address_family(dns[1], FALSE); + if (*argument) + _LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument); + } else { + mtu = tmp; + macaddr = argument; + } + } + + if (iface_spec == NULL && NM_IN_STRSET(kind, "fw", "ibft")) { + reader_read_all_connections_from_fw(reader, sysfs_dir); + return; + } + + /* Parsing done, construct the NMConnection. */ + if (iface_spec) + connection = reader_get_connection(reader, iface_spec, NULL, TRUE); + 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); + + if (netmask && *netmask) { + gboolean is_ipv4 = client_ip_family == AF_INET; + NMIPAddr addr; + + if (is_ipv4 && nm_utils_parse_inaddr_bin(AF_INET, netmask, NULL, &addr)) + client_ip_prefix = nm_utils_ip4_netmask_to_prefix(addr.addr4); + else + client_ip_prefix = _nm_utils_ascii_str_to_int64(netmask, 10, 0, is_ipv4 ? 32 : 128, -1); + + if (client_ip_prefix == -1) + _LOGW(LOGD_CORE, "Invalid IP mask: %s", netmask); + } + + /* Static IP configuration might be present. */ + if (client_ip && *client_ip) { + NMIPAddress *address = NULL; + NMIPAddr addr; + + if (nm_utils_parse_inaddr_prefix_bin(client_ip_family, + client_ip, + NULL, + &addr, + client_ip_prefix == -1 ? &client_ip_prefix : NULL)) { + if (client_ip_prefix == -1) { + switch (client_ip_family) { + case AF_INET: + client_ip_prefix = _nm_utils_ip4_get_default_prefix(addr.addr4); + break; + case AF_INET6: + client_ip_prefix = 64; + break; + } + } + + address = nm_ip_address_new_binary(client_ip_family, + &addr.addr_ptr, + client_ip_prefix, + &error); + if (!address) { + _LOGW(LOGD_CORE, "Invalid address '%s': %s", client_ip, error->message); + g_clear_error(&error); + } + } else + nm_assert_not_reached(); + + if (address) { + switch (client_ip_family) { + case AF_INET: + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + FALSE, + NULL); + nm_setting_ip_config_add_address(s_ip4, address); + break; + case AF_INET6: + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + FALSE, + NULL); + nm_setting_ip_config_add_address(s_ip6, address); + break; + default: + nm_assert_not_reached(); + break; + } + nm_ip_address_unref(address); + } + } + + /* Dynamic IP configuration configured explicitly. */ + if (NM_IN_STRSET(kind, "none", "off")) { + 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, + NULL); + } + if (nm_setting_ip_config_get_num_addresses(s_ip4) == 0) { + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + } + } else if (nm_streq0(kind, "dhcp")) { + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, + FALSE, + 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_AUTO, + NULL); + } + } else if (NM_IN_STRSET(kind, "auto6", "dhcp6")) { + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE, NULL); + if (nm_setting_ip_config_get_num_addresses(s_ip4) == 0) { + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + } + } else if (nm_streq0(kind, "link6")) { + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, + FALSE, + NULL); + if (nm_setting_ip_config_get_num_addresses(s_ip4) == 0) { + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + } + } else if (nm_streq0(kind, "ibft")) { + NMSettingWired *s_wired; + const char * mac = NULL; + const char * ifname; + gs_free char * mac_free = NULL; + gs_free char * address_path = NULL; + GHashTable * nic = NULL; + + if ((s_wired = nm_connection_get_setting_wired(connection)) + && (mac = nm_setting_wired_get_mac_address(s_wired))) { + /* got mac from the connection */ + } else if ((ifname = nm_connection_get_interface_name(connection))) { + /* read it from sysfs */ + address_path = g_build_filename(sysfs_dir, "class", "net", ifname, "address", NULL); + if (g_file_get_contents(address_path, &mac_free, NULL, &error)) { + g_strchomp(mac_free); + mac = mac_free; + } else { + _LOGW(LOGD_CORE, "Can't get a MAC address for %s: %s", ifname, error->message); + g_clear_error(&error); + } + } + + if (mac) { + gs_free char *mac_up = NULL; + + mac_up = g_ascii_strup(mac, -1); + ibft = nmi_ibft_read(sysfs_dir); + nic = g_hash_table_lookup(ibft, mac_up); + if (!nic) + _LOGW(LOGD_CORE, "No iBFT NIC for %s (%s)", iface_spec, mac_up); + } + + if (nic) { + if (!nmi_ibft_update_connection_from_nic(connection, nic, &error)) { + _LOGW(LOGD_CORE, "Unable to merge iBFT configuration: %s", error->message); + g_clear_error(&error); + } + } + } + + if (peer && *peer) + _LOGW(LOGD_CORE, "Ignoring peer: %s (not implemented)\n", peer); + + if (gateway_ip && *gateway_ip) { + 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; + } + } + + if (client_hostname && *client_hostname) { + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, client_hostname, NULL); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, client_hostname, NULL); + } + + for (i = 0; i < 2; i++) { + if (dns_addr_family[i] == AF_UNSPEC) + break; + if (nm_utils_ipaddr_is_valid(dns_addr_family[i], dns[i])) { + switch (dns_addr_family[i]) { + case AF_INET: + nm_setting_ip_config_add_dns(s_ip4, dns[i]); + break; + case AF_INET6: + nm_setting_ip_config_add_dns(s_ip6, dns[i]); + break; + default: + _LOGW(LOGD_CORE, "Unknown address family: %s", dns[i]); + break; + } + } else { + _LOGW(LOGD_CORE, "Invalid name server: %s", dns[i]); + } + } + + if (mtu && *mtu) + connection_set(connection, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MTU, mtu); + + if (macaddr && *macaddr) + connection_set(connection, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_CLONED_MAC_ADDRESS, + macaddr); +} + +static void +reader_parse_master(Reader *reader, char *argument, const char *type_name, const char *default_name) +{ + NMConnection * connection; + NMSettingConnection *s_con; + gs_free char * master_to_free = NULL; + const char * master; + char * slaves; + const char * slave; + char * opts; + const char * mtu = NULL; + + master = get_word(&argument, ':'); + if (!master) + master = master_to_free = g_strdup_printf("%s0", default_name ?: type_name); + slaves = get_word(&argument, ':'); + + 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); + + if (nm_streq(type_name, NM_SETTING_BRIDGE_SETTING_NAME)) { + NMSettingBridge *s_bridge = nm_connection_get_setting_bridge(connection); + + /* Avoid the forwarding delay */ + g_object_set(s_bridge, NM_SETTING_BRIDGE_STP, FALSE, NULL); + } else if (nm_streq(type_name, NM_SETTING_BOND_SETTING_NAME)) { + NMSettingBond *s_bond = nm_connection_get_setting_bond(connection); + + opts = get_word(&argument, ':'); + while (opts && *opts) { + gs_free_error GError *error = NULL; + char * opt; + const char * opt_name; + + opt = get_word(&opts, ','); + opt_name = get_word(&opt, '='); + + if (!_nm_setting_bond_validate_option(opt_name, opt, &error)) { + _LOGW(LOGD_CORE, + "Ignoring invalid bond option: %s%s%s = %s%s%s: %s", + NM_PRINT_FMT_QUOTE_STRING(opt_name), + NM_PRINT_FMT_QUOTE_STRING(opt), + error->message); + continue; + } + nm_setting_bond_add_option(s_bond, opt_name, opt); + } + + mtu = get_word(&argument, ':'); + } + + do { + slave = get_word(&slaves, ','); + if (slave == NULL) + slave = "eth0"; + + 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, + NM_SETTING_CONNECTION_MASTER, + master, + NULL); + if (mtu) + connection_set(connection, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MTU, mtu); + } while (slaves && *slaves != '\0'); + + if (argument && *argument) + _LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument); +} + +static void +reader_add_routes(Reader *reader, GPtrArray *array) +{ + 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 (gateway && *gateway) { + if (!nm_utils_parse_inaddr_bin(family, gateway, &family, &gateway_addr)) { + _LOGW(LOGD_CORE, "Unrecognized address: %s", gateway); + 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); + 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); + continue; + } + + nm_setting_ip_config_add_route(s_ip, route); + nm_ip_route_unref(route); + } +} + +static void +reader_parse_vlan(Reader *reader, char *argument) +{ + NMConnection * connection; + NMSettingVlan *s_vlan; + const char * vlan; + const char * phy; + const char * vlanid; + + vlan = get_word(&argument, ':'); + phy = get_word(&argument, ':'); + + for (vlanid = vlan + strlen(vlan); vlanid > vlan; vlanid--) { + if (!g_ascii_isdigit(*(vlanid - 1))) + break; + } + + 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, + NM_SETTING_VLAN_PARENT, + phy, + NM_SETTING_VLAN_ID, + (guint) _nm_utils_ascii_str_to_int64(vlanid, 10, 0, G_MAXUINT, G_MAXUINT), + NULL); + + 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 +reader_parse_rd_znet(Reader *reader, char *argument, gboolean net_ifnames) +{ + const char * nettype; + const char * subchannels[4] = {0, 0, 0, 0}; + const char * tmp; + gs_free char * ifname = NULL; + const char * prefix; + NMConnection * connection; + NMSettingWired *s_wired; + static int count_ctc = 0; + static int count_eth = 0; + int index; + + nettype = get_word(&argument, ','); + subchannels[0] = get_word(&argument, ','); + subchannels[1] = get_word(&argument, ','); + + if (nm_streq0(nettype, "ctc")) { + if (net_ifnames == TRUE) { + prefix = "sl"; + } else { + prefix = "ctc"; + index = count_ctc++; + } + } else { + subchannels[2] = get_word(&argument, ','); + if (net_ifnames == TRUE) { + prefix = "en"; + } else { + prefix = "eth"; + index = count_eth++; + } + } + + if (net_ifnames == TRUE) { + const char *bus_id; + size_t bus_id_len; + size_t bus_id_start; + + /* The following logic is taken from names_ccw() in systemd/src/udev/udev-builtin-net_id.c */ + bus_id = subchannels[0]; + bus_id_len = strlen(bus_id); + bus_id_start = strspn(bus_id, ".0"); + bus_id += bus_id_start < bus_id_len ? bus_id_start : bus_id_len - 1; + + ifname = g_strdup_printf("%sc%s", prefix, bus_id); + } else { + ifname = g_strdup_printf("%s%d", prefix, index); + } + + connection = reader_get_connection(reader, ifname, NM_SETTING_WIRED_SETTING_NAME, FALSE); + if (!connection) + return; + s_wired = nm_connection_get_setting_wired(connection); + g_object_set(s_wired, + NM_SETTING_WIRED_S390_NETTYPE, + nettype, + NM_SETTING_WIRED_S390_SUBCHANNELS, + &subchannels, + NULL); + + while ((tmp = get_word(&argument, ',')) != NULL) { + char *val; + + val = strchr(tmp, '='); + if (val) { + gs_free char *key = NULL; + + key = g_strndup(tmp, val - tmp); + val[0] = '\0'; + val++; + nm_setting_wired_add_s390_option(s_wired, key, val); + } + } +} + +static void +_normalize_conn(gpointer key, gpointer value, gpointer user_data) +{ + NMConnection *connection = value; + + nm_connection_normalize(connection, NULL, NULL, 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 = get_ip_address_family(ns, FALSE); + 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(); + continue; + } + + nm_setting_ip_config_add_dns(s_ip, ns); + } + } +} + +static void +connection_set_needed(NMConnection *connection) +{ + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection(connection); + if (!nm_streq0(nm_setting_connection_get_connection_type(s_con), NM_SETTING_WIRED_SETTING_NAME)) + return; + + g_object_set(s_con, + NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, + (int) NMI_WAIT_DEVICE_TIMEOUT_MS, + NULL); +} + +static void +connection_set_needed_cb(gpointer key, gpointer value, gpointer user_data) +{ + connection_set_needed(value); +} + +GHashTable * +nmi_cmdline_reader_parse(const char * sysfs_dir, + const char *const *argv, + char ** hostname, + gint64 * carrier_timeout_sec) +{ + 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; + gs_unref_ptrarray GPtrArray *znets = NULL; + int i; + + reader = reader_new(); + + for (i = 0; argv[i]; i++) { + gs_free char *argument_clone = NULL; + char * argument; + + argument_clone = g_strdup(argv[i]); + argument = argument_clone; + + tag = get_word(&argument, '='); + + if (nm_streq(tag, "net.ifnames")) + net_ifnames = !nm_streq(argument, "0"); + else if (nm_streq(tag, "rd.peerdns")) + reader->ignore_auto_dns = !_nm_utils_ascii_str_to_bool(argument, TRUE); + else if (nm_streq(tag, "rd.net.timeout.dhcp")) { + reader->dhcp_timeout = _nm_utils_ascii_str_to_int64(argument, 10, 0, G_MAXINT32, 0); + } else if (nm_streq(tag, "rd.net.dhcp.vendor-class")) { + if (nm_utils_validate_dhcp4_vendor_class_id(argument, NULL)) + nm_utils_strdup_reset(&reader->dhcp4_vci, argument); + } else if (nm_streq(tag, "rd.net.timeout.carrier")) { + reader->carrier_timeout_sec = + _nm_utils_ascii_str_to_int64(argument, 10, 0, G_MAXINT32, 0); + } + } + + 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 (nm_streq(tag, "ip")) + reader_parse_ip(reader, sysfs_dir, argument); + else if (nm_streq(tag, "rd.route")) { + if (!routes) + routes = g_ptr_array_new_with_free_func(g_free); + g_ptr_array_add(routes, g_strdup(argument)); + } else if (nm_streq(tag, "bridge")) + reader_parse_master(reader, argument, NM_SETTING_BRIDGE_SETTING_NAME, "br"); + else if (nm_streq(tag, "bond")) + reader_parse_master(reader, argument, NM_SETTING_BOND_SETTING_NAME, NULL); + else if (nm_streq(tag, "team")) + reader_parse_master(reader, argument, NM_SETTING_TEAM_SETTING_NAME, NULL); + else if (nm_streq(tag, "vlan")) + reader_parse_vlan(reader, argument); + else if (nm_streq(tag, "bootdev")) { + g_free(bootdev); + bootdev = g_strdup(argument); + } else if (nm_streq(tag, "nameserver")) { + 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 (nm_streq(tag, "rd.iscsi.ibft") && _nm_utils_ascii_str_to_bool(argument, TRUE)) + reader_read_all_connections_from_fw(reader, sysfs_dir); + else if (nm_streq(tag, "rd.bootif")) + ignore_bootif = !_nm_utils_ascii_str_to_bool(argument, TRUE); + else if (nm_streq(tag, "rd.neednet")) + neednet = _nm_utils_ascii_str_to_bool(argument, TRUE); + else if (nm_streq(tag, "rd.znet")) { + if (!znets) + znets = g_ptr_array_new_with_free_func(g_free); + g_ptr_array_add(znets, g_strdup(argument)); + } else if (g_ascii_strcasecmp(tag, "BOOTIF") == 0) { + nm_clear_g_free(&bootif_val); + bootif_val = g_strdup(argument); + } + } + + 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) { + NMConnection * connection; + NMSettingWired *s_wired; + const char * bootif = bootif_val; + char prefix[4]; + + if (!nm_utils_hwaddr_valid(bootif, ETH_ALEN)) { + strncpy(prefix, bootif, 3); + prefix[3] = '\0'; + + if (NM_IN_STRSET(prefix, "01-", "01:", "00-", "00:") + && nm_utils_hwaddr_valid(&bootif[3], ETH_ALEN)) { + /* + * BOOTIF MAC address can be prefixed with a hardware type identifier. + * "01" stays for "wired", "00" is also accepted as it means "undefined". + * No others are known. + */ + bootif += 3; + } + } + + 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 = reader_create_connection(reader, + "bootif_connection", + "BOOTIF Connection", + NULL, + bootif, + NM_SETTING_WIRED_SETTING_NAME, + NM_CONNECTION_MULTI_CONNECT_SINGLE); + } else { + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, bootif, NULL); + } + } + + if (bootdev) { + NMConnection *connection; + + connection = reader_get_connection(reader, bootdev, NULL, TRUE); + reader->bootdev_connection = connection; + connection_set_needed(connection); + } + + if (neednet) { + if (g_hash_table_size(reader->hash) == 0) { + /* Make sure there's some connection. */ + reader_get_default_connection(reader); + } + + g_hash_table_foreach(reader->hash, connection_set_needed_cb, NULL); + } + + if (routes) + reader_add_routes(reader, routes); + + if (nameservers) + reader_add_nameservers(reader, nameservers); + + if (znets) { + for (i = 0; i < znets->len; i++) + reader_parse_rd_znet(reader, znets->pdata[i], net_ifnames); + } + + g_hash_table_foreach(reader->hash, _normalize_conn, NULL); + + NM_SET_OUT(hostname, g_steal_pointer(&reader->hostname)); + + NM_SET_OUT(carrier_timeout_sec, reader->carrier_timeout_sec); + + return reader_destroy(reader, FALSE); +} diff --git a/src/core/initrd/nmi-dt-reader.c b/src/core/initrd/nmi-dt-reader.c new file mode 100644 index 00000000..63e4524b --- /dev/null +++ b/src/core/initrd/nmi-dt-reader.c @@ -0,0 +1,371 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019 Red Hat, Inc. + */ + +#include "src/core/nm-default-daemon.h" + +#include "nm-initrd-generator.h" + +#include <arpa/inet.h> +#include <linux/if_ether.h> + +#include "nm-core-internal.h" + +/*****************************************************************************/ + +#define _NMLOG(level, domain, ...) \ + nm_log((level), \ + (domain), \ + NULL, \ + NULL, \ + "dt-reader: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +/*****************************************************************************/ + +static gboolean +dt_get_property(const char *base, + const char *dev, + const char *prop, + char ** contents, + size_t * length) +{ + gs_free char *filename = g_build_filename(base, dev, prop, NULL); + gs_free_error GError *error = NULL; + + if (!g_file_test(filename, G_FILE_TEST_EXISTS)) + return FALSE; + + if (!contents) + return TRUE; + + if (!g_file_get_contents(filename, contents, length, &error)) { + _LOGW(LOGD_CORE, "%s: Can not read the %s property: %s", dev, prop, error->message); + return FALSE; + } + + return TRUE; +} + +static NMIPAddress * +dt_get_ipaddr_property(const char *base, const char *dev, const char *prop, int *family) +{ + gs_free char *buf = NULL; + size_t len; + int f; + + if (!dt_get_property(base, dev, prop, &buf, &len)) + return NULL; + + f = nm_utils_addr_family_from_size(len); + if (f == AF_UNSPEC || (*family != AF_UNSPEC && *family != f)) { + _LOGW(LOGD_CORE, "%s: Address %s has unrecognized length (%zd)", dev, prop, len); + return NULL; + } + + *family = f; + return nm_ip_address_new_binary(f, buf, 0, NULL); +} + +static char * +dt_get_hwaddr_property(const char *base, const char *dev, const char *prop) +{ + gs_free guint8 *buf = NULL; + size_t len; + + if (!dt_get_property(base, dev, prop, (char **) &buf, &len)) + return NULL; + + if (len != ETH_ALEN) { + _LOGW(LOGD_CORE, "%s: MAC address %s has unrecognized length (%zd)", dev, prop, len); + return NULL; + } + + return g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x", + buf[0], + buf[1], + buf[2], + buf[3], + buf[4], + buf[4]); +} + +static NMIPAddress * +str_addr(const char *str, int *family) +{ + NMIPAddr addr_bin; + + if (!nm_utils_parse_inaddr_bin_full(*family, TRUE, str, family, &addr_bin)) { + _LOGW(LOGD_CORE, "Malformed IP address: '%s'", str); + return NULL; + } + return nm_ip_address_new_binary(*family, &addr_bin, 0, NULL); +} + +NMConnection * +nmi_dt_reader_parse(const char *sysfs_dir) +{ + gs_unref_object NMConnection *connection = NULL; + gs_free char * base = NULL; + gs_free char * bootpath = NULL; + gs_strfreev char ** tokens = NULL; + char * path = NULL; + gboolean bootp = FALSE; + const char * s_ipaddr = NULL; + const char * s_netmask = NULL; + const char * s_gateway = NULL; + nm_auto_unref_ip_address NMIPAddress *ipaddr = NULL; + nm_auto_unref_ip_address NMIPAddress *gateway = NULL; + const char * duplex = NULL; + gs_free char * hwaddr = NULL; + gs_free char * local_hwaddr = NULL; + gs_free char * hostname = NULL; + guint32 speed = 0; + int prefix = -1; + NMSettingIPConfig * s_ip = NULL; + NMSetting * s_ip4 = NULL; + NMSetting * s_ip6 = NULL; + NMSetting * s_wired = NULL; + int family = AF_UNSPEC; + int i = 0; + char * c; + gs_free_error GError *error = NULL; + + base = g_build_filename(sysfs_dir, "firmware", "devicetree", "base", NULL); + + if (!dt_get_property(base, "chosen", "bootpath", &bootpath, NULL)) + return NULL; + + c = strchr(bootpath, ':'); + if (c) { + *c = '\0'; + path = c + 1; + } else { + path = ""; + } + + dt_get_property(base, "chosen", "client-name", &hostname, NULL); + + local_hwaddr = dt_get_hwaddr_property(base, bootpath, "local-mac-address"); + hwaddr = dt_get_hwaddr_property(base, bootpath, "mac-address"); + if (nm_streq0(local_hwaddr, hwaddr)) + nm_clear_g_free(&local_hwaddr); + + tokens = g_strsplit(path, ",", 0); + + /* + * Ethernet device settings. Defined by "Open Firmware, + * Recommended Practice: Device Support Extensions, Version 1.0 [1] + * [1] https://www.devicetree.org/open-firmware/practice/devicex/dse1_0a.ps + */ + + for (i = 0; tokens[i]; i++) { + /* Skip these. They have magical meaning for OpenFirmware. */ + if (NM_IN_STRSET(tokens[i], "nfs", "last")) + continue; + if (nm_streq(tokens[i], "promiscuous")) { + /* Ignore. */ + continue; + } + + if (g_str_has_prefix(tokens[i], "speed=")) { + speed = _nm_utils_ascii_str_to_int64(tokens[i] + 6, 10, 0, G_MAXUINT32, 0); + continue; + } + + if (g_str_has_prefix(tokens[i], "duplex=auto")) { + continue; + } else if (g_str_has_prefix(tokens[i], "duplex=half") + || g_str_has_prefix(tokens[i], "duplex=full")) { + duplex = tokens[i] + 7; + continue; + } + + break; + } + + /* + * Network boot configuration. Defined by "Open Firmware, + * Recommended Practice: TFTP Booting Extension, Version 1.0 [1] + * [1] https://www.devicetree.org/open-firmware/practice/obp-tftp/tftp1_0.pdf + */ + + for (; tokens[i]; i++) { + if (NM_IN_STRSET(tokens[i], "bootp", "dhcp", "rarp")) { + bootp = TRUE; + continue; + } + break; + } + + /* s-iaddr, or perhaps a raw absolute filename */ + if (tokens[i] && tokens[i][0] != '/') + i++; + + /* filename */ + if (tokens[i]) + i++; + + /* c-iaddr */ + if (tokens[i]) { + s_ipaddr = tokens[i]; + i++; + } + + /* g-iaddr */ + if (tokens[i]) { + s_gateway = tokens[i]; + i++; + } + + if (tokens[i] && (strchr(tokens[i], '.') || strchr(tokens[i], ':'))) { + /* yaboot claims the mask can be specified here, + * though it doesn't support it. */ + s_netmask = tokens[i]; + i++; + } + + /* bootp-retries */ + if (tokens[i]) + i++; + + /* tftp-retries */ + if (tokens[i]) + i++; + + if (tokens[i]) { + /* yaboot accepts a mask here */ + s_netmask = tokens[i]; + i++; + } + + connection = nm_simple_connection_new(); + + nm_connection_add_setting(connection, + g_object_new(NM_TYPE_SETTING_CONNECTION, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_ID, + "OpenFirmware Connection", + NULL)); + + s_ip4 = nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, s_ip4); + + s_ip6 = nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, s_ip6); + + g_object_set(s_ip6, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, + (int) NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, + NULL); + + if (!bootp && dt_get_property(base, "chosen", "bootp-response", NULL, NULL)) + bootp = TRUE; + + if (!bootp) { + nm_auto_unref_ip_address NMIPAddress *netmask = NULL; + + netmask = dt_get_ipaddr_property(base, "chosen", "netmask-ip", &family); + gateway = dt_get_ipaddr_property(base, "chosen", "gateway-ip", &family); + if (gateway) + s_gateway = nm_ip_address_get_address(gateway); + ipaddr = dt_get_ipaddr_property(base, "chosen", "client-ip", &family); + + if (family == AF_UNSPEC) { + nm_assert(netmask == NULL); + nm_assert(gateway == NULL); + nm_assert(ipaddr == NULL); + + netmask = str_addr(s_netmask, &family); + ipaddr = str_addr(s_ipaddr, &family); + + prefix = _nm_utils_ascii_str_to_int64(s_netmask, 10, 0, 128, -1); + } + + if (prefix == -1 && family == AF_INET && netmask) { + guint32 netmask_v4; + + nm_ip_address_get_address_binary(netmask, &netmask_v4); + prefix = nm_utils_ip4_netmask_to_prefix(netmask_v4); + } + + if (prefix == -1) + _LOGW(LOGD_CORE, "Unable to determine the network prefix"); + else + nm_ip_address_set_prefix(ipaddr, prefix); + } + + if (!ipaddr) { + family = AF_UNSPEC; + bootp = TRUE; + } + + if (bootp) { + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, + hostname, + NULL); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, + hostname, + NULL); + } else { + switch (family) { + case AF_INET: + s_ip = (NMSettingIPConfig *) s_ip4; + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED, + NULL); + break; + case AF_INET6: + s_ip = (NMSettingIPConfig *) s_ip6; + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NULL); + break; + default: + g_return_val_if_reached(NULL); + } + + nm_setting_ip_config_add_address(s_ip, ipaddr); + g_object_set(s_ip, NM_SETTING_IP_CONFIG_GATEWAY, s_gateway, NULL); + } + + if (duplex || speed || hwaddr || local_hwaddr) { + s_wired = nm_setting_wired_new(); + nm_connection_add_setting(connection, s_wired); + + g_object_set(s_wired, + NM_SETTING_WIRED_SPEED, + speed, + NM_SETTING_WIRED_DUPLEX, + duplex, + NM_SETTING_WIRED_MAC_ADDRESS, + hwaddr, + NM_SETTING_WIRED_CLONED_MAC_ADDRESS, + local_hwaddr, + NULL); + } + + if (!nm_connection_normalize(connection, NULL, NULL, &error)) { + _LOGW(LOGD_CORE, "Generated an invalid connection: %s", error->message); + nm_clear_pointer(&connection, g_object_unref); + } + + return g_steal_pointer(&connection); +} diff --git a/src/core/initrd/nmi-ibft-reader.c b/src/core/initrd/nmi-ibft-reader.c new file mode 100644 index 00000000..9895cda4 --- /dev/null +++ b/src/core/initrd/nmi-ibft-reader.c @@ -0,0 +1,463 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 - 2018 Red Hat, Inc. + */ + +#include "src/core/nm-default-daemon.h" + +#include "nm-initrd-generator.h" + +#include <stdlib.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <sys/wait.h> +#include <sys/inotify.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <linux/if_ether.h> + +#include "nm-core-internal.h" +#include "NetworkManagerUtils.h" + +/*****************************************************************************/ + +#define _NMLOG(level, domain, ...) \ + nm_log((level), \ + (domain), \ + NULL, \ + NULL, \ + "ibft-reader: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +/*****************************************************************************/ + +static GHashTable * +load_one_nic(const char *sysfs_dir, const char *dir_name) +{ + gs_free char *nic_path = g_build_filename(sysfs_dir, dir_name, NULL); + GDir * nic_dir; + const char * entry_name; + char * content; + gs_free_error GError *error = NULL; + GHashTable * nic; + + g_return_val_if_fail(sysfs_dir != NULL, FALSE); + + nic_dir = g_dir_open(nic_path, 0, &error); + if (!nic_dir) { + _LOGW(LOGD_CORE, "Can't open %s: %s", nic_path, error->message); + return NULL; + } + + nic = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); + while ((entry_name = g_dir_read_name(nic_dir))) { + gs_free char *entry_path = g_build_filename(nic_path, entry_name, NULL); + + if (!g_file_test(entry_path, G_FILE_TEST_IS_REGULAR)) + continue; + + if (!g_file_get_contents(entry_path, &content, NULL, &error)) { + _LOGW(LOGD_CORE, "Can't read %s: %s", entry_path, error->message); + g_clear_error(&error); + continue; + } + + g_strchomp(content); + if (!g_hash_table_insert(nic, g_strdup(entry_name), content)) + _LOGW(LOGD_CORE, "Duplicate iBFT entry: %s", entry_name); + } + + g_dir_close(nic_dir); + + return nic; +} + +GHashTable * +nmi_ibft_read(const char *sysfs_dir) +{ + gs_free char *ibft_path = NULL; + GDir * ibft_dir; + const char * dir_name; + GHashTable * ibft, *nic; + char * mac; + gs_free_error GError *error = NULL; + + g_return_val_if_fail(sysfs_dir != NULL, FALSE); + + ibft_path = g_build_filename(sysfs_dir, "firmware", "ibft", NULL); + + ibft = g_hash_table_new_full(nm_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) g_hash_table_unref); + + if (!g_file_test(ibft_path, G_FILE_TEST_IS_DIR)) + nm_utils_modprobe(NULL, FALSE, "iscsi_ibft", NULL); + if (!g_file_test(ibft_path, G_FILE_TEST_IS_DIR)) + return ibft; + + ibft_dir = g_dir_open(ibft_path, 0, &error); + if (!ibft_dir) { + _LOGW(LOGD_CORE, "Unable to open iBFT firmware directory: %s", error->message); + return ibft; + } + + while ((dir_name = g_dir_read_name(ibft_dir))) { + if (!g_str_has_prefix(dir_name, "ethernet")) + continue; + + nic = load_one_nic(ibft_path, dir_name); + mac = g_hash_table_lookup(nic, "mac"); + + if (!mac) { + _LOGW(LOGD_CORE, "Ignoring an iBFT record without a MAC address"); + g_hash_table_unref(nic); + continue; + } + + mac = g_ascii_strup(mac, -1); + if (!g_hash_table_insert(ibft, mac, nic)) + _LOGW(LOGD_CORE, "Duplicate iBFT record for %s", mac); + } + + g_dir_close(ibft_dir); + + return ibft; +} + +static gboolean +ip_setting_add_from_block(GHashTable *nic, NMConnection *connection, GError **error) +{ + NMSettingIPConfig *s_ip = NULL; + NMSettingIPConfig *s_ip4 = NULL; + NMSettingIPConfig *s_ip6 = NULL; + NMIPAddress * addr; + const char * s_ipaddr = NULL; + const char * s_prefix = NULL; + const char * s_gateway = NULL; + const char * s_dns1 = NULL; + const char * s_dns2 = NULL; + const char * s_origin = NULL; + const char * method = NULL; + int family; + gint64 prefix; + + s_ipaddr = (const char *) g_hash_table_lookup(nic, "ip-addr"); + s_prefix = (const char *) g_hash_table_lookup(nic, "prefix-len"); + s_gateway = (const char *) g_hash_table_lookup(nic, "gateway"); + s_dns1 = (const char *) g_hash_table_lookup(nic, "primary-dns"); + s_dns2 = (const char *) g_hash_table_lookup(nic, "secondary-dns"); + s_origin = (const char *) g_hash_table_lookup(nic, "origin"); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + if (!s_ip4) { + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + nm_connection_add_setting(connection, (NMSetting *) s_ip4); + } + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + if (!s_ip6) { + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + nm_connection_add_setting(connection, (NMSetting *) s_ip6); + + g_object_set(s_ip6, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, + (int) NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, + NULL); + } + + family = get_ip_address_family(s_ipaddr, FALSE); + if (family == AF_UNSPEC) + family = get_ip_address_family(s_gateway, FALSE); + + switch (family) { + case AF_INET: + s_ip = s_ip4; + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED, + NULL); + break; + case AF_INET6: + s_ip = s_ip6; + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + break; + default: + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: invalid IP address '%s'.", + s_ipaddr); + return FALSE; + } + + if ((nm_streq0(s_origin, "3") && family == AF_INET) + || (nm_streq0(s_origin, "4") && family == AF_INET)) { + method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; + } else if (nm_streq0(s_origin, "3") && family == AF_INET6) { + method = NM_SETTING_IP6_CONFIG_METHOD_DHCP; + } else if (nm_streq0(s_origin, "4") && family == AF_INET6) { + method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; + } else if (family == AF_INET) { + method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; + } else if (family == AF_INET6) { + method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; + } else { + g_return_val_if_reached(FALSE); + } + g_object_set(s_ip, + 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)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: invalid IP gateway '%s'.", + s_gateway); + return FALSE; + } + + if (s_dns1 && !nm_utils_ipaddr_is_valid(family, s_dns1)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: invalid DNS1 address '%s'.", + s_dns1); + return FALSE; + } + + if (s_dns2 && !nm_utils_ipaddr_is_valid(family, s_dns2)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: invalid DNS2 address '%s'.", + s_dns2); + return FALSE; + } + + if (s_ipaddr) { + prefix = _nm_utils_ascii_str_to_int64(s_prefix, 10, 0, 128, -1); + if (prefix == -1) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: invalid IP prefix '%s'.", + s_prefix); + return FALSE; + } + + addr = nm_ip_address_new(family, s_ipaddr, prefix, error); + if (!addr) { + g_prefix_error(error, "iBFT: "); + return FALSE; + } + + nm_setting_ip_config_add_address(s_ip, addr); + nm_ip_address_unref(addr); + + g_object_set(s_ip, NM_SETTING_IP_CONFIG_GATEWAY, s_gateway, NULL); + } + + if (s_dns1) + nm_setting_ip_config_add_dns(s_ip, s_dns1); + if (s_dns2) + nm_setting_ip_config_add_dns(s_ip, s_dns2); + + return TRUE; +} + +static gboolean +connection_setting_add(GHashTable * nic, + NMConnection *connection, + const char * type, + const char * prefix, + GError ** error) +{ + NMSetting * s_con; + char * id, *uuid; + const char *s_index, *s_hwaddr, *s_ipaddr, *s_vlanid; + + s_index = (const char *) g_hash_table_lookup(nic, "index"); + s_hwaddr = (const char *) g_hash_table_lookup(nic, "mac"); + s_ipaddr = (const char *) g_hash_table_lookup(nic, "ip-addr"); + s_vlanid = (const char *) g_hash_table_lookup(nic, "vlan"); + + if (!s_hwaddr) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: missing MAC address"); + return FALSE; + } + + id = g_strdup_printf("iBFT%s%s Connection%s%s", + prefix ? " " : "", + prefix ? prefix : "", + s_index ? " " : "", + s_index ? s_index : ""); + + uuid = _nm_utils_uuid_generate_from_strings("ibft", + s_hwaddr, + s_vlanid ? "V" : "v", + s_vlanid ? s_vlanid : "", + s_ipaddr ? "A" : "DHCP", + s_ipaddr ? s_ipaddr : "", + NULL); + + s_con = (NMSetting *) nm_connection_get_setting_connection(connection); + if (!s_con) { + s_con = nm_setting_connection_new(); + nm_connection_add_setting(connection, s_con); + } + + g_object_set(s_con, + NM_SETTING_CONNECTION_TYPE, + type, + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_ID, + id, + NM_SETTING_CONNECTION_INTERFACE_NAME, + NULL, + NULL); + + g_free(uuid); + g_free(id); + + return TRUE; +} + +static gboolean +is_ibft_vlan_device(GHashTable *nic) +{ + const char *s_vlan_id; + + g_assert(nic); + + s_vlan_id = (const char *) g_hash_table_lookup(nic, "vlan"); + + if (s_vlan_id) { + /* VLAN 0 is normally a valid VLAN ID, but in the iBFT case it + * means "no VLAN". + */ + if (_nm_utils_ascii_str_to_int64(s_vlan_id, 10, 1, 4095, -1) != -1) + return TRUE; + } + + return FALSE; +} + +static gboolean +vlan_setting_add_from_block(GHashTable *nic, NMConnection *connection, GError **error) +{ + NMSetting * s_vlan = NULL; + const char *vlan_id_str = NULL; + gint64 vlan_id = -1; + + g_assert(nic); + g_assert(connection); + + /* This won't fail since this function shouldn't be called unless the + * iBFT VLAN ID exists and is > 0. + */ + vlan_id_str = (const char *) g_hash_table_lookup(nic, "vlan"); + g_assert(vlan_id_str); + + /* VLAN 0 is normally a valid VLAN ID, but in the iBFT case it means "no VLAN" */ + vlan_id = _nm_utils_ascii_str_to_int64(vlan_id_str, 10, 1, 4095, -1); + if (vlan_id == -1) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid VLAN_ID '%s'", + vlan_id_str); + return FALSE; + } + + s_vlan = (NMSetting *) nm_connection_get_setting_vlan(connection); + if (!s_vlan) { + s_vlan = nm_setting_vlan_new(); + nm_connection_add_setting(connection, s_vlan); + } + + g_object_set(s_vlan, NM_SETTING_VLAN_ID, (guint32) vlan_id, NULL); + + return TRUE; +} + +static gboolean +wired_setting_add_from_block(GHashTable *nic, NMConnection *connection, GError **error) +{ + NMSetting * s_wired = NULL; + const char *hwaddr = NULL; + + g_assert(nic); + g_assert(connection); + + hwaddr = (const char *) g_hash_table_lookup(nic, "mac"); + if (!hwaddr) { + g_set_error_literal(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: missing MAC address"); + return FALSE; + } + + if (!nm_utils_hwaddr_valid(hwaddr, ETH_ALEN)) { + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: invalid MAC address '%s'.", + hwaddr); + return FALSE; + } + + s_wired = (NMSetting *) nm_connection_get_setting_wired(connection); + if (!s_wired) { + s_wired = nm_setting_wired_new(); + nm_connection_add_setting(connection, s_wired); + } + + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, hwaddr, NULL); + + return TRUE; +} + +gboolean +nmi_ibft_update_connection_from_nic(NMConnection *connection, GHashTable *nic, GError **error) +{ + gboolean is_vlan = FALSE; + + g_assert(nic); + + is_vlan = is_ibft_vlan_device(nic); + if (is_vlan && !vlan_setting_add_from_block(nic, connection, error)) + return FALSE; + + /* Always have a wired setting; for VLAN it defines the parent */ + if (!wired_setting_add_from_block(nic, connection, error)) + return FALSE; + + if (!ip_setting_add_from_block(nic, connection, error)) + return FALSE; + + if (!connection_setting_add(nic, + connection, + is_vlan ? NM_SETTING_VLAN_SETTING_NAME + : NM_SETTING_WIRED_SETTING_NAME, + is_vlan ? "VLAN" : NULL, + error)) + return FALSE; + + if (!nm_connection_normalize(connection, NULL, NULL, error)) + return FALSE; + + return TRUE; +} diff --git a/src/core/initrd/tests/meson.build b/src/core/initrd/tests/meson.build new file mode 100644 index 00000000..e47ff790 --- /dev/null +++ b/src/core/initrd/tests/meson.build @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +test_units = [ + 'test-dt-reader', + 'test-ibft-reader', + 'test-cmdline-reader', +] + +foreach test_unit : test_units + exe = executable( + test_unit, + test_unit + '.c', + dependencies: libNetworkManagerTest_dep, + c_args: test_c_flags, + link_with: libnmi_core, + ) + + test( + 'initrd/' + test_unit, + test_script, + timeout: default_test_timeout, + args: test_args + [exe.full_path()], + ) +endforeach diff --git a/src/core/initrd/tests/sysfs-bad-dns1/class/net/eth0/address b/src/core/initrd/tests/sysfs-bad-dns1/class/net/eth0/address new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/class/net/eth0/address @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/gateway b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/gateway new file mode 100644 index 00000000..bf6cf454 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/gateway @@ -0,0 +1 @@ +192.168.35.254 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/index b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/ip-addr b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/ip-addr new file mode 100644 index 00000000..944c8d45 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/ip-addr @@ -0,0 +1 @@ +192.168.32.72 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/mac b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/mac new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/mac @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/origin b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/origin new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/origin @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/prefix-len b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/prefix-len new file mode 100644 index 00000000..8fdd954d --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/prefix-len @@ -0,0 +1 @@ +22 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/primary-dns b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/primary-dns new file mode 100644 index 00000000..2303dbdc --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/primary-dns @@ -0,0 +1 @@ +10000.500.250.1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/secondary-dns b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/secondary-dns new file mode 100644 index 00000000..2eb9e1d0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/secondary-dns @@ -0,0 +1 @@ +10.16.255.3 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/subnet-mask b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/subnet-mask new file mode 100644 index 00000000..7cb9d0a9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/subnet-mask @@ -0,0 +1 @@ +255.255.252.0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/vlan b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/vlan new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/ethernet0/vlan @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/initiator/initiator-name b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/initiator/initiator-name new file mode 100644 index 00000000..509a7ab8 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/initiator/initiator-name @@ -0,0 +1 @@ +iqn.pjones6 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/index b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/ip-addr b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/ip-addr new file mode 100644 index 00000000..7450fdf9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/ip-addr @@ -0,0 +1 @@ +10.16.52.16 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/lun b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/lun new file mode 100644 index 00000000..c43d0930 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/lun @@ -0,0 +1 @@ +00000000 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/port b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/port new file mode 100644 index 00000000..58f0d919 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/port @@ -0,0 +1 @@ +3260 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/target-name b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/target-name new file mode 100644 index 00000000..32c9450a --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns1/firmware/ibft/target0/target-name @@ -0,0 +1 @@ +iqn.0.2008-11.com.blahblah:iscsi0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/class/net/eth0/address b/src/core/initrd/tests/sysfs-bad-dns2/class/net/eth0/address new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/class/net/eth0/address @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/gateway b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/gateway new file mode 100644 index 00000000..bf6cf454 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/gateway @@ -0,0 +1 @@ +192.168.35.254 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/index b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/ip-addr b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/ip-addr new file mode 100644 index 00000000..944c8d45 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/ip-addr @@ -0,0 +1 @@ +192.168.32.72 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/mac b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/mac new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/mac @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/origin b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/origin new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/origin @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/prefix-len b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/prefix-len new file mode 100644 index 00000000..8fdd954d --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/prefix-len @@ -0,0 +1 @@ +22 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/primary-dns b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/primary-dns new file mode 100644 index 00000000..2e152cb0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/primary-dns @@ -0,0 +1 @@ +10.16.255.2 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/secondary-dns b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/secondary-dns new file mode 100644 index 00000000..5ed7b719 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/secondary-dns @@ -0,0 +1 @@ +blah.foo.bar.baz \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/subnet-mask b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/subnet-mask new file mode 100644 index 00000000..7cb9d0a9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/subnet-mask @@ -0,0 +1 @@ +255.255.252.0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/vlan b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/vlan new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/ethernet0/vlan @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/initiator/initiator-name b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/initiator/initiator-name new file mode 100644 index 00000000..509a7ab8 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/initiator/initiator-name @@ -0,0 +1 @@ +iqn.pjones6 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/index b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/ip-addr b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/ip-addr new file mode 100644 index 00000000..7450fdf9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/ip-addr @@ -0,0 +1 @@ +10.16.52.16 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/lun b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/lun new file mode 100644 index 00000000..c43d0930 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/lun @@ -0,0 +1 @@ +00000000 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/port b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/port new file mode 100644 index 00000000..58f0d919 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/port @@ -0,0 +1 @@ +3260 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/target-name b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/target-name new file mode 100644 index 00000000..32c9450a --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-dns2/firmware/ibft/target0/target-name @@ -0,0 +1 @@ +iqn.0.2008-11.com.blahblah:iscsi0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/class/net/eth0/address b/src/core/initrd/tests/sysfs-bad-gateway/class/net/eth0/address new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/class/net/eth0/address @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/gateway b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/gateway new file mode 100644 index 00000000..1970856e --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/gateway @@ -0,0 +1 @@ +bb.cc.dd.ee \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/index b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/ip-addr b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/ip-addr new file mode 100644 index 00000000..944c8d45 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/ip-addr @@ -0,0 +1 @@ +192.168.32.72 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/mac b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/mac new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/mac @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/origin b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/origin new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/origin @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/prefix-len b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/prefix-len new file mode 100644 index 00000000..8fdd954d --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/prefix-len @@ -0,0 +1 @@ +22 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/primary-dns b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/primary-dns new file mode 100644 index 00000000..2e152cb0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/primary-dns @@ -0,0 +1 @@ +10.16.255.2 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/secondary-dns b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/secondary-dns new file mode 100644 index 00000000..2eb9e1d0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/secondary-dns @@ -0,0 +1 @@ +10.16.255.3 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/subnet-mask b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/subnet-mask new file mode 100644 index 00000000..7cb9d0a9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/subnet-mask @@ -0,0 +1 @@ +255.255.252.0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/vlan b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/vlan new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/ethernet0/vlan @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/initiator/initiator-name b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/initiator/initiator-name new file mode 100644 index 00000000..509a7ab8 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/initiator/initiator-name @@ -0,0 +1 @@ +iqn.pjones6 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/index b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/ip-addr b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/ip-addr new file mode 100644 index 00000000..7450fdf9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/ip-addr @@ -0,0 +1 @@ +10.16.52.16 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/lun b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/lun new file mode 100644 index 00000000..c43d0930 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/lun @@ -0,0 +1 @@ +00000000 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/port b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/port new file mode 100644 index 00000000..58f0d919 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/port @@ -0,0 +1 @@ +3260 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/target-name b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/target-name new file mode 100644 index 00000000..32c9450a --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-gateway/firmware/ibft/target0/target-name @@ -0,0 +1 @@ +iqn.0.2008-11.com.blahblah:iscsi0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/class/net/eth0/address b/src/core/initrd/tests/sysfs-bad-ipaddr/class/net/eth0/address new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/class/net/eth0/address @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/gateway b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/gateway new file mode 100644 index 00000000..bf6cf454 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/gateway @@ -0,0 +1 @@ +192.168.35.254 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/index b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/ip-addr b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/ip-addr new file mode 100644 index 00000000..d526f324 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/ip-addr @@ -0,0 +1 @@ +aa.bb.cc.dd \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/mac b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/mac new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/mac @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/origin b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/origin new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/origin @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/prefix-len b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/prefix-len new file mode 100644 index 00000000..8fdd954d --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/prefix-len @@ -0,0 +1 @@ +22 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/primary-dns b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/primary-dns new file mode 100644 index 00000000..2e152cb0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/primary-dns @@ -0,0 +1 @@ +10.16.255.2 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/secondary-dns b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/secondary-dns new file mode 100644 index 00000000..2eb9e1d0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/secondary-dns @@ -0,0 +1 @@ +10.16.255.3 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/subnet-mask b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/subnet-mask new file mode 100644 index 00000000..7cb9d0a9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/subnet-mask @@ -0,0 +1 @@ +255.255.252.0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/vlan b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/vlan new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/ethernet0/vlan @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/initiator/initiator-name b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/initiator/initiator-name new file mode 100644 index 00000000..509a7ab8 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/initiator/initiator-name @@ -0,0 +1 @@ +iqn.pjones6 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/index b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/ip-addr b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/ip-addr new file mode 100644 index 00000000..7450fdf9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/ip-addr @@ -0,0 +1 @@ +10.16.52.16 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/lun b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/lun new file mode 100644 index 00000000..c43d0930 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/lun @@ -0,0 +1 @@ +00000000 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/port b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/port new file mode 100644 index 00000000..58f0d919 --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/port @@ -0,0 +1 @@ +3260 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/target-name b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/target-name new file mode 100644 index 00000000..32c9450a --- /dev/null +++ b/src/core/initrd/tests/sysfs-bad-ipaddr/firmware/ibft/target0/target-name @@ -0,0 +1 @@ +iqn.0.2008-11.com.blahblah:iscsi0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/class/net/eth0/address b/src/core/initrd/tests/sysfs-dhcp/class/net/eth0/address new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/class/net/eth0/address @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/class/net/eth1/address b/src/core/initrd/tests/sysfs-dhcp/class/net/eth1/address new file mode 100644 index 00000000..befa7850 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/class/net/eth1/address @@ -0,0 +1 @@ +00:33:21:98:b9:f1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/gateway b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/gateway new file mode 100644 index 00000000..59ea5b82 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/gateway @@ -0,0 +1 @@ +10.16.52.254 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/index b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/mac b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/mac new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/mac @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/origin b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/origin new file mode 100644 index 00000000..e440e5c8 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/origin @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/primary-dns b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/primary-dns new file mode 100644 index 00000000..2e152cb0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/primary-dns @@ -0,0 +1 @@ +10.16.255.2 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/secondary-dns b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/secondary-dns new file mode 100644 index 00000000..2eb9e1d0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/secondary-dns @@ -0,0 +1 @@ +10.16.255.3 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/vlan b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/vlan new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet0/vlan @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/gateway b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/gateway new file mode 100644 index 00000000..59ea5b82 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/gateway @@ -0,0 +1 @@ +10.16.52.254 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/index b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/index new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/index @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/mac b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/mac new file mode 100644 index 00000000..befa7850 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/mac @@ -0,0 +1 @@ +00:33:21:98:b9:f1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/origin b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/origin new file mode 100644 index 00000000..e440e5c8 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/origin @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/primary-dns b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/primary-dns new file mode 100644 index 00000000..2e152cb0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/primary-dns @@ -0,0 +1 @@ +10.16.255.2 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/secondary-dns b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/secondary-dns new file mode 100644 index 00000000..2eb9e1d0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/secondary-dns @@ -0,0 +1 @@ +10.16.255.3 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/vlan b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/vlan new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/ethernet1/vlan @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/initiator/initiator-name b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/initiator/initiator-name new file mode 100644 index 00000000..509a7ab8 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/initiator/initiator-name @@ -0,0 +1 @@ +iqn.pjones6 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/index b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/ip-addr b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/ip-addr new file mode 100644 index 00000000..7450fdf9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/ip-addr @@ -0,0 +1 @@ +10.16.52.16 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/lun b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/lun new file mode 100644 index 00000000..c43d0930 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/lun @@ -0,0 +1 @@ +00000000 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/port b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/port new file mode 100644 index 00000000..58f0d919 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/port @@ -0,0 +1 @@ +3260 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/target-name b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/target-name new file mode 100644 index 00000000..32c9450a --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target0/target-name @@ -0,0 +1 @@ +iqn.0.2008-11.com.blahblah:iscsi0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/index b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/index new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/index @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/ip-addr b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/ip-addr new file mode 100644 index 00000000..7450fdf9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/ip-addr @@ -0,0 +1 @@ +10.16.52.16 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/lun b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/lun new file mode 100644 index 00000000..c43d0930 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/lun @@ -0,0 +1 @@ +00000000 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/port b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/port new file mode 100644 index 00000000..58f0d919 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/port @@ -0,0 +1 @@ +3260 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/target-name b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/target-name new file mode 100644 index 00000000..ac3a6a2a --- /dev/null +++ b/src/core/initrd/tests/sysfs-dhcp/firmware/ibft/target1/target-name @@ -0,0 +1 @@ +iqn.1.2008-11.com.blahblah:iscsi1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dt-tftp/firmware/devicetree/base/chosen/bootpath b/src/core/initrd/tests/sysfs-dt-tftp/firmware/devicetree/base/chosen/bootpath new file mode 100644 index 00000000..6f069ae0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt-tftp/firmware/devicetree/base/chosen/bootpath Binary files differdiff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-request b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-request new file mode 100644 index 00000000..034d423e --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-request Binary files differdiff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-response b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-response new file mode 100644 index 00000000..25982d6f --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootp-response Binary files differdiff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootpath b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootpath new file mode 100644 index 00000000..db880702 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/bootpath Binary files differdiff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/broadcast-ip b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/broadcast-ip new file mode 100644 index 00000000..7bde8641 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/broadcast-ip @@ -0,0 +1 @@ +ÿÿÿÿ \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/client-ip b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/client-ip new file mode 100644 index 00000000..f108ba9b --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/client-ip @@ -0,0 +1,2 @@ + ++ \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/client-name b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/client-name new file mode 100644 index 00000000..fe0f76b8 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/client-name Binary files differdiff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/domain-name b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/domain-name new file mode 100644 index 00000000..b34f9f96 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/domain-name Binary files differdiff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/gateway-ip b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/gateway-ip new file mode 100644 index 00000000..f0361835 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/gateway-ip @@ -0,0 +1,2 @@ + ++þ \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/name b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/name new file mode 100644 index 00000000..f3e58052 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/name Binary files differdiff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/netmask-ip b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/netmask-ip new file mode 100644 index 00000000..d441cd83 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/netmask-ip Binary files differdiff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/root-path b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/root-path new file mode 100644 index 00000000..f76dd238 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/root-path Binary files differdiff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/server-ip b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/server-ip new file mode 100644 index 00000000..a2a4b2e8 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/server-ip @@ -0,0 +1,2 @@ + +& \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/tftp-file b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/tftp-file new file mode 100644 index 00000000..c0e0e330 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/tftp-file Binary files differdiff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/vendor-options b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/vendor-options new file mode 100644 index 00000000..f76dd238 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/chosen/vendor-options Binary files differdiff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/device_type b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/device_type new file mode 100644 index 00000000..df3c9d9f --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/device_type Binary files differdiff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/local-mac-address b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/local-mac-address new file mode 100644 index 00000000..c983e752 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/local-mac-address @@ -0,0 +1 @@ +¬>åØ \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/mac-address b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/mac-address new file mode 100644 index 00000000..c983e752 --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/mac-address @@ -0,0 +1 @@ +¬>åØ \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/name b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/name new file mode 100644 index 00000000..88eaddfe --- /dev/null +++ b/src/core/initrd/tests/sysfs-dt/firmware/devicetree/base/ethernet/name Binary files differdiff --git a/src/core/initrd/tests/sysfs-static/class/net/eth0/address b/src/core/initrd/tests/sysfs-static/class/net/eth0/address new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/class/net/eth0/address @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/class/net/eth1/address b/src/core/initrd/tests/sysfs-static/class/net/eth1/address new file mode 100644 index 00000000..befa7850 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/class/net/eth1/address @@ -0,0 +1 @@ +00:33:21:98:b9:f1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/gateway b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/gateway new file mode 100644 index 00000000..bf6cf454 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/gateway @@ -0,0 +1 @@ +192.168.35.254 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/index b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/ip-addr b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/ip-addr new file mode 100644 index 00000000..944c8d45 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/ip-addr @@ -0,0 +1 @@ +192.168.32.72 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/mac b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/mac new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/mac @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/origin b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/origin new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/origin @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/prefix-len b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/prefix-len new file mode 100644 index 00000000..8fdd954d --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/prefix-len @@ -0,0 +1 @@ +22 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/primary-dns b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/primary-dns new file mode 100644 index 00000000..2e152cb0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/primary-dns @@ -0,0 +1 @@ +10.16.255.2 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/secondary-dns b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/secondary-dns new file mode 100644 index 00000000..2eb9e1d0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/secondary-dns @@ -0,0 +1 @@ +10.16.255.3 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/subnet-mask b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/subnet-mask new file mode 100644 index 00000000..7cb9d0a9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/subnet-mask @@ -0,0 +1 @@ +255.255.252.0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/vlan b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/vlan new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet0/vlan @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/gateway b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/gateway new file mode 100644 index 00000000..59ea5b82 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/gateway @@ -0,0 +1 @@ +10.16.52.254 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/index b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/index new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/index @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/mac b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/mac new file mode 100644 index 00000000..befa7850 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/mac @@ -0,0 +1 @@ +00:33:21:98:b9:f1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/origin b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/origin new file mode 100644 index 00000000..e440e5c8 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/origin @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/primary-dns b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/primary-dns new file mode 100644 index 00000000..2e152cb0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/primary-dns @@ -0,0 +1 @@ +10.16.255.2 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/secondary-dns b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/secondary-dns new file mode 100644 index 00000000..2eb9e1d0 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/secondary-dns @@ -0,0 +1 @@ +10.16.255.3 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/vlan b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/vlan new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/ethernet1/vlan @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/initiator/initiator-name b/src/core/initrd/tests/sysfs-static/firmware/ibft/initiator/initiator-name new file mode 100644 index 00000000..509a7ab8 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/initiator/initiator-name @@ -0,0 +1 @@ +iqn.pjones6 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/index b/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/ip-addr b/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/ip-addr new file mode 100644 index 00000000..7450fdf9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/ip-addr @@ -0,0 +1 @@ +10.16.52.16 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/lun b/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/lun new file mode 100644 index 00000000..c43d0930 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/lun @@ -0,0 +1 @@ +00000000 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/port b/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/port new file mode 100644 index 00000000..58f0d919 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/port @@ -0,0 +1 @@ +3260 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/target-name b/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/target-name new file mode 100644 index 00000000..32c9450a --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/target0/target-name @@ -0,0 +1 @@ +iqn.0.2008-11.com.blahblah:iscsi0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/index b/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/index new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/index @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/ip-addr b/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/ip-addr new file mode 100644 index 00000000..7450fdf9 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/ip-addr @@ -0,0 +1 @@ +10.16.52.16 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/lun b/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/lun new file mode 100644 index 00000000..c43d0930 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/lun @@ -0,0 +1 @@ +00000000 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/port b/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/port new file mode 100644 index 00000000..58f0d919 --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/port @@ -0,0 +1 @@ +3260 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/target-name b/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/target-name new file mode 100644 index 00000000..ac3a6a2a --- /dev/null +++ b/src/core/initrd/tests/sysfs-static/firmware/ibft/target1/target-name @@ -0,0 +1 @@ +iqn.1.2008-11.com.blahblah:iscsi1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/class/net/eth0/address b/src/core/initrd/tests/sysfs-vlan/class/net/eth0/address new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/class/net/eth0/address @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/index b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/ip-addr b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/ip-addr new file mode 100644 index 00000000..4923230c --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/ip-addr @@ -0,0 +1 @@ +192.168.6.200 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/mac b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/mac new file mode 100644 index 00000000..20659db7 --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/mac @@ -0,0 +1 @@ +00:33:21:98:b9:f0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/origin b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/origin new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/origin @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/prefix-len b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/prefix-len new file mode 100644 index 00000000..cabf43b5 --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/prefix-len @@ -0,0 +1 @@ +24 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/subnet-mask b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/subnet-mask new file mode 100644 index 00000000..5a279b41 --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/subnet-mask @@ -0,0 +1 @@ +255.255.255.0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/vlan b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/vlan new file mode 100644 index 00000000..d800886d --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/ethernet0/vlan @@ -0,0 +1 @@ +123 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/initiator/initiator-name b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/initiator/initiator-name new file mode 100644 index 00000000..8e9cd2c4 --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/initiator/initiator-name @@ -0,0 +1 @@ +iqn.2010-04.org.ipxe:d05faa97-c4be-44f6-a723-efde9aa399a0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/index b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/index new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/index @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/ip-addr b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/ip-addr new file mode 100644 index 00000000..a32ce01b --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/ip-addr @@ -0,0 +1 @@ +192.168.6.32 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/lun b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/lun new file mode 100644 index 00000000..f309ca6a --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/lun @@ -0,0 +1 @@ +01000000 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/port b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/port new file mode 100644 index 00000000..58f0d919 --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/port @@ -0,0 +1 @@ +3260 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/target-name b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/target-name new file mode 100644 index 00000000..f0e61157 --- /dev/null +++ b/src/core/initrd/tests/sysfs-vlan/firmware/ibft/target0/target-name @@ -0,0 +1 @@ +iqn.2003-01.org.x:disk1 \ No newline at end of file diff --git a/src/core/initrd/tests/sysfs/class/net/eth0/address b/src/core/initrd/tests/sysfs/class/net/eth0/address new file mode 100644 index 00000000..1f2f610e --- /dev/null +++ b/src/core/initrd/tests/sysfs/class/net/eth0/address @@ -0,0 +1 @@ +00:53:00:AB:00:01 diff --git a/src/core/initrd/tests/sysfs/class/net/eth2/address b/src/core/initrd/tests/sysfs/class/net/eth2/address new file mode 100644 index 00000000..6ec1078a --- /dev/null +++ b/src/core/initrd/tests/sysfs/class/net/eth2/address @@ -0,0 +1 @@ +00:53:06:66:ab:01 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/oem_id b/src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/oem_id new file mode 100644 index 00000000..590d9cd2 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/oem_id @@ -0,0 +1 @@ +NMTst diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/oem_table_id b/src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/oem_table_id new file mode 100644 index 00000000..35d4d09c --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/oem_table_id @@ -0,0 +1 @@ +Whatevs diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/signature b/src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/signature new file mode 100644 index 00000000..e3a5d7ef --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/acpi_header/signature @@ -0,0 +1 @@ +IBFT diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/dhcp b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/dhcp new file mode 100644 index 00000000..98a0d797 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/dhcp @@ -0,0 +1 @@ +2001:0db8:0000:0000:0000:0000:0000:0002 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/flags b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/flags new file mode 100644 index 00000000..00750edc --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/flags @@ -0,0 +1 @@ +3 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/gateway b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/gateway new file mode 100644 index 00000000..7f378f8f --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/gateway @@ -0,0 +1 @@ +2001:0db8:0000:0000:0000:0000:0000:0001 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/hostname b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/hostname new file mode 100644 index 00000000..3ed5163c --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/hostname @@ -0,0 +1 @@ +host0.example.com diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/index b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/index new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/index @@ -0,0 +1 @@ +0 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/ip-addr b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/ip-addr new file mode 100644 index 00000000..98a0d797 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/ip-addr @@ -0,0 +1 @@ +2001:0db8:0000:0000:0000:0000:0000:0002 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/mac b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/mac new file mode 100644 index 00000000..f2441319 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/mac @@ -0,0 +1 @@ +00:53:00:ab:00:01 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/origin b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/origin new file mode 100644 index 00000000..b8626c4c --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/origin @@ -0,0 +1 @@ +4 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/prefix-len b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/prefix-len new file mode 100644 index 00000000..900731ff --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/prefix-len @@ -0,0 +1 @@ +64 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/primary-dns b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/primary-dns new file mode 100644 index 00000000..e7511d5a --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/primary-dns @@ -0,0 +1 @@ +2001:0db8:0000:0000:0000:0000:0000:0053 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/secondary-dns b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/secondary-dns new file mode 100644 index 00000000..1f6c5c95 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/secondary-dns @@ -0,0 +1 @@ +2001:0db8:0000:0000:0000:0000:0000:5353 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/subnet-mask b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/subnet-mask new file mode 100644 index 00000000..5df93454 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/subnet-mask @@ -0,0 +1 @@ +255.255.255.255 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/vlan b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/vlan new file mode 100644 index 00000000..7cc86ad1 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet0/vlan @@ -0,0 +1 @@ +666 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/dhcp b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/dhcp new file mode 100644 index 00000000..61ef5585 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/dhcp @@ -0,0 +1 @@ +192.0.2.2 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/flags b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/flags new file mode 100644 index 00000000..00750edc --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/flags @@ -0,0 +1 @@ +3 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/gateway b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/gateway new file mode 100644 index 00000000..2096f194 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/gateway @@ -0,0 +1 @@ +192.0.2.1 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/hostname b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/hostname new file mode 100644 index 00000000..5dc539d5 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/hostname @@ -0,0 +1 @@ +host2.example.com diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/index b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/index new file mode 100644 index 00000000..0cfbf088 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/index @@ -0,0 +1 @@ +2 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/ip-addr b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/ip-addr new file mode 100644 index 00000000..61ef5585 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/ip-addr @@ -0,0 +1 @@ +192.0.2.2 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/mac b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/mac new file mode 100644 index 00000000..2fc3d525 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/mac @@ -0,0 +1 @@ +00:53:06:66:AB:01 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/origin b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/origin new file mode 100644 index 00000000..00750edc --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/origin @@ -0,0 +1 @@ +3 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/prefix-len b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/prefix-len new file mode 100644 index 00000000..a45fd52c --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/prefix-len @@ -0,0 +1 @@ +24 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/primary-dns b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/primary-dns new file mode 100644 index 00000000..6fa8c742 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/primary-dns @@ -0,0 +1 @@ +192.0.2.53 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/secondary-dns b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/secondary-dns new file mode 100644 index 00000000..a7269ff5 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/secondary-dns @@ -0,0 +1 @@ +192.0.2.54 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/subnet-mask b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/subnet-mask new file mode 100644 index 00000000..d30f9e9f --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/subnet-mask @@ -0,0 +1 @@ +255.255.255.0 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/vlan b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/vlan new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/ethernet2/vlan @@ -0,0 +1 @@ +0 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/initiator/flags b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/flags new file mode 100644 index 00000000..00750edc --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/flags @@ -0,0 +1 @@ +3 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/initiator/index b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/index new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/index @@ -0,0 +1 @@ +0 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/initiator/initiator-name b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/initiator-name new file mode 100644 index 00000000..337b5a0f --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/initiator-name @@ -0,0 +1 @@ +iqn.1994-05.com.example.initiator:48b055856417 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/initiator/isns-server b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/isns-server new file mode 100644 index 00000000..4aff9398 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/isns-server @@ -0,0 +1 @@ +2001:0db8:0000:0000:0000:0000:0000:3205 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/initiator/pri-radius-server b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/pri-radius-server new file mode 100644 index 00000000..a26fb649 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/pri-radius-server @@ -0,0 +1 @@ +2001:0db8:0000:0000:0000:0000:0000:1812 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/initiator/sec-radius-server b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/sec-radius-server new file mode 100644 index 00000000..908be27f --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/sec-radius-server @@ -0,0 +1 @@ +192.0.2.181 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/initiator/slp-server b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/slp-server new file mode 100644 index 00000000..fca9e24b --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/initiator/slp-server @@ -0,0 +1 @@ +2001:0db8:0000:0000:0000:0000:0000:0427 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target0/chap-type b/src/core/initrd/tests/sysfs/firmware/ibft/target0/chap-type new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target0/chap-type @@ -0,0 +1 @@ +0 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target0/flags b/src/core/initrd/tests/sysfs/firmware/ibft/target0/flags new file mode 100644 index 00000000..00750edc --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target0/flags @@ -0,0 +1 @@ +3 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target0/index b/src/core/initrd/tests/sysfs/firmware/ibft/target0/index new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target0/index @@ -0,0 +1 @@ +0 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target0/ip-addr b/src/core/initrd/tests/sysfs/firmware/ibft/target0/ip-addr new file mode 100644 index 00000000..994b6e9c --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target0/ip-addr @@ -0,0 +1 @@ +2001:0db8:0000:0000:0000:0000:0000:3260 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target0/lun b/src/core/initrd/tests/sysfs/firmware/ibft/target0/lun new file mode 100644 index 00000000..7c295bd4 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target0/lun @@ -0,0 +1 @@ +01000000 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target0/nic-assoc b/src/core/initrd/tests/sysfs/firmware/ibft/target0/nic-assoc new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target0/nic-assoc @@ -0,0 +1 @@ +0 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target0/port b/src/core/initrd/tests/sysfs/firmware/ibft/target0/port new file mode 100644 index 00000000..53f0295f --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target0/port @@ -0,0 +1 @@ +3260 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target2/chap-type b/src/core/initrd/tests/sysfs/firmware/ibft/target2/chap-type new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target2/chap-type @@ -0,0 +1 @@ +0 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target2/flags b/src/core/initrd/tests/sysfs/firmware/ibft/target2/flags new file mode 100644 index 00000000..00750edc --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target2/flags @@ -0,0 +1 @@ +3 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target2/index b/src/core/initrd/tests/sysfs/firmware/ibft/target2/index new file mode 100644 index 00000000..0cfbf088 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target2/index @@ -0,0 +1 @@ +2 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target2/ip-addr b/src/core/initrd/tests/sysfs/firmware/ibft/target2/ip-addr new file mode 100644 index 00000000..a210477e --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target2/ip-addr @@ -0,0 +1 @@ +2001:0db8:0000:0000:0000:0000:0002:3260 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target2/lun b/src/core/initrd/tests/sysfs/firmware/ibft/target2/lun new file mode 100644 index 00000000..7c295bd4 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target2/lun @@ -0,0 +1 @@ +01000000 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target2/nic-assoc b/src/core/initrd/tests/sysfs/firmware/ibft/target2/nic-assoc new file mode 100644 index 00000000..0cfbf088 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target2/nic-assoc @@ -0,0 +1 @@ +2 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target2/port b/src/core/initrd/tests/sysfs/firmware/ibft/target2/port new file mode 100644 index 00000000..53f0295f --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target2/port @@ -0,0 +1 @@ +3260 diff --git a/src/core/initrd/tests/sysfs/firmware/ibft/target2/target-name b/src/core/initrd/tests/sysfs/firmware/ibft/target2/target-name new file mode 100644 index 00000000..f4094320 --- /dev/null +++ b/src/core/initrd/tests/sysfs/firmware/ibft/target2/target-name @@ -0,0 +1 @@ +iqn.1994-05.com.example.target:48b055851337 diff --git a/src/core/initrd/tests/test-cmdline-reader.c b/src/core/initrd/tests/test-cmdline-reader.c new file mode 100644 index 00000000..cb65cd33 --- /dev/null +++ b/src/core/initrd/tests/test-cmdline-reader.c @@ -0,0 +1,2118 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2018 Red Hat, Inc. + */ + +#include "src/core/nm-default-daemon.h" + +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/socket.h> + +#include "nm-core-internal.h" +#include "NetworkManagerUtils.h" + +#include "../nm-initrd-generator.h" + +#include "nm-test-utils-core.h" + +#define TEST_INITRD_DIR NM_BUILD_SRCDIR "/src/core/initrd/tests" + +/*****************************************************************************/ + +#define _parse(ARGV, out_hostname, out_carrier_timeout_sec) \ + ({ \ + const char *const *const _ARGV = (ARGV); \ + char **const _out_hostname = (out_hostname); \ + gint64 *const _out_carrier_timeout_sec = (out_carrier_timeout_sec); \ + GHashTable * _connections; \ + \ + _connections = nmi_cmdline_reader_parse(TEST_INITRD_DIR "/sysfs", \ + _ARGV, \ + _out_hostname, \ + _out_carrier_timeout_sec); \ + \ + g_assert(_connections); \ + \ + _connections; \ + }) + +#define _parse_cons(ARGV) \ + ({ \ + GHashTable * _con_connections; \ + gs_free char *_con_hostname = NULL; \ + gint64 _con_carrier_timeout_sec = 0; \ + \ + _con_connections = _parse((ARGV), \ + nmtst_get_rand_bool() ? &_con_hostname : NULL, \ + nmtst_get_rand_bool() ? &_con_carrier_timeout_sec : NULL); \ + g_assert_cmpstr(_con_hostname, ==, NULL); \ + g_assert_cmpint(_con_carrier_timeout_sec, ==, 0); \ + \ + _con_connections; \ + }) + +#define _parse_con(ARGV, connection_name) \ + ({ \ + gs_unref_hashtable GHashTable *_1_connections = NULL; \ + NMConnection * _1_connection; \ + const char *const _1_connection_name = (connection_name); \ + \ + g_assert(_1_connection_name); \ + \ + _1_connections = _parse_cons((ARGV)); \ + \ + g_assert_cmpint(g_hash_table_size(_1_connections), ==, 1); \ + \ + _1_connection = g_hash_table_lookup(_1_connections, _1_connection_name); \ + g_assert(NM_IS_CONNECTION(_1_connection)); \ + \ + nmtst_assert_connection_verifies_without_normalization(_1_connection); \ + \ + NM_CONNECTION(g_object_ref(_1_connection)); \ + }) + +/*****************************************************************************/ + +static void +test_auto(void) +{ + const char *const *ARGV = NM_MAKE_STRV("ip=auto"); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connection = _parse_con(ARGV, "default_connection"); + + g_assert(!nm_connection_get_setting_vlan(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_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_MULTIPLE); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), ==, -1); + + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert(!nm_setting_wired_get_mac_address(s_wired)); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 0); + + 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(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 0); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip4)); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 0); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip6)); +} + +static void +test_dhcp_with_hostname(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("ip=::::host1::dhcp"); + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; + + connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + g_assert_cmpint(g_hash_table_size(connections), ==, 1); + g_assert_cmpstr(hostname, ==, "host1"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); + + connection = g_hash_table_lookup(connections, "default_connection"); + + nmtst_assert_connection_verifies_without_normalization(connection); + + g_assert(!nm_connection_get_setting_vlan(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_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_MULTIPLE); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), ==, -1); + + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert(!nm_setting_wired_get_mac_address(s_wired)); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 0); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); +} + +static void +test_dhcp_with_mtu(void) +{ + const char *const *ARGV0 = NM_MAKE_STRV("ip=:dhcp:1499"); + const char *const *ARGV1 = NM_MAKE_STRV("ip=::::::dhcp:1499"); + const char *const *ARGV[] = {ARGV0, ARGV1}; + guint i; + + for (i = 0; i < G_N_ELEMENTS(ARGV); i++) { + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connection = _parse_con(ARGV[i], "default_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_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_MULTIPLE); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), ==, -1); + + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert(!nm_setting_wired_get_mac_address(s_wired)); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 1499); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_AUTO); + } +} + +static void +test_if_auto_with_mtu(void) +{ + const char *const *ARGV = NM_MAKE_STRV("ip=eth0:auto:1666"); + gs_unref_object NMConnection *connection = NULL; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connection = _parse_con(ARGV, "eth0"); + + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 1666); + + 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(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); +} + +static void +test_if_dhcp6(void) +{ + const char *const *ARGV = NM_MAKE_STRV("ip=eth1:dhcp6"); + gs_unref_object NMConnection *connection = NULL; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connection = _parse_con(ARGV, "eth1"); + + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth1"); + + 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_DISABLED); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); +} + +static void +test_if_auto_with_mtu_and_mac(void) +{ + const char *const *ARGV = NM_MAKE_STRV("ip=eth2:auto6:2048:00:53:ef:12:34:56"); + gs_unref_object NMConnection *connection = NULL; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connection = _parse_con(ARGV, "eth2"); + + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth2"); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 2048); + g_assert_cmpstr(nm_setting_wired_get_cloned_mac_address(s_wired), ==, "00:53:EF:12:34:56"); + + 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_DISABLED); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); +} + +static void +test_if_ip4_manual(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("ip=192.0.2.2::192.0.2.1:255.255.255.0:" + "hostname0.example.com:eth3:none:192.0.2.53", + "ip=203.0.113.2::203.0.113.1:26:" + "hostname1.example.com:eth4"); + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMIPAddress * ip_addr; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; + + connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + g_assert_cmpint(g_hash_table_size(connections), ==, 2); + g_assert_cmpstr(hostname, ==, "hostname1.example.com"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); + + connection = g_hash_table_lookup(connections, "eth3"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth3"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), ==, -1); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + 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), ==, "192.0.2.53"); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 0); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip_addr); + g_assert_cmpstr(nm_ip_address_get_address(ip_addr), ==, "192.0.2.2"); + g_assert_cmpint(nm_ip_address_get_prefix(ip_addr), ==, 24); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "192.0.2.1"); + g_assert_cmpstr(nm_setting_ip_config_get_dhcp_hostname(s_ip4), ==, "hostname0.example.com"); + + 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(nm_setting_ip_config_get_may_fail(s_ip6)); + + connection = g_hash_table_lookup(connections, "eth4"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth4"); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 0); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 0); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip_addr); + g_assert_cmpstr(nm_ip_address_get_address(ip_addr), ==, "203.0.113.2"); + g_assert_cmpint(nm_ip_address_get_prefix(ip_addr), ==, 26); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "203.0.113.1"); + g_assert_cmpstr(nm_setting_ip_config_get_dhcp_hostname(s_ip4), ==, "hostname1.example.com"); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(nm_setting_ip_config_get_may_fail(s_ip6)); +} + +static void +test_if_ip6_manual(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("ip=[2001:0db8::02]/64::[2001:0db8::01]::" + "hostname0.example.com:eth4::[2001:0db8::53]"); + NMConnection * connection; + NMSettingIPConfig * s_ip6; + NMIPAddress * ip_addr; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; + + connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + g_assert_cmpint(g_hash_table_size(connections), ==, 1); + g_assert_cmpstr(hostname, ==, "hostname0.example.com"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); + + connection = g_hash_table_lookup(connections, "eth4"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth4"); + + 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_MANUAL); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + 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::53"); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip6), ==, 0); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 1); + ip_addr = nm_setting_ip_config_get_address(s_ip6, 0); + g_assert(ip_addr); + g_assert_cmpstr(nm_ip_address_get_address(ip_addr), ==, "2001:db8::2"); + g_assert_cmpint(nm_ip_address_get_prefix(ip_addr), ==, 64); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip6), ==, "2001:db8::1"); + g_assert_cmpstr(nm_setting_ip_config_get_dhcp_hostname(s_ip6), ==, "hostname0.example.com"); +} + +static void +test_if_off(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("ip=off", + "ip=ens3:off", + "ip=10.0.0.8:::::ens4:off", + "ip=[2001:DB8::8]:::::ens5:off"); + NMConnection * connection; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + struct { + const char name[32]; + const char ipv4_method[32]; + const char ipv6_method[32]; + + } conn_expected[] = { + {"default_connection", + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED}, + {"ens3", NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NM_SETTING_IP6_CONFIG_METHOD_DISABLED}, + {"ens4", NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NM_SETTING_IP6_CONFIG_METHOD_DISABLED}, + {"ens5", NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NM_SETTING_IP6_CONFIG_METHOD_MANUAL}, + }; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, G_N_ELEMENTS(conn_expected)); + + for (int i = 0; i < G_N_ELEMENTS(conn_expected); ++i) { + connection = g_hash_table_lookup(connections, conn_expected[i].name); + nmtst_assert_connection_verifies_without_normalization(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), ==, conn_expected[i].ipv4_method); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, conn_expected[i].ipv6_method); + } +} + +static void +test_if_mac_ifname(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("ip=[2001:0db8::42]/64::[2001:0db8::01]::" + "hostname0:00-11-22-33-44-55::[2001:0db8::53]"); + NMConnection * connection; + NMSettingIPConfig * s_ip6; + NMSettingWired * s_wired; + NMIPAddress * ip_addr; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; + + connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + g_assert_cmpint(g_hash_table_size(connections), ==, 1); + g_assert_cmpstr(hostname, ==, "hostname0"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); + + connection = g_hash_table_lookup(connections, "00:11:22:33:44:55"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "00:11:22:33:44:55"); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, NULL); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert_cmpstr(nm_setting_wired_get_mac_address(s_wired), ==, "00:11:22:33:44:55"); + + 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_MANUAL); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + 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::53"); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip6), ==, 0); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 1); + ip_addr = nm_setting_ip_config_get_address(s_ip6, 0); + g_assert(ip_addr); + g_assert_cmpstr(nm_ip_address_get_address(ip_addr), ==, "2001:db8::42"); + g_assert_cmpint(nm_ip_address_get_prefix(ip_addr), ==, 64); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip6), ==, "2001:db8::1"); + g_assert_cmpstr(nm_setting_ip_config_get_dhcp_hostname(s_ip6), ==, "hostname0"); +} + +static void +test_multiple_merge(void) +{ + const char *const *ARGV = + NM_MAKE_STRV("ip=192.0.2.2/16:::::eth0", "ip=[2001:db8::2]:::56::eth0"); + gs_unref_object NMConnection *connection = NULL; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMIPAddress * ip_addr; + + connection = _parse_con(ARGV, "eth0"); + + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), ==, -1); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip_addr); + g_assert_cmpstr(nm_ip_address_get_address(ip_addr), ==, "192.0.2.2"); + g_assert_cmpint(nm_ip_address_get_prefix(ip_addr), ==, 16); + + 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_MANUAL); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 1); + ip_addr = nm_setting_ip_config_get_address(s_ip6, 0); + g_assert(ip_addr); + g_assert_cmpstr(nm_ip_address_get_address(ip_addr), ==, "2001:db8::2"); + g_assert_cmpint(nm_ip_address_get_prefix(ip_addr), ==, 56); +} + +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", + "ip=eth5:link6", + "bootdev=eth4"); + + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 3); + + connection = g_hash_table_lookup(connections, "eth3"); + g_assert(connection); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), ==, -1); + 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_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), + ==, + NMI_WAIT_DEVICE_TIMEOUT_MS); + 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"); + + connection = g_hash_table_lookup(connections, "eth5"); + g_assert(connection); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), ==, -1); + 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_LINK_LOCAL); +} + +static void +test_bootdev(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("vlan=vlan2:ens5", "bootdev=ens3"); + NMConnection * connection; + NMSettingConnection * s_con; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 3); + + connection = g_hash_table_lookup(connections, "ens3"); + 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), ==, "ens3"); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, "ens3"); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), + ==, + NMI_WAIT_DEVICE_TIMEOUT_MS); + + connection = g_hash_table_lookup(connections, "vlan2"); + 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_VLAN_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "vlan2"); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, "vlan2"); + + connection = g_hash_table_lookup(connections, "ens5"); + 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), ==, "ens5"); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, "ens5"); +} + +static void +test_some_more(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("bootdev=eth1", + "hail", + "nameserver=[2001:DB8:3::53]", + "satan", + "nameserver=192.0.2.53", + "worship", + "doom", + "rd.peerdns=0", + "rd.route=[2001:DB8:3::/48]:[2001:DB8:2::1]:ens10"); + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMIPRoute * ip_route; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 2); + + connection = g_hash_table_lookup(connections, "eth1"); + 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), ==, "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_SINGLE); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + + 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(nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip4)); + 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), ==, "192.0.2.53"); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 1); + g_assert(!nm_setting_ip_config_get_gateway(s_ip6)); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 0), ==, "2001:db8:3::53"); + + connection = g_hash_table_lookup(connections, "ens10"); + 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), ==, "ens10"); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, "ens10"); + 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); + g_assert(!nm_setting_wired_get_mac_address(s_wired)); + + 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), ==, 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); + g_assert_cmpstr(nm_ip_route_get_dest(ip_route), ==, "2001:db8:3::"); + g_assert_cmpint(nm_ip_route_get_family(ip_route), ==, AF_INET6); + g_assert_cmpint(nm_ip_route_get_metric(ip_route), ==, -1); + g_assert_cmpstr(nm_ip_route_get_next_hop(ip_route), ==, "2001:db8:2::1"); + g_assert_cmpint(nm_ip_route_get_prefix(ip_route), ==, 48); +} + +static void +test_bond(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("rd.route=192.0.2.53::bong0", + "bond=bong0:eth0,eth1:mode=balance-rr", + "nameserver=203.0.113.53"); + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingBond * s_bond; + NMIPRoute * ip_route; + const char * master_uuid; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 3); + + connection = g_hash_table_lookup(connections, "bong0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_BOND_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "bong0"); + master_uuid = nm_connection_get_uuid(connection); + g_assert(master_uuid); + + 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(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + 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), ==, "203.0.113.53"); + g_assert(!nm_setting_ip_config_get_gateway(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 1); + ip_route = nm_setting_ip_config_get_route(s_ip4, 0); + g_assert_cmpstr(nm_ip_route_get_dest(ip_route), ==, "192.0.2.53"); + g_assert_cmpint(nm_ip_route_get_family(ip_route), ==, AF_INET); + g_assert_cmpint(nm_ip_route_get_metric(ip_route), ==, -1); + g_assert(!nm_ip_route_get_next_hop(ip_route)); + g_assert_cmpint(nm_ip_route_get_prefix(ip_route), ==, 32); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip6), ==, 0); + + s_bond = nm_connection_get_setting_bond(connection); + g_assert(s_bond); + g_assert_cmpint(nm_setting_bond_get_num_options(s_bond), ==, 1); + g_assert_cmpstr(nm_setting_bond_get_option_by_name(s_bond, "mode"), ==, "balance-rr"); + + connection = g_hash_table_lookup(connections, "eth0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "eth0"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NM_SETTING_BOND_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, master_uuid); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_SINGLE); + + connection = g_hash_table_lookup(connections, "eth1"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth1"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "eth1"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NM_SETTING_BOND_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, master_uuid); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_SINGLE); +} + +static void +test_bond_ip(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = + NM_MAKE_STRV("bond=bond0:eth0,eth1", + "ip=192.168.1.1::192.168.1.254:24::bond0:none:1480:01:02:03:04:05:06", + "nameserver=4.8.15.16"); + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingWired * s_wired; + NMSettingBond * s_bond; + NMIPAddress * ip_addr; + const char * master_uuid; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 3); + + connection = g_hash_table_lookup(connections, "bond0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_BOND_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "bond0"); + master_uuid = nm_connection_get_uuid(connection); + g_assert(master_uuid); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 1480); + g_assert_cmpstr(nm_setting_wired_get_cloned_mac_address(s_wired), ==, "01:02:03:04:05:06"); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip_addr); + g_assert_cmpstr(nm_ip_address_get_address(ip_addr), ==, "192.168.1.1"); + g_assert_cmpint(nm_ip_address_get_prefix(ip_addr), ==, 24); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "192.168.1.254"); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 1); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 0), ==, "4.8.15.16"); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 0); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip6), ==, 0); + + s_bond = nm_connection_get_setting_bond(connection); + g_assert(s_bond); + g_assert_cmpint(nm_setting_bond_get_num_options(s_bond), ==, 1); + g_assert_cmpstr(nm_setting_bond_get_option_by_name(s_bond, "mode"), ==, "balance-rr"); + + connection = g_hash_table_lookup(connections, "eth0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "eth0"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NM_SETTING_BOND_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, master_uuid); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_SINGLE); + + connection = g_hash_table_lookup(connections, "eth1"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth1"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "eth1"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NM_SETTING_BOND_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, master_uuid); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_SINGLE); +} + +static void +test_bond_default(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("bond"); + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingBond * s_bond; + const char * master_uuid; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 2); + + connection = g_hash_table_lookup(connections, "bond0"); + + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_BOND_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "bond0"); + master_uuid = nm_connection_get_uuid(connection); + g_assert(master_uuid); + + s_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(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 0); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip6), ==, 0); + + s_bond = nm_connection_get_setting_bond(connection); + g_assert(s_bond); + g_assert_cmpint(nm_setting_bond_get_num_options(s_bond), ==, 1); + g_assert_cmpstr(nm_setting_bond_get_option_by_name(s_bond, "mode"), ==, "balance-rr"); + + connection = g_hash_table_lookup(connections, "eth0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "eth0"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NM_SETTING_BOND_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, master_uuid); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_SINGLE); +} + +static void +test_bridge(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("bridge=bridge0:eth0,eth1", + "rd.route=192.0.2.53::bridge0", + "rd.net.timeout.dhcp=10"); + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingBridge * s_bridge; + NMIPRoute * ip_route; + const char * master_uuid; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 3); + + connection = g_hash_table_lookup(connections, "bridge0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_BRIDGE_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "bridge0"); + master_uuid = nm_connection_get_uuid(connection); + g_assert(master_uuid); + + 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(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 1); + g_assert_cmpint(nm_setting_ip_config_get_dhcp_timeout(s_ip4), ==, 10); + ip_route = nm_setting_ip_config_get_route(s_ip4, 0); + g_assert_cmpstr(nm_ip_route_get_dest(ip_route), ==, "192.0.2.53"); + g_assert_cmpint(nm_ip_route_get_family(ip_route), ==, AF_INET); + g_assert_cmpint(nm_ip_route_get_metric(ip_route), ==, -1); + g_assert(!nm_ip_route_get_next_hop(ip_route)); + g_assert_cmpint(nm_ip_route_get_prefix(ip_route), ==, 32); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip6), ==, 0); + g_assert_cmpint(nm_setting_ip_config_get_dhcp_timeout(s_ip6), ==, 10); + + s_bridge = nm_connection_get_setting_bridge(connection); + g_assert(s_bridge); + g_assert_cmpint(nm_setting_bridge_get_stp(s_bridge), ==, FALSE); + + connection = g_hash_table_lookup(connections, "eth0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "eth0"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_BRIDGE_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, master_uuid); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_SINGLE); + + connection = g_hash_table_lookup(connections, "eth1"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth1"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "eth1"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_BRIDGE_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, master_uuid); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_SINGLE); +} + +static void +test_bridge_default(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("bridge"); + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingBridge * s_bridge; + const char * master_uuid; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 2); + + connection = g_hash_table_lookup(connections, "br0"); + + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_BRIDGE_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "br0"); + master_uuid = nm_connection_get_uuid(connection); + g_assert(master_uuid); + + 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(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 0); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip6), ==, 0); + + s_bridge = nm_connection_get_setting_bridge(connection); + g_assert(s_bridge); + + connection = g_hash_table_lookup(connections, "eth0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "eth0"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_BRIDGE_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, master_uuid); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_SINGLE); +} + +static void +test_bridge_ip(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = + NM_MAKE_STRV("ip=bridge123:auto:1280:00:11:22:33:CA:fe", + "bridge=bridge123:eth0,eth1,eth2,eth3,eth4,eth5,eth6,eth7,eth8,eth9"); + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingWired * s_wired; + NMSettingBridge * s_bridge; + const char * master_uuid; + guint i; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 11); + + connection = g_hash_table_lookup(connections, "bridge123"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_BRIDGE_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "bridge123"); + master_uuid = nm_connection_get_uuid(connection); + g_assert(master_uuid); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 1280); + g_assert_cmpstr(nm_setting_wired_get_cloned_mac_address(s_wired), ==, "00:11:22:33:CA:FE"); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + + s_bridge = nm_connection_get_setting_bridge(connection); + g_assert(s_bridge); + + for (i = 0; i < 10; i++) { + char ifname[16]; + + nm_sprintf_buf(ifname, "eth%u", i); + + connection = g_hash_table_lookup(connections, ifname); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, ifname); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, ifname); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), + ==, + NM_SETTING_BRIDGE_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, master_uuid); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_SINGLE); + } +} + +static void +test_team(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("team=team0:eth0,eth1", "ip=team0:dhcp6"); + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingTeam * s_team; + const char * master_uuid; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 3); + + connection = g_hash_table_lookup(connections, "team0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_TEAM_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "team0"); + master_uuid = nm_connection_get_uuid(connection); + g_assert(master_uuid); + + 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_DISABLED); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip4)); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 0); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 0); + g_assert(!nm_setting_ip_config_get_gateway(s_ip6)); + g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip6), ==, 0); + + s_team = nm_connection_get_setting_team(connection); + g_assert(s_team); + + connection = g_hash_table_lookup(connections, "eth0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "eth0"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NM_SETTING_TEAM_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, master_uuid); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_SINGLE); + + connection = g_hash_table_lookup(connections, "eth1"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth1"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "eth1"); + g_assert_cmpstr(nm_setting_connection_get_slave_type(s_con), ==, NM_SETTING_TEAM_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, master_uuid); + g_assert_cmpint(nm_setting_connection_get_multi_connect(s_con), + ==, + NM_CONNECTION_MULTI_CONNECT_SINGLE); +} + +static void +test_vlan(void) +{ + const char *const *ARGV0 = NM_MAKE_STRV("ip=eth0.100:dhcp", "vlan=eth0.100:eth0"); + const char *const *ARGV1 = NM_MAKE_STRV("vlan=eth0.100:eth0", "ip=eth0.100:dhcp"); + const char *const *ARGV[] = {ARGV0, ARGV1}; + guint i; + + for (i = 0; i < G_N_ELEMENTS(ARGV); i++) { + gs_unref_hashtable GHashTable *connections = NULL; + NMConnection * connection; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingVlan * s_vlan; + + connections = _parse_cons(ARGV[i]); + g_assert_cmpint(g_hash_table_size(connections), ==, 2); + + /* VLAN eth0.100 */ + connection = g_hash_table_lookup(connections, "eth0.100"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_VLAN_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0.100"); + + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth0"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 100); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_AUTO); + + /* Ethernet eth0 */ + connection = g_hash_table_lookup(connections, "eth0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + + 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_DISABLED); + + 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); + } +} + +static void +test_vlan_with_dhcp_on_parent(void) +{ + const char *const *ARGV0 = NM_MAKE_STRV("vlan=eth0.100:eth0", "ip=eth0:dhcp"); + const char *const *ARGV1 = NM_MAKE_STRV("ip=eth0:dhcp", "vlan=eth0.100:eth0"); + const char *const *ARGV[] = {ARGV0, ARGV1}; + guint i; + + for (i = 0; i < G_N_ELEMENTS(ARGV); i++) { + gs_unref_hashtable GHashTable *connections = NULL; + NMConnection * connection; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingVlan * s_vlan; + + connections = _parse_cons(ARGV[i]); + g_assert_cmpint(g_hash_table_size(connections), ==, 2); + + /* VLAN eth0.100 */ + connection = g_hash_table_lookup(connections, "eth0.100"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_VLAN_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0.100"); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_AUTO); + + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "eth0"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 100); + + /* Ethernet eth0 */ + connection = g_hash_table_lookup(connections, "eth0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_AUTO); + } +} + +static void +test_vlan_over_bond(void) +{ + const char *const *ARGV0 = NM_MAKE_STRV("ip=1.2.3.4:::24::vlan1:none", + "bond=bond2:ens3,ens4:mode=active-backup", + "vlan=vlan1:bond2"); + const char *const *ARGV1 = NM_MAKE_STRV("vlan=vlan1:bond2", + "ip=1.2.3.4:::24::vlan1:none", + "bond=bond2:ens3,ens4:mode=active-backup"); + const char *const *ARGV2 = NM_MAKE_STRV("bond=bond2:ens3,ens4:mode=active-backup", + "ip=1.2.3.4:::24::vlan1:none", + "vlan=vlan1:bond2"); + const char *const *ARGV[] = {ARGV0, ARGV1, ARGV2}; + guint i; + + for (i = 0; i < G_N_ELEMENTS(ARGV); i++) { + gs_unref_hashtable GHashTable *connections = NULL; + NMConnection * connection; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMSettingVlan * s_vlan; + + connections = _parse_cons(ARGV[i]); + g_assert_cmpint(g_hash_table_size(connections), ==, 4); + + /* VLAN vlan1 */ + connection = g_hash_table_lookup(connections, "vlan1"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_VLAN_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "vlan1"); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + + 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); + + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "bond2"); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 1); + + /* Bond bond2 */ + connection = g_hash_table_lookup(connections, "bond2"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_BOND_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "bond2"); + + 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_DISABLED); + + 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); + + /* Ethernet ens3 and ens4 */ + connection = g_hash_table_lookup(connections, "ens3"); + g_assert(connection); + connection = g_hash_table_lookup(connections, "ens4"); + g_assert(connection); + } +} + +static void +test_ibft_ip_dev(void) +{ + const char *const * ARGV = NM_MAKE_STRV("ip=eth0:ibft"); + NMSettingConnection *s_con; + gs_unref_object NMConnection *connection = NULL; + + connection = _parse_con(ARGV, "eth0"); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_VLAN_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, NULL); +} + +static void +test_ibft_ip_dev_mac(void) +{ + const char *const * ARGV = NM_MAKE_STRV("ip=00-53-06-66-ab-01:ibft"); + NMSettingConnection *s_con; + gs_unref_object NMConnection *connection = NULL; + + connection = _parse_con(ARGV, "00:53:06:66:AB:01"); + + 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_interface_name(s_con), ==, NULL); +} + +static void +_test_ibft_ip(const char *const *ARGV) +{ + gs_unref_hashtable GHashTable *connections = NULL; + NMConnection * connection; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 2); + + connection = g_hash_table_lookup(connections, "ibft0"); + nmtst_assert_connection_verifies_without_normalization(connection); + + g_assert_cmpstr(nm_connection_get_id(connection), ==, "iBFT VLAN Connection 0"); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, NULL); + + connection = g_hash_table_lookup(connections, "ibft2"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "iBFT Connection 2"); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, NULL); +} + +static void +test_ibft_ip(void) +{ + const char *const *ARGV = NM_MAKE_STRV("ip=ibft"); + + _test_ibft_ip(ARGV); +} + +static void +test_ibft_rd_iscsi_ibft(void) +{ + const char *const *ARGV = NM_MAKE_STRV("rd.iscsi.ibft"); + + _test_ibft_ip(ARGV); +} + +static void +test_ignore_extra(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("blabla", "extra", "lalala"); + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 0); +} + +static void +test_rd_znet(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const *const ARGV = + NM_MAKE_STRV("ip=10.11.12.13::10.11.12.1:24:foo.example.com:enc800:none", + "ip=slc600:dhcp", + "rd.znet=qeth,0.0.0800,0.0.0801,0.0.0802,layer2=0,portno=1", + "rd.znet=ctc,0.0.0600,0.0.0601,layer2=0,portno=0"); + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingWired * s_wired; + const char *const * v_subchannels; + const NMUtilsNamedValue s390_options[] = { + {.name = "layer2", .value_str = "0"}, + {.name = "portno", .value_str = "1"}, + }; + int i_s390_options_keys; + gs_free char *hostname = NULL; + gint64 carrier_timeout_sec = 0; + + connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + g_assert_cmpint(g_hash_table_size(connections), ==, 2); + g_assert_cmpstr(hostname, ==, "foo.example.com"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); + + connection = g_hash_table_lookup(connections, "enc800"); + g_assert(NM_IS_CONNECTION(connection)); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(NM_IS_SETTING_CONNECTION(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), ==, "enc800"); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, "enc800"); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(NM_IS_SETTING_WIRED(s_wired)); + + v_subchannels = nm_setting_wired_get_s390_subchannels(s_wired); + g_assert(v_subchannels); + g_assert_cmpstr(v_subchannels[0], ==, "0.0.0800"); + g_assert_cmpstr(v_subchannels[1], ==, "0.0.0801"); + g_assert_cmpstr(v_subchannels[2], ==, "0.0.0802"); + g_assert_cmpstr(v_subchannels[3], ==, NULL); + + g_assert_cmpint(nm_setting_wired_get_num_s390_options(s_wired), ==, G_N_ELEMENTS(s390_options)); + for (i_s390_options_keys = 0; i_s390_options_keys < G_N_ELEMENTS(s390_options); + i_s390_options_keys++) { + const NMUtilsNamedValue *s390_option = &s390_options[i_s390_options_keys]; + const char * k; + const char * v; + const char * v2; + + g_assert(s390_option->name); + g_assert(s390_option->value_str); + v = nm_setting_wired_get_s390_option_by_key(s_wired, s390_option->name); + g_assert(v); + g_assert_cmpstr(v, ==, s390_option->value_str); + + if (!nm_setting_wired_get_s390_option(s_wired, i_s390_options_keys, &k, &v2)) + g_assert_not_reached(); + g_assert_cmpstr(k, ==, s390_option->name); + g_assert(v == v2); + g_assert_cmpstr(v2, ==, s390_option->value_str); + } + + nmtst_assert_connection_verifies_without_normalization(connection); + + connection = g_hash_table_lookup(connections, "slc600"); + g_assert(NM_IS_CONNECTION(connection)); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(NM_IS_SETTING_CONNECTION(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), ==, "slc600"); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, "slc600"); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(NM_IS_SETTING_WIRED(s_wired)); + + v_subchannels = nm_setting_wired_get_s390_subchannels(s_wired); + g_assert(v_subchannels); + g_assert_cmpstr(v_subchannels[0], ==, "0.0.0600"); + g_assert_cmpstr(v_subchannels[1], ==, "0.0.0601"); + g_assert_cmpstr(v_subchannels[2], ==, NULL); + + nmtst_assert_connection_verifies_without_normalization(connection); +} + +static void +test_rd_znet_legacy(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const *const ARGV = + NM_MAKE_STRV("ip=10.11.12.13::10.11.12.1:24:foo.example.com:eth0:none", + "rd.znet=qeth,0.0.0800,0.0.0801,0.0.0802,layer2=0,portno=1", + "rd.znet=ctc,0.0.0600,0.0.0601,layer2=0,portno=0", + "ip=ctc0:dhcp", + "net.ifnames=0"); + NMConnection * connection; + NMSettingConnection *s_con; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; + + connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + g_assert_cmpint(g_hash_table_size(connections), ==, 2); + g_assert_cmpstr(hostname, ==, "foo.example.com"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); + + connection = g_hash_table_lookup(connections, "eth0"); + g_assert(NM_IS_CONNECTION(connection)); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(NM_IS_SETTING_CONNECTION(s_con)); + g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con), + ==, + NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "eth0"); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, "eth0"); + + nmtst_assert_connection_verifies_without_normalization(connection); + + connection = g_hash_table_lookup(connections, "ctc0"); + g_assert(NM_IS_CONNECTION(connection)); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(NM_IS_SETTING_CONNECTION(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), ==, "ctc0"); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, "ctc0"); + + nmtst_assert_connection_verifies_without_normalization(connection); +} + +static void +test_rd_znet_no_ip(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const *const ARGV = + NM_MAKE_STRV("rd.znet=qeth,0.0.0800,0.0.0801,0.0.0802,layer2=0,portno=1"); + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 0); +} + +static void +test_bootif_ip(void) +{ + const char *const *ARGV = NM_MAKE_STRV("BOOTIF=00:53:AB:cd:02:03", "ip=dhcp"); + gs_unref_object NMConnection *connection = NULL; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connection = _parse_con(ARGV, "default_connection"); + + g_assert_cmpstr(nm_connection_get_id(connection), ==, "Wired Connection"); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert_cmpstr(nm_setting_wired_get_mac_address(s_wired), ==, "00:53:AB:CD:02:03"); + g_assert(s_wired); + + 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(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + g_assert(!nm_setting_ip_config_get_may_fail(s_ip4)); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); +} + +static void +test_neednet(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("rd.neednet", + "ip=eno1:dhcp", + "ip=172.25.1.100::172.25.1.1:24::eno2", + "bridge=br0:eno3"); + NMConnection * connection; + NMSettingConnection * s_con; + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 4); + + connection = g_hash_table_lookup(connections, "eno1"); + 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_interface_name(s_con), ==, "eno1"); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), + ==, + NMI_WAIT_DEVICE_TIMEOUT_MS); + + connection = g_hash_table_lookup(connections, "eno2"); + 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_interface_name(s_con), ==, "eno2"); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), + ==, + NMI_WAIT_DEVICE_TIMEOUT_MS); + + connection = g_hash_table_lookup(connections, "eno3"); + 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_interface_name(s_con), ==, "eno3"); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), + ==, + NMI_WAIT_DEVICE_TIMEOUT_MS); + + connection = g_hash_table_lookup(connections, "br0"); + 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_interface_name(s_con), ==, "br0"); + g_assert_cmpint(nm_setting_connection_get_wait_device_timeout(s_con), ==, -1); +} + +static void +test_bootif_no_ip(void) +{ + const char *const *ARGV = NM_MAKE_STRV("BOOTIF=00:53:AB:cd:02:03"); + gs_unref_object NMConnection *connection = NULL; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connection = _parse_con(ARGV, "default_connection"); + + g_assert_cmpstr(nm_connection_get_id(connection), ==, "Wired Connection"); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert_cmpstr(nm_setting_wired_get_mac_address(s_wired), ==, "00:53:AB:CD:02:03"); + g_assert(s_wired); + + 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(nm_setting_ip_config_get_may_fail(s_ip4)); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(nm_setting_ip_config_get_may_fail(s_ip6)); +} + +static void +test_bootif_hwtype(void) +{ + const char *const *ARGV0 = NM_MAKE_STRV("ip=eth0:dhcp", "BOOTIF=01-00-53-AB-cd-02-03"); + const char *const *ARGV1 = NM_MAKE_STRV("ip=eth0:dhcp", "BOOTIF=00-00-53-Ab-cD-02-03"); + const char *const *ARGV[] = {ARGV0, ARGV1}; + guint i; + + for (i = 0; i < G_N_ELEMENTS(ARGV); i++) { + gs_unref_hashtable GHashTable *connections = NULL; + NMConnection * connection; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + + connections = _parse_cons(ARGV[i]); + g_assert_cmpint(g_hash_table_size(connections), ==, 2); + + connection = g_hash_table_lookup(connections, "eth0"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "eth0"); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(!nm_setting_wired_get_mac_address(s_wired)); + g_assert(s_wired); + + 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(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + g_assert(!nm_setting_ip_config_get_may_fail(s_ip4)); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + + connection = g_hash_table_lookup(connections, "bootif_connection"); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert_cmpstr(nm_connection_get_id(connection), ==, "BOOTIF Connection"); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert_cmpstr(nm_setting_wired_get_mac_address(s_wired), ==, "00:53:AB:CD:02:03"); + g_assert(s_wired); + + 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(!nm_setting_ip_config_get_ignore_auto_dns(s_ip4)); + g_assert(nm_setting_ip_config_get_may_fail(s_ip4)); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert(!nm_setting_ip_config_get_ignore_auto_dns(s_ip6)); + g_assert(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; + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; + + connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + g_assert_cmpint(g_hash_table_size(connections), ==, 3); + g_assert_cmpstr(hostname, ==, "foo.example.com"); + g_assert_cmpint(carrier_timeout_sec, ==, 0); + + connection = g_hash_table_lookup(connections, "eth0"); + 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"); + 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"); + 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) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const *ARGV = NM_MAKE_STRV("BOOTIF=01-00-53-AB-cd-02-03", "rd.bootif=0"); + + connections = _parse_cons(ARGV); + g_assert_cmpint(g_hash_table_size(connections), ==, 0); +} + +static void +test_dhcp_vendor_class_id(void) +{ + const char *const *ARGV; + gs_unref_object NMConnection *connection = NULL; + NMSettingIP4Config * s_ip4; + gs_free char * vci_long = NULL; + char vci_arg_long[512] = {0}; + + ARGV = NM_MAKE_STRV("rd.net.dhcp.vendor-class=testvci", "ip=eno1:dhcp"); + connection = _parse_con(ARGV, "eno1"); + s_ip4 = NM_SETTING_IP4_CONFIG(nm_connection_get_setting_ip4_config(connection)); + g_assert_cmpstr(nm_setting_ip4_config_get_dhcp_vendor_class_identifier(s_ip4), ==, "testvci"); + + g_clear_object(&connection); + + ARGV = NM_MAKE_STRV("rd.net.dhcp.vendor-class", "ip=eno1:dhcp"); + connection = _parse_con(ARGV, "eno1"); + s_ip4 = NM_SETTING_IP4_CONFIG(nm_connection_get_setting_ip4_config(connection)); + g_assert(nm_setting_ip4_config_get_dhcp_vendor_class_identifier(s_ip4) == NULL); + + g_clear_object(&connection); + + memset(vci_arg_long, 'A', 400); + vci_long = g_strdup_printf("rd.net.dhcp.vendor-class=%s", vci_arg_long); + ARGV = NM_MAKE_STRV(vci_long, "ip=eno1:dhcp"); + connection = _parse_con(ARGV, "eno1"); + s_ip4 = NM_SETTING_IP4_CONFIG(nm_connection_get_setting_ip4_config(connection)); + g_assert(nm_setting_ip4_config_get_dhcp_vendor_class_identifier(s_ip4) == NULL); +} + +static void +test_infiniband_iface(void) +{ + const char *const *ARGV = NM_MAKE_STRV("ip=ib1:dhcp"); + gs_unref_object NMConnection *connection = NULL; + NMSettingInfiniband * s_ib; + + connection = _parse_con(ARGV, "ib1"); + + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_INFINIBAND_SETTING_NAME); + s_ib = nm_connection_get_setting_infiniband(connection); + g_assert(s_ib); +} + +static void +test_infiniband_mac(void) +{ + const char *const *ARGV = + NM_MAKE_STRV("ip=00-11-22-33-44-55-66-77-88-99-aa-bb-cc-dd-ee-ff-00-11-22-33:dhcp"); + gs_unref_object NMConnection *connection = NULL; + NMSettingInfiniband * s_ib; + + connection = _parse_con(ARGV, "00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33"); + + g_assert_cmpstr(nm_connection_get_connection_type(connection), + ==, + NM_SETTING_INFINIBAND_SETTING_NAME); + g_assert_cmpstr(nm_connection_get_interface_name(connection), ==, NULL); + s_ib = nm_connection_get_setting_infiniband(connection); + g_assert(s_ib); + g_assert_cmpstr(nm_setting_infiniband_get_mac_address(s_ib), + ==, + "00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33"); +} + +static void +test_carrier_timeout(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const * ARGV = NM_MAKE_STRV("rd.net.timeout.carrier=20"); + gs_free char * hostname = NULL; + gint64 carrier_timeout_sec = 0; + + connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + g_assert_cmpint(g_hash_table_size(connections), ==, 0); + g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 20); +} + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init_assert_logging(&argc, &argv, "INFO", "DEFAULT"); + + g_test_add_func("/initrd/cmdline/auto", test_auto); + g_test_add_func("/initrd/cmdline/dhcp_with_hostname", test_dhcp_with_hostname); + g_test_add_func("/initrd/cmdline/dhcp_with_mtu", test_dhcp_with_mtu); + g_test_add_func("/initrd/cmdline/if_auto_with_mtu", test_if_auto_with_mtu); + g_test_add_func("/initrd/cmdline/if_dhcp6", test_if_dhcp6); + 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/if_mac_ifname", test_if_mac_ifname); + g_test_add_func("/initrd/cmdline/if_off", test_if_off); + 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); + g_test_add_func("/initrd/cmdline/bond/ip", test_bond_ip); + g_test_add_func("/initrd/cmdline/bond/default", test_bond_default); + g_test_add_func("/initrd/cmdline/team", test_team); + g_test_add_func("/initrd/cmdline/vlan", test_vlan); + g_test_add_func("/initrd/cmdline/vlan/dhcp-on-parent", test_vlan_with_dhcp_on_parent); + g_test_add_func("/initrd/cmdline/vlan/over-bond", test_vlan_over_bond); + g_test_add_func("/initrd/cmdline/bridge", test_bridge); + g_test_add_func("/initrd/cmdline/bridge/default", test_bridge_default); + g_test_add_func("/initrd/cmdline/bridge/ip", test_bridge_ip); + g_test_add_func("/initrd/cmdline/ibft/ip_dev", test_ibft_ip_dev); + g_test_add_func("/initrd/cmdline/ibft/ip_dev_mac", test_ibft_ip_dev_mac); + g_test_add_func("/initrd/cmdline/ibft/ip", test_ibft_ip); + g_test_add_func("/initrd/cmdline/ibft/rd_iscsi_ibft", test_ibft_rd_iscsi_ibft); + g_test_add_func("/initrd/cmdline/ignore_extra", test_ignore_extra); + g_test_add_func("/initrd/cmdline/rd_znet", test_rd_znet); + g_test_add_func("/initrd/cmdline/rd_znet/legacy", test_rd_znet_legacy); + g_test_add_func("/initrd/cmdline/rd_znet/no_ip", test_rd_znet_no_ip); + g_test_add_func("/initrd/cmdline/bootif/ip", test_bootif_ip); + g_test_add_func("/initrd/cmdline/bootif/no_ip", test_bootif_no_ip); + g_test_add_func("/initrd/cmdline/bootif/hwtype", test_bootif_hwtype); + g_test_add_func("/initrd/cmdline/bootif/off", test_bootif_off); + g_test_add_func("/initrd/cmdline/neednet", test_neednet); + g_test_add_func("/initrd/cmdline/dhcp/vendor_class_id", test_dhcp_vendor_class_id); + g_test_add_func("/initrd/cmdline/infiniband/iface", test_infiniband_iface); + g_test_add_func("/initrd/cmdline/infiniband/mac", test_infiniband_mac); + g_test_add_func("/initrd/cmdline/carrier_timeout", test_carrier_timeout); + + return g_test_run(); +} diff --git a/src/core/initrd/tests/test-dt-reader.c b/src/core/initrd/tests/test-dt-reader.c new file mode 100644 index 00000000..619a4e6f --- /dev/null +++ b/src/core/initrd/tests/test-dt-reader.c @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 - 2018 Red Hat, Inc. + */ + +#include "src/core/nm-default-daemon.h" + +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/socket.h> + +#include "nm-core-internal.h" +#include "NetworkManagerUtils.h" + +#include "../nm-initrd-generator.h" + +#include "nm-test-utils-core.h" + +#define TEST_INITRD_DIR NM_BUILD_SRCDIR "/src/core/initrd/tests" + +/*****************************************************************************/ + +static void +test_read_dt_ofw(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + const char * mac_address; + + connection = nmi_dt_reader_parse(TEST_INITRD_DIR "/sysfs-dt"); + g_assert(connection); + nmtst_assert_connection_verifies(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), ==, "OpenFirmware Connection"); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + mac_address = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac_address); + g_assert(nm_utils_hwaddr_matches(mac_address, -1, "ac:7f:3e:e5:d8:d8", -1)); + g_assert(!nm_setting_wired_get_duplex(s_wired)); + g_assert_cmpint(nm_setting_wired_get_speed(s_wired), ==, 0); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 0); + + 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_cmpstr(nm_setting_ip_config_get_dhcp_hostname(s_ip4), ==, "demiurge"); + + 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_object_unref(connection); +} + +static void +test_read_dt_slof(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + NMIPAddress * ip4_addr; + + connection = nmi_dt_reader_parse(TEST_INITRD_DIR "/sysfs-dt-tftp"); + g_assert(connection); + nmtst_assert_connection_verifies(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), ==, "OpenFirmware Connection"); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + g_assert(!nm_setting_wired_get_mac_address(s_wired)); + g_assert_cmpstr(nm_setting_wired_get_duplex(s_wired), ==, "half"); + g_assert_cmpint(nm_setting_wired_get_speed(s_wired), ==, 10); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 0); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "192.168.32.2"); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 16); + + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "192.168.32.1"); + + 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_object_unref(connection); +} + +static void +test_read_dt_none(void) +{ + NMConnection *connection; + + connection = nmi_dt_reader_parse(TEST_INITRD_DIR "/sysfs"); + g_assert(!connection); +} + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init_assert_logging(&argc, &argv, "INFO", "DEFAULT"); + + g_test_add_func("/initrd/dt/ofw", test_read_dt_ofw); + g_test_add_func("/initrd/dt/slof", test_read_dt_slof); + g_test_add_func("/initrd/dt/none", test_read_dt_none); + + return g_test_run(); +} diff --git a/src/core/initrd/tests/test-ibft-reader.c b/src/core/initrd/tests/test-ibft-reader.c new file mode 100644 index 00000000..1d263b9e --- /dev/null +++ b/src/core/initrd/tests/test-ibft-reader.c @@ -0,0 +1,303 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2014 - 2018 Red Hat, Inc. + */ + +#include "src/core/nm-default-daemon.h" + +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/socket.h> + +#include "nm-core-internal.h" +#include "NetworkManagerUtils.h" + +#include "../nm-initrd-generator.h" + +#include "nm-test-utils-core.h" + +#define TEST_INITRD_DIR NM_BUILD_SRCDIR "/src/core/initrd/tests" + +/*****************************************************************************/ + +static NMConnection * +read_connection(const char *sysfs_dir, const char *expected_mac, GError **error) +{ + NMConnection * connection = NULL; + gs_unref_hashtable GHashTable *ibft = NULL; + gs_free char * mac = NULL; + GHashTable * nic = NULL; + + ibft = nmi_ibft_read(sysfs_dir); + + mac = g_ascii_strup(expected_mac, -1); + nic = g_hash_table_lookup(ibft, mac); + if (!nic) + return NULL; + + connection = nm_simple_connection_new(); + + if (!nmi_ibft_update_connection_from_nic(connection, nic, error)) + g_clear_object(&connection); + + return connection; +} + +static void +test_read_ibft_dhcp(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GError * error = NULL; + const char * mac_address; + const char * expected_mac_address = "00:33:21:98:b9:f1"; + + connection = read_connection(TEST_INITRD_DIR "/sysfs-dhcp", expected_mac_address, &error); + g_assert_no_error(error); + nmtst_assert_connection_verifies_without_normalization(connection); + + g_assert(!nm_connection_get_setting_vlan(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), ==, "iBFT Connection 1"); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, NULL); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + mac_address = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac_address); + g_assert(nm_utils_hwaddr_matches(mac_address, -1, expected_mac_address, -1)); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 0); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED); + + g_object_unref(connection); +} + +static void +test_read_ibft_static(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingIPConfig * s_ip4; + NMSettingIPConfig * s_ip6; + GError * error = NULL; + const char * mac_address; + const char * expected_mac_address = "00:33:21:98:b9:f0"; + NMIPAddress * ip4_addr; + + connection = read_connection(TEST_INITRD_DIR "/sysfs-static", expected_mac_address, &error); + g_assert_no_error(error); + nmtst_assert_connection_verifies_without_normalization(connection); + + g_assert(!nm_connection_get_setting_vlan(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), ==, "iBFT Connection 0"); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, NULL); + g_assert_cmpint(nm_setting_connection_get_timestamp(s_con), ==, 0); + g_assert(nm_setting_connection_get_autoconnect(s_con)); + + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + mac_address = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac_address); + g_assert(nm_utils_hwaddr_matches(mac_address, -1, expected_mac_address, -1)); + g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 0); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 2); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 0), ==, "10.16.255.2"); + g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 1), ==, "10.16.255.3"); + + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "192.168.32.72"); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 22); + + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "192.168.35.254"); + + 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_object_unref(connection); +} + +static void +test_read_ibft_bad_address(gconstpointer user_data) +{ + const char * sysfs_dir = user_data; + NMConnection *connection; + GError * error = NULL; + + g_assert(g_file_test(sysfs_dir, G_FILE_TEST_EXISTS)); + + connection = read_connection(sysfs_dir, "00:33:21:98:b9:f0", &error); + g_assert(connection == NULL); + g_assert(error); + g_clear_error(&error); +} + +static void +test_read_ibft_vlan(void) +{ + NMConnection * connection; + NMSettingConnection *s_con; + NMSettingWired * s_wired; + NMSettingVlan * s_vlan; + NMSettingIPConfig * s_ip4; + const char * mac_address; + const char * expected_mac_address = "00:33:21:98:b9:f0"; + NMIPAddress * ip4_addr; + GError * error = NULL; + + connection = read_connection(TEST_INITRD_DIR "/sysfs-vlan", expected_mac_address, &error); + g_assert_no_error(error); + 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_VLAN_SETTING_NAME); + g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, NULL); + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired(connection); + g_assert(s_wired); + mac_address = nm_setting_wired_get_mac_address(s_wired); + g_assert(mac_address); + g_assert(nm_utils_hwaddr_matches(mac_address, -1, expected_mac_address, -1)); + + /* ===== VLAN SETTING ===== */ + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); + g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 123); + g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, NULL); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + + g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 0); + + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address(s_ip4, 0); + g_assert(ip4_addr); + g_assert_cmpstr(nm_ip_address_get_address(ip4_addr), ==, "192.168.6.200"); + g_assert_cmpint(nm_ip_address_get_prefix(ip4_addr), ==, 24); + + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, NULL); + + g_object_unref(connection); +} + +static void +test_read_ibft(void) +{ + NMConnection * connection; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + GError * error = NULL; + + /* This test doesn't actually test too much (apart from the presence of + * IPv6 that is not covered by other tests), but the test fixture is a good + * example of about everything that can be included in iBFT table (as of + * ACPI 3.0b). */ + + connection = read_connection(TEST_INITRD_DIR "/sysfs", "00:53:00:AB:00:01", &error); + g_assert(connection); + g_assert_no_error(error); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + nmtst_assert_connection_verifies_without_normalization(connection); + g_assert(nm_setting_ip_config_get_num_addresses(s_ip4) == 0); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), + ==, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(nm_setting_ip_config_get_num_addresses(s_ip6) == 1); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_object_unref(connection); + + connection = read_connection(TEST_INITRD_DIR "/sysfs", "00:53:06:66:AB:01", &error); + g_assert(connection); + g_assert_no_error(error); + nmtst_assert_connection_verifies_without_normalization(connection); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(nm_setting_ip_config_get_num_addresses(s_ip4) == 1); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(nm_setting_ip_config_get_num_addresses(s_ip6) == 0); + g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6), + ==, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED); + g_object_unref(connection); +} + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init_assert_logging(&argc, &argv, "INFO", "DEFAULT"); + + g_test_add_func("/initrd/ibft", test_read_ibft); + g_test_add_func("/initrd/ibft/dhcp", test_read_ibft_dhcp); + g_test_add_func("/initrd/ibft/static", test_read_ibft_static); + g_test_add_func("/initrd/ibft/vlan", test_read_ibft_vlan); + g_test_add_data_func("/initrd/ibft/bad-ipaddr-read", + TEST_INITRD_DIR "/sysfs-bad-ipaddr", + test_read_ibft_bad_address); + g_test_add_data_func("/initrd/ibft/bad-gateway-read", + TEST_INITRD_DIR "/sysfs-bad-gateway", + test_read_ibft_bad_address); + g_test_add_data_func("/initrd/ibft/bad-dns1-read", + TEST_INITRD_DIR "/sysfs-bad-dns1", + test_read_ibft_bad_address); + g_test_add_data_func("/initrd/ibft/bad-dns2-read", + TEST_INITRD_DIR "/sysfs-bad-dns2", + test_read_ibft_bad_address); + + return g_test_run(); +} |