merge: branch 'nbft-parser-1'
initrd: add new NBFT parser https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2077
This commit is contained in:
@@ -60,11 +60,11 @@ variables:
|
|||||||
#
|
#
|
||||||
# This is done by running `ci-fairy generate-template` and possibly bumping
|
# This is done by running `ci-fairy generate-template` and possibly bumping
|
||||||
# ".default_tag".
|
# ".default_tag".
|
||||||
ALPINE_TAG: 'tag-77ec3d923fd6'
|
ALPINE_TAG: 'tag-57edf560bf4f'
|
||||||
CENTOS_TAG: 'tag-7a677f4838e1'
|
CENTOS_TAG: 'tag-7ea4f50c8578'
|
||||||
DEBIAN_TAG: 'tag-ecad19904683'
|
DEBIAN_TAG: 'tag-1601ce2572c5'
|
||||||
FEDORA_TAG: 'tag-7a677f4838e1'
|
FEDORA_TAG: 'tag-7ea4f50c8578'
|
||||||
UBUNTU_TAG: 'tag-ecad19904683'
|
UBUNTU_TAG: 'tag-1601ce2572c5'
|
||||||
|
|
||||||
ALPINE_EXEC: 'bash .gitlab-ci/alpine-install.sh'
|
ALPINE_EXEC: 'bash .gitlab-ci/alpine-install.sh'
|
||||||
CENTOS_EXEC: 'bash .gitlab-ci/fedora-install.sh'
|
CENTOS_EXEC: 'bash .gitlab-ci/fedora-install.sh'
|
||||||
|
@@ -280,3 +280,8 @@
|
|||||||
/* Define to 1 if you have history support from -lreadline. */
|
/* Define to 1 if you have history support from -lreadline. */
|
||||||
#mesondefine HAVE_READLINE_HISTORY
|
#mesondefine HAVE_READLINE_HISTORY
|
||||||
|
|
||||||
|
/* Define if NBFT support is enabled */
|
||||||
|
#mesondefine WITH_NBFT
|
||||||
|
|
||||||
|
/* Define to 1 if dlvsym() is available */
|
||||||
|
#mesondefine HAVE_DLVSYM
|
||||||
|
@@ -24,6 +24,7 @@ apk add \
|
|||||||
'jansson-dev' \
|
'jansson-dev' \
|
||||||
'libgudev-dev' \
|
'libgudev-dev' \
|
||||||
'libndp-dev' \
|
'libndp-dev' \
|
||||||
|
'libnvme-dev' \
|
||||||
'libnl3-dev' \
|
'libnl3-dev' \
|
||||||
'libpsl-dev' \
|
'libpsl-dev' \
|
||||||
'libsoup-dev' \
|
'libsoup-dev' \
|
||||||
|
@@ -56,6 +56,7 @@ install \
|
|||||||
libndp-dev \
|
libndp-dev \
|
||||||
libnewt-dev \
|
libnewt-dev \
|
||||||
libnss3-dev \
|
libnss3-dev \
|
||||||
|
libnvme-dev \
|
||||||
libpolkit-gobject-1-dev \
|
libpolkit-gobject-1-dev \
|
||||||
libpsl-dev \
|
libpsl-dev \
|
||||||
libreadline-dev \
|
libreadline-dev \
|
||||||
|
@@ -66,6 +66,7 @@ install \
|
|||||||
jq \
|
jq \
|
||||||
libcurl-devel \
|
libcurl-devel \
|
||||||
libndp-devel \
|
libndp-devel \
|
||||||
|
libnvme-devel \
|
||||||
libselinux-devel \
|
libselinux-devel \
|
||||||
libtool \
|
libtool \
|
||||||
libuuid-devel \
|
libuuid-devel \
|
||||||
|
@@ -307,6 +307,7 @@ BuildRequires: libubsan
|
|||||||
BuildRequires: firewalld-filesystem
|
BuildRequires: firewalld-filesystem
|
||||||
BuildRequires: iproute
|
BuildRequires: iproute
|
||||||
BuildRequires: iproute-tc
|
BuildRequires: iproute-tc
|
||||||
|
BuildRequires: libnvme-devel >= 1.5
|
||||||
|
|
||||||
Provides: %{name}-dispatcher%{?_isa} = %{epoch}:%{version}-%{release}
|
Provides: %{name}-dispatcher%{?_isa} = %{epoch}:%{version}-%{release}
|
||||||
|
|
||||||
|
@@ -54,10 +54,15 @@ _WITH_WERROR=1
|
|||||||
_WITH_LIBTEAM="true"
|
_WITH_LIBTEAM="true"
|
||||||
_WITH_DOCS="true"
|
_WITH_DOCS="true"
|
||||||
_WITH_SYSTEMD_LOGIND="true"
|
_WITH_SYSTEMD_LOGIND="true"
|
||||||
|
_WITH_NBFT="true"
|
||||||
if [ $IS_ALPINE = 1 ]; then
|
if [ $IS_ALPINE = 1 ]; then
|
||||||
_WITH_SYSTEMD_LOGIND="false"
|
_WITH_SYSTEMD_LOGIND="false"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! pkgconf 'libnvme >= 1.5'; then
|
||||||
|
_WITH_NBFT="false"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -z "${NMTST_SEED_RAND+x}" ]; then
|
if [ -z "${NMTST_SEED_RAND+x}" ]; then
|
||||||
NMTST_SEED_RAND="$SRANDOM"
|
NMTST_SEED_RAND="$SRANDOM"
|
||||||
if [ -z "$NMTST_SEED_RAND" ]; then
|
if [ -z "$NMTST_SEED_RAND" ]; then
|
||||||
@@ -181,6 +186,8 @@ meson setup build \
|
|||||||
-D ifcfg_rh=false \
|
-D ifcfg_rh=false \
|
||||||
-D ifupdown=true \
|
-D ifupdown=true \
|
||||||
\
|
\
|
||||||
|
-D nbft=$_WITH_NBFT \
|
||||||
|
\
|
||||||
#end
|
#end
|
||||||
|
|
||||||
export NM_TEST_CLIENT_CHECK_L10N=1
|
export NM_TEST_CLIENT_CHECK_L10N=1
|
||||||
|
@@ -154,6 +154,7 @@
|
|||||||
<member><option>net.ifnames</option></member>
|
<member><option>net.ifnames</option></member>
|
||||||
<member><option>rd.peerdns</option></member>
|
<member><option>rd.peerdns</option></member>
|
||||||
<member><option>rd.iscsi.ibft</option></member>
|
<member><option>rd.iscsi.ibft</option></member>
|
||||||
|
<member><option>rd.nvmf.nonbft</option></member>
|
||||||
<member><option>rd.bootif</option></member>
|
<member><option>rd.bootif</option></member>
|
||||||
<member><option>rd.neednet</option></member>
|
<member><option>rd.neednet</option></member>
|
||||||
<member><option>rd.ethtool</option></member>
|
<member><option>rd.ethtool</option></member>
|
||||||
|
11
meson.build
11
meson.build
@@ -137,6 +137,9 @@ config_h.set10('HAVE_DECL_REALLOCARRAY', cc.has_function('reallocarray', prefix:
|
|||||||
config_h.set10('HAVE_DECL_EXPLICIT_BZERO', cc.has_function('explicit_bzero', prefix: '#include <string.h>'))
|
config_h.set10('HAVE_DECL_EXPLICIT_BZERO', cc.has_function('explicit_bzero', prefix: '#include <string.h>'))
|
||||||
config_h.set10('HAVE_DECL_MEMFD_CREATE', cc.has_function('memfd_create', prefix: '#include <sys/mman.h>'))
|
config_h.set10('HAVE_DECL_MEMFD_CREATE', cc.has_function('memfd_create', prefix: '#include <sys/mman.h>'))
|
||||||
|
|
||||||
|
config_h.set10('HAVE_DLVSYM', cc.has_function('dlvsym', prefix: '''#define _GNU_SOURCE
|
||||||
|
#include <dlfcn.h>'''))
|
||||||
|
|
||||||
# types
|
# types
|
||||||
config_h.set('SIZEOF_PID_T', cc.sizeof('pid_t', prefix : '#include <sys/types.h>'))
|
config_h.set('SIZEOF_PID_T', cc.sizeof('pid_t', prefix : '#include <sys/types.h>'))
|
||||||
config_h.set('SIZEOF_UID_T', cc.sizeof('uid_t', prefix : '#include <sys/types.h>'))
|
config_h.set('SIZEOF_UID_T', cc.sizeof('uid_t', prefix : '#include <sys/types.h>'))
|
||||||
@@ -929,6 +932,14 @@ if python.found()
|
|||||||
config_h.set_quoted('TEST_NM_PYTHON', python_path)
|
config_h.set_quoted('TEST_NM_PYTHON', python_path)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# libnvme (NBFT support)
|
||||||
|
enable_nbft = get_option('nbft')
|
||||||
|
if enable_nbft
|
||||||
|
libnvme_dep = dependency('libnvme', version: '>= 1.5', required: false)
|
||||||
|
assert(libnvme_dep.found(), 'NBFT support was requested, but the libnvme library is not available. Use -Dnbft=false to build without it.')
|
||||||
|
endif
|
||||||
|
config_h.set10('WITH_NBFT', enable_nbft)
|
||||||
|
|
||||||
data_conf = configuration_data()
|
data_conf = configuration_data()
|
||||||
data_conf.set('DISTRO_NETWORK_SERVICE', (enable_ifcfg_rh ? 'network.service' : ''))
|
data_conf.set('DISTRO_NETWORK_SERVICE', (enable_ifcfg_rh ? 'network.service' : ''))
|
||||||
data_conf.set('NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT', config_default_logging_audit)
|
data_conf.set('NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT', config_default_logging_audit)
|
||||||
|
@@ -45,6 +45,7 @@ option('nmtui', type: 'boolean', value: true, description: 'Build nmtui')
|
|||||||
option('nm_cloud_setup', type: 'boolean', value: true, description: 'Build nm-cloud-setup, a tool for automatically configuring networking in cloud')
|
option('nm_cloud_setup', type: 'boolean', value: true, description: 'Build nm-cloud-setup, a tool for automatically configuring networking in cloud')
|
||||||
option('bluez5_dun', type: 'boolean', value: false, description: 'enable Bluez5 DUN support')
|
option('bluez5_dun', type: 'boolean', value: false, description: 'enable Bluez5 DUN support')
|
||||||
option('ebpf', type: 'combo', choices: ['auto', 'true', 'false'], description: 'Enable eBPF support')
|
option('ebpf', type: 'combo', choices: ['auto', 'true', 'false'], description: 'Enable eBPF support')
|
||||||
|
option('nbft', type: 'boolean', value: true, description: 'Enable NBFT support in the initrd generator')
|
||||||
|
|
||||||
# configuration plugins
|
# configuration plugins
|
||||||
option('config_plugins_default', type: 'string', value: '', description: 'Default configuration option for main.plugins setting, used as fallback if the configuration option is unset')
|
option('config_plugins_default', type: 'string', value: '', description: 'Default configuration option for main.plugins setting, used as fallback if the configuration option is unset')
|
||||||
|
@@ -6,6 +6,7 @@ libnmi_core = static_library(
|
|||||||
'nmi-cmdline-reader.c',
|
'nmi-cmdline-reader.c',
|
||||||
'nmi-dt-reader.c',
|
'nmi-dt-reader.c',
|
||||||
'nmi-ibft-reader.c',
|
'nmi-ibft-reader.c',
|
||||||
|
'nmi-nbft-reader.c',
|
||||||
),
|
),
|
||||||
include_directories: [
|
include_directories: [
|
||||||
src_inc,
|
src_inc,
|
||||||
|
@@ -41,6 +41,8 @@ nmi_ibft_update_connection_from_nic(NMConnection *connection, GHashTable *nic, G
|
|||||||
|
|
||||||
NMConnection *nmi_dt_reader_parse(const char *sysfs_dir);
|
NMConnection *nmi_dt_reader_parse(const char *sysfs_dir);
|
||||||
|
|
||||||
|
NMConnection **nmi_nbft_reader_parse(const char *sysfs_dir, char **hostname);
|
||||||
|
|
||||||
GHashTable *nmi_cmdline_reader_parse(const char *etc_connections_dir,
|
GHashTable *nmi_cmdline_reader_parse(const char *etc_connections_dir,
|
||||||
const char *sysfs_dir,
|
const char *sysfs_dir,
|
||||||
const char *const *argv,
|
const char *const *argv,
|
||||||
|
@@ -1451,8 +1451,10 @@ nmi_cmdline_reader_parse(const char *etc_connections_dir,
|
|||||||
gs_unref_ptrarray GPtrArray *routes = NULL;
|
gs_unref_ptrarray GPtrArray *routes = NULL;
|
||||||
gs_unref_ptrarray GPtrArray *znets = NULL;
|
gs_unref_ptrarray GPtrArray *znets = NULL;
|
||||||
int i;
|
int i;
|
||||||
guint64 dhcp_timeout = 90;
|
guint64 dhcp_timeout = 90;
|
||||||
guint64 dhcp_num_tries = 1;
|
guint64 dhcp_num_tries = 1;
|
||||||
|
gboolean nvmf_nonbft = FALSE;
|
||||||
|
gboolean have_dracut_nbft = FALSE;
|
||||||
|
|
||||||
reader = reader_new();
|
reader = reader_new();
|
||||||
|
|
||||||
@@ -1469,7 +1471,10 @@ nmi_cmdline_reader_parse(const char *etc_connections_dir,
|
|||||||
/* pass */
|
/* pass */
|
||||||
} else if (nm_streq(tag, "net.ifnames"))
|
} else if (nm_streq(tag, "net.ifnames"))
|
||||||
net_ifnames = !nm_streq(argument, "0");
|
net_ifnames = !nm_streq(argument, "0");
|
||||||
else if (nm_streq(tag, "rd.peerdns"))
|
else if (nm_streq(tag, "ifname")) {
|
||||||
|
if (NM_STR_HAS_PREFIX(argument, "nbft"))
|
||||||
|
have_dracut_nbft = TRUE;
|
||||||
|
} else if (nm_streq(tag, "rd.peerdns"))
|
||||||
reader->ignore_auto_dns = !_nm_utils_ascii_str_to_bool(argument, TRUE);
|
reader->ignore_auto_dns = !_nm_utils_ascii_str_to_bool(argument, TRUE);
|
||||||
else if (nm_streq(tag, "rd.net.timeout.dhcp")) {
|
else if (nm_streq(tag, "rd.net.timeout.dhcp")) {
|
||||||
if (nm_streq0(argument, "infinity")) {
|
if (nm_streq0(argument, "infinity")) {
|
||||||
@@ -1561,7 +1566,18 @@ nmi_cmdline_reader_parse(const char *etc_connections_dir,
|
|||||||
reader_parse_dns_backend(reader, argument);
|
reader_parse_dns_backend(reader, argument);
|
||||||
} else if (nm_streq(tag, "rd.net.dns-resolve-mode")) {
|
} else if (nm_streq(tag, "rd.net.dns-resolve-mode")) {
|
||||||
reader_parse_dns_resolve_mode(reader, argument);
|
reader_parse_dns_resolve_mode(reader, argument);
|
||||||
|
} else if (nm_streq(tag, "rd.nvmf.nonbft"))
|
||||||
|
nvmf_nonbft = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nvmf_nonbft && !have_dracut_nbft) {
|
||||||
|
NMConnection **nbft_connections, **c;
|
||||||
|
|
||||||
|
nbft_connections = nmi_nbft_reader_parse(sysfs_dir, &reader->hostname);
|
||||||
|
for (c = nbft_connections; c && *c; c++) {
|
||||||
|
reader_add_connection(reader, nm_connection_get_id(*c), *c);
|
||||||
}
|
}
|
||||||
|
g_free(nbft_connections);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < reader->vlan_parents->len; i++) {
|
for (i = 0; i < reader->vlan_parents->len; i++) {
|
||||||
|
414
src/nm-initrd-generator/nmi-nbft-reader.c
Normal file
414
src/nm-initrd-generator/nmi-nbft-reader.c
Normal file
@@ -0,0 +1,414 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Red Hat, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libnm-core-impl/nm-default-libnm-core.h"
|
||||||
|
|
||||||
|
#include "nm-initrd-generator.h"
|
||||||
|
|
||||||
|
#if WITH_NBFT
|
||||||
|
|
||||||
|
#include <libnvme.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include "libnm-log-core/nm-logging.h"
|
||||||
|
#include "libnm-core-intern/nm-core-internal.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
#define _NMLOG(level, domain, ...) \
|
||||||
|
nm_log((level), \
|
||||||
|
(domain), \
|
||||||
|
NULL, \
|
||||||
|
NULL, \
|
||||||
|
"nbft-reader: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) _NM_UTILS_MACRO_REST(__VA_ARGS__))
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
is_valid_addr(int family, const char *addr)
|
||||||
|
{
|
||||||
|
return (addr && strlen(addr) > 0 && !nm_streq(addr, "0.0.0.0") && !nm_streq(addr, "::")
|
||||||
|
&& nm_utils_ipaddr_valid(family, addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int (*_nvme_nbft_read)(struct nbft_info **nbft, const char *filename);
|
||||||
|
static void (*_nvme_nbft_free)(struct nbft_info *nbft);
|
||||||
|
|
||||||
|
static void *
|
||||||
|
load_libnvme(void)
|
||||||
|
{
|
||||||
|
void *handle;
|
||||||
|
|
||||||
|
handle = dlopen("libnvme.so.1", RTLD_LAZY);
|
||||||
|
if (!handle)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
#if HAVE_DLVSYM
|
||||||
|
_nvme_nbft_read = dlvsym(handle, "nvme_nbft_read", "LIBNVME_1_5");
|
||||||
|
_nvme_nbft_free = dlvsym(handle, "nvme_nbft_free", "LIBNVME_1_5");
|
||||||
|
#else
|
||||||
|
/* no dlvsym() in musl */
|
||||||
|
_nvme_nbft_read = dlsym(handle, "nvme_nbft_read");
|
||||||
|
_nvme_nbft_free = dlsym(handle, "nvme_nbft_free");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!_nvme_nbft_read || !_nvme_nbft_free) {
|
||||||
|
dlclose(handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
format_conn_name(const char *table_name, struct nbft_info_hfi *hfi, gboolean is_vlan)
|
||||||
|
{
|
||||||
|
if (is_vlan) {
|
||||||
|
nm_assert(hfi->tcp_info.vlan > 0);
|
||||||
|
return g_strdup_printf("%s connection HFI %d VLAN %d",
|
||||||
|
table_name,
|
||||||
|
hfi->index,
|
||||||
|
hfi->tcp_info.vlan);
|
||||||
|
} else
|
||||||
|
return g_strdup_printf("%s connection HFI %d", table_name, hfi->index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NMConnection *
|
||||||
|
find_conn_for_wired_mac(GPtrArray *a, const char *hwaddr)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < a->len; i++) {
|
||||||
|
NMConnection *con = a->pdata[i];
|
||||||
|
NMSettingWired *s_wired;
|
||||||
|
|
||||||
|
if (!nm_connection_is_type(con, NM_SETTING_WIRED_SETTING_NAME))
|
||||||
|
continue;
|
||||||
|
s_wired = nm_connection_get_setting_wired(con);
|
||||||
|
if (!s_wired)
|
||||||
|
continue;
|
||||||
|
if (nm_streq(hwaddr, nm_setting_wired_get_mac_address(s_wired)))
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NMConnection *
|
||||||
|
create_wired_conn(struct nbft_info_hfi *hfi,
|
||||||
|
const char *conn_name,
|
||||||
|
const char *hwaddr,
|
||||||
|
gboolean is_vlan)
|
||||||
|
{
|
||||||
|
NMConnection *connection;
|
||||||
|
NMSetting *s_connection;
|
||||||
|
NMSetting *s_wired;
|
||||||
|
|
||||||
|
connection = nm_simple_connection_new();
|
||||||
|
|
||||||
|
s_connection = nm_setting_connection_new();
|
||||||
|
g_object_set(s_connection,
|
||||||
|
NM_SETTING_CONNECTION_TYPE,
|
||||||
|
is_vlan ? NM_SETTING_VLAN_SETTING_NAME : NM_SETTING_WIRED_SETTING_NAME,
|
||||||
|
NM_SETTING_CONNECTION_ID,
|
||||||
|
conn_name,
|
||||||
|
NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY,
|
||||||
|
NMI_AUTOCONNECT_PRIORITY_FIRMWARE,
|
||||||
|
NULL);
|
||||||
|
nm_connection_add_setting(connection, s_connection);
|
||||||
|
|
||||||
|
/* MAC address */
|
||||||
|
s_wired = nm_setting_wired_new();
|
||||||
|
g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, hwaddr, NULL);
|
||||||
|
nm_connection_add_setting(connection, s_wired);
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_hfi(GPtrArray *a, struct nbft_info_hfi *hfi, const char *table_name, char **hostname)
|
||||||
|
{
|
||||||
|
gs_unref_object NMConnection *connection = NULL;
|
||||||
|
NMConnection *parent_connection;
|
||||||
|
NMSetting *s_vlan;
|
||||||
|
gs_free char *hwaddr = NULL;
|
||||||
|
gs_free char *conn_name = NULL;
|
||||||
|
gs_unref_object NMSetting *s_ip4 = NULL;
|
||||||
|
gs_unref_object NMSetting *s_ip6 = NULL;
|
||||||
|
nm_auto_unref_ip_address NMIPAddress *ipaddr = NULL;
|
||||||
|
guint prefix;
|
||||||
|
gs_free_error GError *error = NULL;
|
||||||
|
int family = AF_UNSPEC;
|
||||||
|
NMIPAddr addr_bin;
|
||||||
|
|
||||||
|
/* Pre-checks */
|
||||||
|
if (!nm_inet_parse_bin_full(family, FALSE, hfi->tcp_info.ipaddr, &family, &addr_bin)) {
|
||||||
|
_LOGW(LOGD_CORE, "NBFT: Malformed IP address: '%s'", hfi->tcp_info.ipaddr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MAC address */
|
||||||
|
hwaddr = g_strdup_printf("%02X:%02X:%02X:%02X:%02X:%02X",
|
||||||
|
hfi->tcp_info.mac_addr[0],
|
||||||
|
hfi->tcp_info.mac_addr[1],
|
||||||
|
hfi->tcp_info.mac_addr[2],
|
||||||
|
hfi->tcp_info.mac_addr[3],
|
||||||
|
hfi->tcp_info.mac_addr[4],
|
||||||
|
hfi->tcp_info.mac_addr[5]);
|
||||||
|
|
||||||
|
/* First check if we need VLANs */
|
||||||
|
if (hfi->tcp_info.vlan > 0) {
|
||||||
|
parent_connection = find_conn_for_wired_mac(a, hwaddr);
|
||||||
|
if (!parent_connection) {
|
||||||
|
/* Create new parent wired connection */
|
||||||
|
conn_name = format_conn_name(table_name, hfi, FALSE);
|
||||||
|
parent_connection = create_wired_conn(hfi, conn_name, hwaddr, FALSE);
|
||||||
|
|
||||||
|
s_ip4 = nm_setting_ip4_config_new();
|
||||||
|
s_ip6 = nm_setting_ip6_config_new();
|
||||||
|
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_DISABLED,
|
||||||
|
NULL);
|
||||||
|
nm_connection_add_setting(parent_connection, g_steal_pointer(&s_ip4));
|
||||||
|
nm_connection_add_setting(parent_connection, g_steal_pointer(&s_ip6));
|
||||||
|
|
||||||
|
if (!nm_connection_normalize(parent_connection, NULL, NULL, &error)) {
|
||||||
|
_LOGW(LOGD_CORE, "Generated an invalid connection: %s", error->message);
|
||||||
|
g_object_unref(parent_connection);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_ptr_array_add(a, parent_connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
conn_name = format_conn_name(table_name, hfi, TRUE);
|
||||||
|
connection = create_wired_conn(hfi, conn_name, hwaddr, TRUE);
|
||||||
|
|
||||||
|
s_vlan = nm_setting_vlan_new();
|
||||||
|
g_object_set(s_vlan, NM_SETTING_VLAN_ID, hfi->tcp_info.vlan, NULL);
|
||||||
|
nm_connection_add_setting(connection, s_vlan);
|
||||||
|
} else {
|
||||||
|
/* No VLANS */
|
||||||
|
conn_name = format_conn_name(table_name, hfi, FALSE);
|
||||||
|
connection = create_wired_conn(hfi, conn_name, hwaddr, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IP addresses */
|
||||||
|
s_ip4 = nm_setting_ip4_config_new();
|
||||||
|
s_ip6 = nm_setting_ip6_config_new();
|
||||||
|
|
||||||
|
switch (family) {
|
||||||
|
/* IPv4 */
|
||||||
|
case AF_INET:
|
||||||
|
g_object_set(s_ip6,
|
||||||
|
NM_SETTING_IP_CONFIG_METHOD,
|
||||||
|
NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
|
||||||
|
NULL);
|
||||||
|
if (is_valid_addr(AF_INET, hfi->tcp_info.dhcp_server_ipaddr)) {
|
||||||
|
g_object_set(s_ip4,
|
||||||
|
NM_SETTING_IP_CONFIG_METHOD,
|
||||||
|
NM_SETTING_IP4_CONFIG_METHOD_AUTO,
|
||||||
|
NULL);
|
||||||
|
if (hfi->tcp_info.host_name && strlen(hfi->tcp_info.host_name) > 0) {
|
||||||
|
g_object_set(s_ip4,
|
||||||
|
NM_SETTING_IP_CONFIG_DHCP_HOSTNAME,
|
||||||
|
hfi->tcp_info.host_name,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_object_set(s_ip4,
|
||||||
|
NM_SETTING_IP_CONFIG_METHOD,
|
||||||
|
NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
|
||||||
|
NULL);
|
||||||
|
ipaddr = nm_ip_address_new_binary(AF_INET,
|
||||||
|
&addr_bin,
|
||||||
|
hfi->tcp_info.subnet_mask_prefix,
|
||||||
|
&error);
|
||||||
|
if (!ipaddr) {
|
||||||
|
_LOGW(LOGD_CORE,
|
||||||
|
"Cannot parse IP %s/%u: %s",
|
||||||
|
hfi->tcp_info.ipaddr,
|
||||||
|
hfi->tcp_info.subnet_mask_prefix,
|
||||||
|
error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nm_setting_ip_config_add_address(NM_SETTING_IP_CONFIG(s_ip4), ipaddr);
|
||||||
|
if (is_valid_addr(AF_INET, hfi->tcp_info.gateway_ipaddr)) {
|
||||||
|
g_object_set(s_ip4,
|
||||||
|
NM_SETTING_IP_CONFIG_GATEWAY,
|
||||||
|
hfi->tcp_info.gateway_ipaddr,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
if (is_valid_addr(AF_INET, hfi->tcp_info.primary_dns_ipaddr)) {
|
||||||
|
nm_setting_ip_config_add_dns(NM_SETTING_IP_CONFIG(s_ip4),
|
||||||
|
hfi->tcp_info.primary_dns_ipaddr);
|
||||||
|
}
|
||||||
|
if (is_valid_addr(AF_INET, hfi->tcp_info.secondary_dns_ipaddr)) {
|
||||||
|
nm_setting_ip_config_add_dns(NM_SETTING_IP_CONFIG(s_ip4),
|
||||||
|
hfi->tcp_info.secondary_dns_ipaddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* IPv6 */
|
||||||
|
case AF_INET6:
|
||||||
|
g_object_set(s_ip4,
|
||||||
|
NM_SETTING_IP_CONFIG_METHOD,
|
||||||
|
NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
||||||
|
NULL);
|
||||||
|
if (is_valid_addr(AF_INET6, hfi->tcp_info.dhcp_server_ipaddr)) {
|
||||||
|
g_object_set(s_ip6,
|
||||||
|
NM_SETTING_IP_CONFIG_METHOD,
|
||||||
|
NM_SETTING_IP6_CONFIG_METHOD_AUTO,
|
||||||
|
NULL);
|
||||||
|
if (hfi->tcp_info.host_name && strlen(hfi->tcp_info.host_name) > 0) {
|
||||||
|
g_object_set(s_ip6,
|
||||||
|
NM_SETTING_IP_CONFIG_DHCP_HOSTNAME,
|
||||||
|
hfi->tcp_info.host_name,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_object_set(s_ip6,
|
||||||
|
NM_SETTING_IP_CONFIG_METHOD,
|
||||||
|
NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
|
||||||
|
NULL);
|
||||||
|
prefix = hfi->tcp_info.subnet_mask_prefix;
|
||||||
|
if (prefix == 0) {
|
||||||
|
/* Buggy firmware implementations may report prefix=0 for v6 addresses,
|
||||||
|
* let's fall back to /64.
|
||||||
|
*/
|
||||||
|
_LOGW(LOGD_CORE,
|
||||||
|
"NBFT: Invalid IPv6 prefix %d, using /64 as a fallback.",
|
||||||
|
hfi->tcp_info.subnet_mask_prefix);
|
||||||
|
prefix = 64;
|
||||||
|
}
|
||||||
|
ipaddr = nm_ip_address_new_binary(AF_INET6, &addr_bin, prefix, &error);
|
||||||
|
if (!ipaddr) {
|
||||||
|
_LOGW(LOGD_CORE,
|
||||||
|
"Cannot parse IP %s/%u: %s",
|
||||||
|
hfi->tcp_info.ipaddr,
|
||||||
|
prefix,
|
||||||
|
error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nm_setting_ip_config_add_address(NM_SETTING_IP_CONFIG(s_ip6), ipaddr);
|
||||||
|
if (is_valid_addr(AF_INET6, hfi->tcp_info.gateway_ipaddr)) {
|
||||||
|
g_object_set(s_ip6,
|
||||||
|
NM_SETTING_IP_CONFIG_GATEWAY,
|
||||||
|
hfi->tcp_info.gateway_ipaddr,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
if (is_valid_addr(AF_INET6, hfi->tcp_info.primary_dns_ipaddr)) {
|
||||||
|
nm_setting_ip_config_add_dns(NM_SETTING_IP_CONFIG(s_ip6),
|
||||||
|
hfi->tcp_info.primary_dns_ipaddr);
|
||||||
|
}
|
||||||
|
if (is_valid_addr(AF_INET6, hfi->tcp_info.secondary_dns_ipaddr)) {
|
||||||
|
nm_setting_ip_config_add_dns(NM_SETTING_IP_CONFIG(s_ip6),
|
||||||
|
hfi->tcp_info.secondary_dns_ipaddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_warn_if_reached();
|
||||||
|
}
|
||||||
|
|
||||||
|
nm_connection_add_setting(connection, g_steal_pointer(&s_ip4));
|
||||||
|
nm_connection_add_setting(connection, g_steal_pointer(&s_ip6));
|
||||||
|
|
||||||
|
/* Hostname */
|
||||||
|
if (hfi->tcp_info.host_name && strlen(hfi->tcp_info.host_name) > 0) {
|
||||||
|
g_free(*hostname);
|
||||||
|
*hostname = g_strdup(hfi->tcp_info.host_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: translate the following HFI struct members?
|
||||||
|
* hfi->tcp_info.pci_sbdf
|
||||||
|
* hfi->tcp_info.ip_origin
|
||||||
|
* hfi->tcp_info.dhcp_server_ipaddr
|
||||||
|
* hfi->tcp_info.this_hfi_is_default_route
|
||||||
|
* hfi->tcp_info.dhcp_override
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!nm_connection_normalize(connection, NULL, NULL, &error)) {
|
||||||
|
_LOGW(LOGD_CORE, "Generated an invalid connection: %s", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ptr_array_add(a, g_steal_pointer(&connection));
|
||||||
|
}
|
||||||
|
|
||||||
|
NMConnection **
|
||||||
|
nmi_nbft_reader_parse(const char *sysfs_dir, char **hostname)
|
||||||
|
{
|
||||||
|
nm_auto_unref_ptrarray GPtrArray *a = NULL;
|
||||||
|
gs_free char *path = NULL;
|
||||||
|
gs_free_error GError *error = NULL;
|
||||||
|
GDir *dir;
|
||||||
|
void *libnvme_handle = NULL;
|
||||||
|
const char *entry_name;
|
||||||
|
|
||||||
|
g_return_val_if_fail(sysfs_dir != NULL, NULL);
|
||||||
|
path = g_build_filename(sysfs_dir, "firmware", "acpi", "tables", NULL);
|
||||||
|
|
||||||
|
dir = g_dir_open(path, 0, NULL);
|
||||||
|
if (!dir)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
a = g_ptr_array_new();
|
||||||
|
|
||||||
|
while ((entry_name = g_dir_read_name(dir))) {
|
||||||
|
gs_free char *entry_path = NULL;
|
||||||
|
struct nbft_info *nbft;
|
||||||
|
struct nbft_info_hfi **hfi;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!g_str_has_prefix(entry_name, "NBFT"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* attempt to load libnvme only on the first table match, saving some I/O */
|
||||||
|
if (!libnvme_handle && !(libnvme_handle = load_libnvme())) {
|
||||||
|
g_dir_close(dir);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_path = g_build_filename(path, entry_name, NULL);
|
||||||
|
ret = _nvme_nbft_read(&nbft, entry_path);
|
||||||
|
if (ret) {
|
||||||
|
_LOGW(LOGD_CORE, "Error parsing NBFT table %s: %m", entry_path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (hfi = nbft->hfi_list; hfi && *hfi; hfi++) {
|
||||||
|
if (!nm_streq((*hfi)->transport, "tcp")) {
|
||||||
|
_LOGW(LOGD_CORE,
|
||||||
|
"NBFT table %s, HFI descriptor %d: unsupported transport type '%s'",
|
||||||
|
entry_path,
|
||||||
|
(*hfi)->index,
|
||||||
|
(*hfi)->transport);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
parse_hfi(a, *hfi, entry_name, hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
_nvme_nbft_free(nbft);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_dir_close(dir);
|
||||||
|
dlclose(libnvme_handle);
|
||||||
|
g_ptr_array_add(a, NULL); /* trailing NULL-delimiter */
|
||||||
|
return (NMConnection **) g_ptr_array_free(g_steal_pointer(&a), FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* WITH_NBFT */
|
||||||
|
|
||||||
|
NMConnection **
|
||||||
|
nmi_nbft_reader_parse(const char *sysfs_dir, char **hostname)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -224,6 +224,7 @@ RUN dnf install -y \\
|
|||||||
libasan \\
|
libasan \\
|
||||||
libcurl-devel \\
|
libcurl-devel \\
|
||||||
libndp-devel \\
|
libndp-devel \\
|
||||||
|
libnvme-devel \\
|
||||||
libpsl-devel \\
|
libpsl-devel \\
|
||||||
libselinux-devel \\
|
libselinux-devel \\
|
||||||
libtool \\
|
libtool \\
|
||||||
|
Reference in New Issue
Block a user