diff options
Diffstat (limited to 'src/core/initrd/nmi-ibft-reader.c')
| -rw-r--r-- | src/core/initrd/nmi-ibft-reader.c | 463 |
1 files changed, 0 insertions, 463 deletions
diff --git a/src/core/initrd/nmi-ibft-reader.c b/src/core/initrd/nmi-ibft-reader.c deleted file mode 100644 index 9895cda4..00000000 --- a/src/core/initrd/nmi-ibft-reader.c +++ /dev/null @@ -1,463 +0,0 @@ -/* 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; -} |