|
Packit Service |
5ffa24 |
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
Packit Service |
5ffa24 |
/*
|
|
Packit Service |
5ffa24 |
* Copyright (C) 2018 Red Hat, Inc.
|
|
Packit Service |
5ffa24 |
*/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
2bceb2 |
#include "src/core/nm-default-daemon.h"
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#include <linux/if_ether.h>
|
|
Packit Service |
5ffa24 |
#include <linux/if_infiniband.h>
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#include "nm-core-internal.h"
|
|
Packit Service |
5ffa24 |
#include "nm-initrd-generator.h"
|
|
Packit Service |
5ffa24 |
#include "systemd/nm-sd-utils-shared.h"
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
#define _NMLOG(level, domain, ...) \
|
|
Packit Service |
5ffa24 |
nm_log((level), \
|
|
Packit Service |
5ffa24 |
(domain), \
|
|
Packit Service |
5ffa24 |
NULL, \
|
|
Packit Service |
5ffa24 |
NULL, \
|
|
Packit Service |
5ffa24 |
"cmdline-reader: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) \
|
|
Packit Service |
5ffa24 |
_NM_UTILS_MACRO_REST(__VA_ARGS__))
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*****************************************************************************/
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
typedef struct {
|
|
Packit Service |
5ffa24 |
GHashTable * hash;
|
|
Packit Service |
5ffa24 |
GPtrArray * array;
|
|
Packit Service |
5ffa24 |
GPtrArray * vlan_parents;
|
|
Packit Service |
5ffa24 |
GHashTable * explicit_ip_connections;
|
|
Packit Service |
5ffa24 |
NMConnection *bootdev_connection; /* connection for bootdev=$ifname */
|
|
Packit Service |
5ffa24 |
NMConnection *default_connection; /* connection not bound to any ifname */
|
|
Packit Service |
5ffa24 |
char * hostname;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* Parameters to be set for all connections */
|
|
Packit Service |
5ffa24 |
gboolean ignore_auto_dns;
|
|
Packit Service |
5ffa24 |
int dhcp_timeout;
|
|
Packit Service |
5ffa24 |
char * dhcp4_vci;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
gint64 carrier_timeout_sec;
|
|
Packit Service |
5ffa24 |
} Reader;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static Reader *
|
|
Packit Service |
5ffa24 |
reader_new(void)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
Reader *reader;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
reader = g_slice_new(Reader);
|
|
Packit Service |
5ffa24 |
*reader = (Reader){
|
|
Packit Service |
5ffa24 |
.hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_object_unref),
|
|
Packit Service |
5ffa24 |
.explicit_ip_connections =
|
|
Packit Service |
5ffa24 |
g_hash_table_new_full(nm_direct_hash, NULL, g_object_unref, NULL),
|
|
Packit Service |
5ffa24 |
.vlan_parents = g_ptr_array_new_with_free_func(g_free),
|
|
Packit Service |
5ffa24 |
.array = g_ptr_array_new(),
|
|
Packit Service |
5ffa24 |
};
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
return reader;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static GHashTable *
|
|
Packit Service |
5ffa24 |
reader_destroy(Reader *reader, gboolean free_hash)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
gs_unref_hashtable GHashTable *hash = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_ptr_array_unref(reader->array);
|
|
Packit Service |
5ffa24 |
g_ptr_array_unref(reader->vlan_parents);
|
|
Packit Service |
5ffa24 |
g_hash_table_unref(reader->explicit_ip_connections);
|
|
Packit Service |
5ffa24 |
hash = g_steal_pointer(&reader->hash);
|
|
Packit Service |
5ffa24 |
nm_clear_g_free(&reader->hostname);
|
|
Packit Service |
5ffa24 |
nm_clear_g_free(&reader->dhcp4_vci);
|
|
Packit Service |
5ffa24 |
nm_g_slice_free(reader);
|
|
Packit Service |
5ffa24 |
if (!free_hash)
|
|
Packit Service |
5ffa24 |
return g_steal_pointer(&hash);
|
|
Packit Service |
5ffa24 |
return NULL;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static NMConnection *
|
|
Packit Service |
5ffa24 |
reader_add_connection(Reader *reader, const char *name, NMConnection *connection_take)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
char *name_dup;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
name_dup = g_strdup(name);
|
|
Packit Service |
5ffa24 |
if (g_hash_table_insert(reader->hash, name_dup, connection_take))
|
|
Packit Service |
5ffa24 |
g_ptr_array_add(reader->array, name_dup);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
return connection_take;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* Returns a new connection owned by the reader */
|
|
Packit Service |
5ffa24 |
static NMConnection *
|
|
Packit Service |
5ffa24 |
reader_create_connection(Reader * reader,
|
|
Packit Service |
5ffa24 |
const char * basename,
|
|
Packit Service |
5ffa24 |
const char * id,
|
|
Packit Service |
5ffa24 |
const char * ifname,
|
|
Packit Service |
5ffa24 |
const char * mac,
|
|
Packit Service |
5ffa24 |
const char * type_name,
|
|
Packit Service |
5ffa24 |
NMConnectionMultiConnect multi_connect)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMConnection *connection;
|
|
Packit Service |
5ffa24 |
NMSetting * setting;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
connection = reader_add_connection(reader, basename, nm_simple_connection_new());
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* Start off assuming dynamic IP configurations. */
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
setting = nm_setting_ip4_config_new();
|
|
Packit Service |
5ffa24 |
nm_connection_add_setting(connection, setting);
|
|
Packit Service |
5ffa24 |
g_object_set(setting,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP4_CONFIG_METHOD_AUTO,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_MAY_FAIL,
|
|
Packit Service |
5ffa24 |
TRUE,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS,
|
|
Packit Service |
5ffa24 |
reader->ignore_auto_dns,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_DHCP_TIMEOUT,
|
|
Packit Service |
5ffa24 |
reader->dhcp_timeout,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER,
|
|
Packit Service |
5ffa24 |
reader->dhcp4_vci,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
setting = nm_setting_ip6_config_new();
|
|
Packit Service |
5ffa24 |
nm_connection_add_setting(connection, setting);
|
|
Packit Service |
5ffa24 |
g_object_set(setting,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP4_CONFIG_METHOD_AUTO,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_MAY_FAIL,
|
|
Packit Service |
5ffa24 |
TRUE,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE,
|
|
Packit Service |
5ffa24 |
(int) NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS,
|
|
Packit Service |
5ffa24 |
reader->ignore_auto_dns,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_DHCP_TIMEOUT,
|
|
Packit Service |
5ffa24 |
reader->dhcp_timeout,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
setting = nm_setting_connection_new();
|
|
Packit Service |
5ffa24 |
nm_connection_add_setting(connection, setting);
|
|
Packit Service |
5ffa24 |
g_object_set(setting,
|
|
Packit Service |
5ffa24 |
NM_SETTING_CONNECTION_ID,
|
|
Packit Service |
5ffa24 |
id,
|
|
Packit Service |
5ffa24 |
NM_SETTING_CONNECTION_UUID,
|
|
Packit Service |
5ffa24 |
nm_utils_uuid_generate_a(),
|
|
Packit Service |
5ffa24 |
NM_SETTING_CONNECTION_INTERFACE_NAME,
|
|
Packit Service |
5ffa24 |
ifname,
|
|
Packit Service |
5ffa24 |
NM_SETTING_CONNECTION_TYPE,
|
|
Packit Service |
5ffa24 |
type_name,
|
|
Packit Service |
5ffa24 |
NM_SETTING_CONNECTION_MULTI_CONNECT,
|
|
Packit Service |
5ffa24 |
multi_connect,
|
|
Packit Service |
f8a693 |
NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES,
|
|
Packit Service |
f8a693 |
1,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (nm_streq0(type_name, NM_SETTING_INFINIBAND_SETTING_NAME)) {
|
|
Packit Service |
5ffa24 |
setting = nm_setting_infiniband_new();
|
|
Packit Service |
5ffa24 |
nm_connection_add_setting(connection, setting);
|
|
Packit Service |
5ffa24 |
g_object_set(setting, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (mac) {
|
|
Packit Service |
5ffa24 |
if (nm_streq0(type_name, NM_SETTING_INFINIBAND_SETTING_NAME)) {
|
|
Packit Service |
5ffa24 |
setting = (NMSetting *) nm_connection_get_setting_infiniband(connection);
|
|
Packit Service |
5ffa24 |
g_object_set(setting, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL);
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
setting = nm_setting_wired_new();
|
|
Packit Service |
5ffa24 |
nm_connection_add_setting(connection, setting);
|
|
Packit Service |
5ffa24 |
g_object_set(setting, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
return connection;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static NMConnection *
|
|
Packit Service |
5ffa24 |
reader_get_default_connection(Reader *reader)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMConnection *con;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!reader->default_connection) {
|
|
Packit Service |
5ffa24 |
con = reader_create_connection(reader,
|
|
Packit Service |
5ffa24 |
"default_connection",
|
|
Packit Service |
5ffa24 |
"Wired Connection",
|
|
Packit Service |
5ffa24 |
NULL,
|
|
Packit Service |
5ffa24 |
NULL,
|
|
Packit Service |
5ffa24 |
NM_SETTING_WIRED_SETTING_NAME,
|
|
Packit Service |
5ffa24 |
NM_CONNECTION_MULTI_CONNECT_MULTIPLE);
|
|
Packit Service |
5ffa24 |
nm_connection_add_setting(con, nm_setting_wired_new());
|
|
Packit Service |
5ffa24 |
reader->default_connection = con;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
return reader->default_connection;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static NMConnection *
|
|
Packit Service |
5ffa24 |
reader_get_connection(Reader * reader,
|
|
Packit Service |
5ffa24 |
const char *iface_spec,
|
|
Packit Service |
5ffa24 |
const char *type_name,
|
|
Packit Service |
5ffa24 |
gboolean create_if_missing)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMConnection *connection = NULL;
|
|
Packit Service |
5ffa24 |
NMSetting * setting;
|
|
Packit Service |
5ffa24 |
const char * ifname = NULL;
|
|
Packit Service |
5ffa24 |
gs_free char *mac = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (iface_spec) {
|
|
Packit Service |
5ffa24 |
if (nm_utils_is_valid_iface_name(iface_spec, NULL))
|
|
Packit Service |
5ffa24 |
ifname = iface_spec;
|
|
Packit Service |
5ffa24 |
else {
|
|
Packit Service |
5ffa24 |
mac = nm_utils_hwaddr_canonical(iface_spec, -1);
|
|
Packit Service |
5ffa24 |
if (!mac)
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "invalid interface '%s'", iface_spec);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!ifname && !mac) {
|
|
Packit Service |
5ffa24 |
NMConnection * candidate;
|
|
Packit Service |
5ffa24 |
NMSettingConnection *s_con;
|
|
Packit Service |
5ffa24 |
guint i;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/*
|
|
Packit Service |
5ffa24 |
* If ifname was not given, we'll match the connection by type.
|
|
Packit Service |
5ffa24 |
* If the type was not given either, then we're happy with any connection but slaves.
|
|
Packit Service |
5ffa24 |
* This is so that things like "bond=bond0:eth1,eth2 nameserver=1.3.3.7 end up
|
|
Packit Service |
5ffa24 |
* slapping the nameserver to the most reasonable connection (bond0).
|
|
Packit Service |
5ffa24 |
*/
|
|
Packit Service |
5ffa24 |
for (i = 0; i < reader->array->len; i++) {
|
|
Packit Service |
5ffa24 |
candidate = g_hash_table_lookup(reader->hash, reader->array->pdata[i]);
|
|
Packit Service |
5ffa24 |
s_con = nm_connection_get_setting_connection(candidate);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (type_name == NULL && nm_setting_connection_get_master(s_con) == NULL) {
|
|
Packit Service |
5ffa24 |
connection = candidate;
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (type_name != NULL
|
|
Packit Service |
5ffa24 |
&& nm_streq(nm_setting_connection_get_connection_type(s_con), type_name)) {
|
|
Packit Service |
5ffa24 |
connection = candidate;
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
} else
|
|
Packit Service |
5ffa24 |
connection = g_hash_table_lookup(reader->hash, (gpointer) ifname ?: mac);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!connection) {
|
|
Packit Service |
5ffa24 |
if (!create_if_missing)
|
|
Packit Service |
5ffa24 |
return NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!type_name) {
|
|
Packit Service |
5ffa24 |
if (NM_STR_HAS_PREFIX(ifname, "ib")
|
|
Packit Service |
5ffa24 |
|| (mac && nm_utils_hwaddr_valid(mac, INFINIBAND_ALEN)))
|
|
Packit Service |
5ffa24 |
type_name = NM_SETTING_INFINIBAND_SETTING_NAME;
|
|
Packit Service |
5ffa24 |
else
|
|
Packit Service |
5ffa24 |
type_name = NM_SETTING_WIRED_SETTING_NAME;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
connection = reader_create_connection(reader,
|
|
Packit Service |
5ffa24 |
ifname ?: mac,
|
|
Packit Service |
5ffa24 |
ifname ?: (mac ?: "Wired Connection"),
|
|
Packit Service |
5ffa24 |
ifname,
|
|
Packit Service |
5ffa24 |
mac,
|
|
Packit Service |
5ffa24 |
type_name,
|
|
Packit Service |
5ffa24 |
NM_CONNECTION_MULTI_CONNECT_SINGLE);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
setting = (NMSetting *) nm_connection_get_setting_connection(connection);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (type_name) {
|
|
Packit Service |
5ffa24 |
g_object_set(setting, NM_SETTING_CONNECTION_TYPE, type_name, NULL);
|
|
Packit Service |
5ffa24 |
if (!nm_connection_get_setting_by_name(connection, type_name)) {
|
|
Packit Service |
5ffa24 |
setting = g_object_new(nm_setting_lookup_type(type_name), NULL);
|
|
Packit Service |
5ffa24 |
nm_connection_add_setting(connection, setting);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
return connection;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static char *
|
|
Packit Service |
5ffa24 |
get_word(char **argument, const char separator)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
char *word;
|
|
Packit Service |
5ffa24 |
int nest = 0;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (*argument == NULL)
|
|
Packit Service |
5ffa24 |
return NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (**argument == '[') {
|
|
Packit Service |
5ffa24 |
nest++;
|
|
Packit Service |
5ffa24 |
(*argument)++;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
word = *argument;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
while (**argument != '\0') {
|
|
Packit Service |
5ffa24 |
if (nest && **argument == ']') {
|
|
Packit Service |
5ffa24 |
**argument = '\0';
|
|
Packit Service |
5ffa24 |
(*argument)++;
|
|
Packit Service |
5ffa24 |
nest--;
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (nest == 0 && **argument == separator) {
|
|
Packit Service |
5ffa24 |
**argument = '\0';
|
|
Packit Service |
5ffa24 |
(*argument)++;
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
(*argument)++;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
return *word ? word : NULL;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
connection_set(NMConnection *connection,
|
|
Packit Service |
5ffa24 |
const char * setting_name,
|
|
Packit Service |
5ffa24 |
const char * property,
|
|
Packit Service |
5ffa24 |
const char * value)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMSetting * setting;
|
|
Packit Service |
5ffa24 |
GType setting_type;
|
|
Packit Service |
5ffa24 |
nm_auto_unref_gtypeclass GObjectClass *object_class = NULL;
|
|
Packit Service |
5ffa24 |
GParamSpec * spec;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
setting_type = nm_setting_lookup_type(setting_name);
|
|
Packit Service |
5ffa24 |
object_class = g_type_class_ref(setting_type);
|
|
Packit Service |
5ffa24 |
spec = g_object_class_find_property(object_class, property);
|
|
Packit Service |
5ffa24 |
nm_assert(spec);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
setting = nm_connection_get_setting_by_name(connection, setting_name);
|
|
Packit Service |
5ffa24 |
if (!setting) {
|
|
Packit Service |
5ffa24 |
setting = g_object_new(setting_type, NULL);
|
|
Packit Service |
5ffa24 |
nm_connection_add_setting(connection, setting);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (G_IS_PARAM_SPEC_UINT(spec)) {
|
|
Packit Service |
5ffa24 |
guint v;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
v = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT, 0);
|
|
Packit Service |
5ffa24 |
if (errno || !nm_g_object_set_property_uint(G_OBJECT(setting), property, v, NULL)) {
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE,
|
|
Packit Service |
5ffa24 |
"Could not set property '%s.%s' to '%s'",
|
|
Packit Service |
5ffa24 |
setting_name,
|
|
Packit Service |
5ffa24 |
property,
|
|
Packit Service |
5ffa24 |
value);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
} else if (G_IS_PARAM_SPEC_STRING(spec))
|
|
Packit Service |
5ffa24 |
g_object_set(setting, property, value, NULL);
|
|
Packit Service |
5ffa24 |
else
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Don't know how to set '%s' of %s", property, setting_name);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
reader_read_all_connections_from_fw(Reader *reader, const char *sysfs_dir)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
gs_unref_hashtable GHashTable *ibft = NULL;
|
|
Packit Service |
5ffa24 |
NMConnection * dt_connection;
|
|
Packit Service |
5ffa24 |
const char * mac;
|
|
Packit Service |
5ffa24 |
GHashTable * nic;
|
|
Packit Service |
5ffa24 |
const char * index;
|
|
Packit Service |
5ffa24 |
GError * error = NULL;
|
|
Packit Service |
5ffa24 |
guint i, length;
|
|
Packit Service |
5ffa24 |
gs_free const char ** keys = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
ibft = nmi_ibft_read(sysfs_dir);
|
|
Packit Service |
5ffa24 |
keys = nm_utils_strdict_get_keys(ibft, TRUE, &length);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
for (i = 0; i < length; i++) {
|
|
Packit Service |
5ffa24 |
gs_unref_object NMConnection *connection = NULL;
|
|
Packit Service |
5ffa24 |
gs_free char * name = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
mac = keys[i];
|
|
Packit Service |
5ffa24 |
nic = g_hash_table_lookup(ibft, mac);
|
|
Packit Service |
5ffa24 |
connection = nm_simple_connection_new();
|
|
Packit Service |
5ffa24 |
index = g_hash_table_lookup(nic, "index");
|
|
Packit Service |
5ffa24 |
if (!index) {
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Ignoring an iBFT entry without an index");
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!nmi_ibft_update_connection_from_nic(connection, nic, &error)) {
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Unable to merge iBFT configuration: %s", error->message);
|
|
Packit Service |
5ffa24 |
g_error_free(error);
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
name = g_strdup_printf("ibft%s", index);
|
|
Packit Service |
5ffa24 |
reader_add_connection(reader, name, g_steal_pointer(&connection));
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
dt_connection = nmi_dt_reader_parse(sysfs_dir);
|
|
Packit Service |
5ffa24 |
if (dt_connection)
|
|
Packit Service |
5ffa24 |
reader_add_connection(reader, "ofw", dt_connection);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
reader_parse_ip(Reader *reader, const char *sysfs_dir, char *argument)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMConnection * connection;
|
|
Packit Service |
5ffa24 |
NMSettingIPConfig *s_ip4 = NULL, *s_ip6 = NULL;
|
|
Packit Service |
5ffa24 |
gs_unref_hashtable GHashTable *ibft = NULL;
|
|
Packit Service |
5ffa24 |
const char * tmp;
|
|
Packit Service |
5ffa24 |
const char * tmp2;
|
|
Packit Service |
5ffa24 |
const char * kind = NULL;
|
|
Packit Service |
5ffa24 |
const char * client_ip = NULL;
|
|
Packit Service |
5ffa24 |
const char * peer = NULL;
|
|
Packit Service |
5ffa24 |
const char * gateway_ip = NULL;
|
|
Packit Service |
5ffa24 |
const char * netmask = NULL;
|
|
Packit Service |
5ffa24 |
const char * client_hostname = NULL;
|
|
Packit Service |
5ffa24 |
const char * iface_spec = NULL;
|
|
Packit Service |
5ffa24 |
const char * mtu = NULL;
|
|
Packit Service |
5ffa24 |
const char * macaddr = NULL;
|
|
Packit Service |
5ffa24 |
int client_ip_family = AF_UNSPEC;
|
|
Packit Service |
5ffa24 |
int client_ip_prefix = -1;
|
|
Packit Service |
5ffa24 |
const char * dns[2] = {
|
|
Packit Service |
5ffa24 |
0,
|
|
Packit Service |
5ffa24 |
};
|
|
Packit Service |
5ffa24 |
int dns_addr_family[2] = {
|
|
Packit Service |
5ffa24 |
0,
|
|
Packit Service |
5ffa24 |
};
|
|
Packit Service |
5ffa24 |
int i;
|
|
Packit Service |
5ffa24 |
GError *error = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!*argument)
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
tmp = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
if (!*argument) {
|
|
Packit Service |
5ffa24 |
/* ip={dhcp|on|any|dhcp6|auto6|link6|ibft} */
|
|
Packit Service |
5ffa24 |
kind = tmp;
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
tmp2 = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
if (NM_IN_STRSET(tmp2,
|
|
Packit Service |
5ffa24 |
"none",
|
|
Packit Service |
5ffa24 |
"off",
|
|
Packit Service |
5ffa24 |
"dhcp",
|
|
Packit Service |
5ffa24 |
"on"
|
|
Packit Service |
5ffa24 |
"any",
|
|
Packit Service |
5ffa24 |
"dhcp6",
|
|
Packit Service |
5ffa24 |
"auto",
|
|
Packit Service |
5ffa24 |
"auto6",
|
|
Packit Service |
5ffa24 |
"link6",
|
|
Packit Service |
5ffa24 |
"ibft")) {
|
|
Packit Service |
5ffa24 |
/* <ifname>:{none|off|dhcp|on|any|dhcp6|auto|auto6|link6|ibft} */
|
|
Packit Service |
5ffa24 |
iface_spec = tmp;
|
|
Packit Service |
5ffa24 |
kind = tmp2;
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
/* <client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<kind> */
|
|
Packit Service |
5ffa24 |
client_ip = tmp;
|
|
Packit Service |
5ffa24 |
if (client_ip) {
|
|
Packit Service |
5ffa24 |
client_ip_family = get_ip_address_family(client_ip, TRUE);
|
|
Packit Service |
5ffa24 |
if (client_ip_family == AF_UNSPEC) {
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Invalid IP address '%s'.", client_ip);
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
peer = tmp2;
|
|
Packit Service |
5ffa24 |
gateway_ip = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
netmask = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
client_hostname = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
iface_spec = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
kind = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (client_hostname && !nm_sd_hostname_is_valid(client_hostname, FALSE))
|
|
Packit Service |
5ffa24 |
client_hostname = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (client_hostname) {
|
|
Packit Service |
5ffa24 |
g_free(reader->hostname);
|
|
Packit Service |
5ffa24 |
reader->hostname = g_strdup(client_hostname);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
tmp = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
dns_addr_family[0] = get_ip_address_family(tmp, FALSE);
|
|
Packit Service |
5ffa24 |
if (dns_addr_family[0] != AF_UNSPEC) {
|
|
Packit Service |
5ffa24 |
dns[0] = tmp;
|
|
Packit Service |
5ffa24 |
dns[1] = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
dns_addr_family[1] = get_ip_address_family(dns[1], FALSE);
|
|
Packit Service |
5ffa24 |
if (*argument)
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument);
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
mtu = tmp;
|
|
Packit Service |
5ffa24 |
macaddr = argument;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (iface_spec == NULL && NM_IN_STRSET(kind, "fw", "ibft")) {
|
|
Packit Service |
5ffa24 |
reader_read_all_connections_from_fw(reader, sysfs_dir);
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* Parsing done, construct the NMConnection. */
|
|
Packit Service |
5ffa24 |
if (iface_spec)
|
|
Packit Service |
5ffa24 |
connection = reader_get_connection(reader, iface_spec, NULL, TRUE);
|
|
Packit Service |
5ffa24 |
else
|
|
Packit Service |
5ffa24 |
connection = reader_get_default_connection(reader);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_hash_table_add(reader->explicit_ip_connections, g_object_ref(connection));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
s_ip4 = nm_connection_get_setting_ip4_config(connection);
|
|
Packit Service |
5ffa24 |
s_ip6 = nm_connection_get_setting_ip6_config(connection);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (netmask && *netmask) {
|
|
Packit Service |
5ffa24 |
gboolean is_ipv4 = client_ip_family == AF_INET;
|
|
Packit Service |
5ffa24 |
NMIPAddr addr;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (is_ipv4 && nm_utils_parse_inaddr_bin(AF_INET, netmask, NULL, &addr))
|
|
Packit Service |
5ffa24 |
client_ip_prefix = nm_utils_ip4_netmask_to_prefix(addr.addr4);
|
|
Packit Service |
5ffa24 |
else
|
|
Packit Service |
5ffa24 |
client_ip_prefix = _nm_utils_ascii_str_to_int64(netmask, 10, 0, is_ipv4 ? 32 : 128, -1);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (client_ip_prefix == -1)
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Invalid IP mask: %s", netmask);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* Static IP configuration might be present. */
|
|
Packit Service |
5ffa24 |
if (client_ip && *client_ip) {
|
|
Packit Service |
5ffa24 |
NMIPAddress *address = NULL;
|
|
Packit Service |
5ffa24 |
NMIPAddr addr;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (nm_utils_parse_inaddr_prefix_bin(client_ip_family,
|
|
Packit Service |
5ffa24 |
client_ip,
|
|
Packit Service |
5ffa24 |
NULL,
|
|
Packit Service |
5ffa24 |
&addr,
|
|
Packit Service |
5ffa24 |
client_ip_prefix == -1 ? &client_ip_prefix : NULL)) {
|
|
Packit Service |
5ffa24 |
if (client_ip_prefix == -1) {
|
|
Packit Service |
5ffa24 |
switch (client_ip_family) {
|
|
Packit Service |
5ffa24 |
case AF_INET:
|
|
Packit Service |
5ffa24 |
client_ip_prefix = _nm_utils_ip4_get_default_prefix(addr.addr4);
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
case AF_INET6:
|
|
Packit Service |
5ffa24 |
client_ip_prefix = 64;
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
address = nm_ip_address_new_binary(client_ip_family,
|
|
Packit Service |
5ffa24 |
&addr.addr_ptr,
|
|
Packit Service |
5ffa24 |
client_ip_prefix,
|
|
Packit Service |
5ffa24 |
&error);
|
|
Packit Service |
5ffa24 |
if (!address) {
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Invalid address '%s': %s", client_ip, error->message);
|
|
Packit Service |
5ffa24 |
g_clear_error(&error);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
} else
|
|
Packit Service |
5ffa24 |
nm_assert_not_reached();
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (address) {
|
|
Packit Service |
5ffa24 |
switch (client_ip_family) {
|
|
Packit Service |
5ffa24 |
case AF_INET:
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip4,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_MAY_FAIL,
|
|
Packit Service |
5ffa24 |
FALSE,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
nm_setting_ip_config_add_address(s_ip4, address);
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
case AF_INET6:
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip6,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_MAY_FAIL,
|
|
Packit Service |
5ffa24 |
FALSE,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
nm_setting_ip_config_add_address(s_ip6, address);
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
default:
|
|
Packit Service |
5ffa24 |
nm_assert_not_reached();
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
nm_ip_address_unref(address);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* Dynamic IP configuration configured explicitly. */
|
|
Packit Service |
5ffa24 |
if (NM_IN_STRSET(kind, "none", "off")) {
|
|
Packit Service |
5ffa24 |
if (nm_setting_ip_config_get_num_addresses(s_ip6) == 0) {
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip6,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
if (nm_setting_ip_config_get_num_addresses(s_ip4) == 0) {
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip4,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
} else if (nm_streq0(kind, "dhcp")) {
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip4,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP4_CONFIG_METHOD_AUTO,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_MAY_FAIL,
|
|
Packit Service |
5ffa24 |
FALSE,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
if (nm_setting_ip_config_get_num_addresses(s_ip6) == 0) {
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip6,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP6_CONFIG_METHOD_AUTO,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
} else if (NM_IN_STRSET(kind, "auto6", "dhcp6")) {
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip4, NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE, NULL);
|
|
Packit Service |
5ffa24 |
if (nm_setting_ip_config_get_num_addresses(s_ip4) == 0) {
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip4,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
} else if (nm_streq0(kind, "link6")) {
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip6,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_MAY_FAIL,
|
|
Packit Service |
5ffa24 |
FALSE,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
if (nm_setting_ip_config_get_num_addresses(s_ip4) == 0) {
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip4,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
} else if (nm_streq0(kind, "ibft")) {
|
|
Packit Service |
5ffa24 |
NMSettingWired *s_wired;
|
|
Packit Service |
5ffa24 |
const char * mac = NULL;
|
|
Packit Service |
5ffa24 |
const char * ifname;
|
|
Packit Service |
5ffa24 |
gs_free char * mac_free = NULL;
|
|
Packit Service |
5ffa24 |
gs_free char * address_path = NULL;
|
|
Packit Service |
5ffa24 |
GHashTable * nic = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if ((s_wired = nm_connection_get_setting_wired(connection))
|
|
Packit Service |
5ffa24 |
&& (mac = nm_setting_wired_get_mac_address(s_wired))) {
|
|
Packit Service |
5ffa24 |
/* got mac from the connection */
|
|
Packit Service |
5ffa24 |
} else if ((ifname = nm_connection_get_interface_name(connection))) {
|
|
Packit Service |
5ffa24 |
/* read it from sysfs */
|
|
Packit Service |
5ffa24 |
address_path = g_build_filename(sysfs_dir, "class", "net", ifname, "address", NULL);
|
|
Packit Service |
5ffa24 |
if (g_file_get_contents(address_path, &mac_free, NULL, &error)) {
|
|
Packit Service |
5ffa24 |
g_strchomp(mac_free);
|
|
Packit Service |
5ffa24 |
mac = mac_free;
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Can't get a MAC address for %s: %s", ifname, error->message);
|
|
Packit Service |
5ffa24 |
g_clear_error(&error);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (mac) {
|
|
Packit Service |
5ffa24 |
gs_free char *mac_up = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
mac_up = g_ascii_strup(mac, -1);
|
|
Packit Service |
5ffa24 |
ibft = nmi_ibft_read(sysfs_dir);
|
|
Packit Service |
5ffa24 |
nic = g_hash_table_lookup(ibft, mac_up);
|
|
Packit Service |
5ffa24 |
if (!nic)
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "No iBFT NIC for %s (%s)", iface_spec, mac_up);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (nic) {
|
|
Packit Service |
5ffa24 |
if (!nmi_ibft_update_connection_from_nic(connection, nic, &error)) {
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Unable to merge iBFT configuration: %s", error->message);
|
|
Packit Service |
5ffa24 |
g_clear_error(&error);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (peer && *peer)
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Ignoring peer: %s (not implemented)\n", peer);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (gateway_ip && *gateway_ip) {
|
|
Packit Service |
5ffa24 |
switch (get_ip_address_family(gateway_ip, FALSE)) {
|
|
Packit Service |
5ffa24 |
case AF_INET:
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway_ip, NULL);
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
case AF_INET6:
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, gateway_ip, NULL);
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
default:
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Invalid gateway: %s", gateway_ip);
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (client_hostname && *client_hostname) {
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, client_hostname, NULL);
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, client_hostname, NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
for (i = 0; i < 2; i++) {
|
|
Packit Service |
5ffa24 |
if (dns_addr_family[i] == AF_UNSPEC)
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
if (nm_utils_ipaddr_is_valid(dns_addr_family[i], dns[i])) {
|
|
Packit Service |
5ffa24 |
switch (dns_addr_family[i]) {
|
|
Packit Service |
5ffa24 |
case AF_INET:
|
|
Packit Service |
5ffa24 |
nm_setting_ip_config_add_dns(s_ip4, dns[i]);
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
case AF_INET6:
|
|
Packit Service |
5ffa24 |
nm_setting_ip_config_add_dns(s_ip6, dns[i]);
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
default:
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Unknown address family: %s", dns[i]);
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Invalid name server: %s", dns[i]);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (mtu && *mtu)
|
|
Packit Service |
5ffa24 |
connection_set(connection, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MTU, mtu);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (macaddr && *macaddr)
|
|
Packit Service |
5ffa24 |
connection_set(connection,
|
|
Packit Service |
5ffa24 |
NM_SETTING_WIRED_SETTING_NAME,
|
|
Packit Service |
5ffa24 |
NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
|
Packit Service |
5ffa24 |
macaddr);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
reader_parse_master(Reader *reader, char *argument, const char *type_name, const char *default_name)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMConnection * connection;
|
|
Packit Service |
5ffa24 |
NMSettingConnection *s_con;
|
|
Packit Service |
5ffa24 |
gs_free char * master_to_free = NULL;
|
|
Packit Service |
5ffa24 |
const char * master;
|
|
Packit Service |
5ffa24 |
char * slaves;
|
|
Packit Service |
5ffa24 |
const char * slave;
|
|
Packit Service |
5ffa24 |
char * opts;
|
|
Packit Service |
5ffa24 |
const char * mtu = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
master = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
if (!master)
|
|
Packit Service |
5ffa24 |
master = master_to_free = g_strdup_printf("%s0", default_name ?: type_name);
|
|
Packit Service |
5ffa24 |
slaves = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
connection = reader_get_connection(reader, master, type_name, TRUE);
|
|
Packit Service |
5ffa24 |
s_con = nm_connection_get_setting_connection(connection);
|
|
Packit Service |
5ffa24 |
master = nm_setting_connection_get_uuid(s_con);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (nm_streq(type_name, NM_SETTING_BRIDGE_SETTING_NAME)) {
|
|
Packit Service |
5ffa24 |
NMSettingBridge *s_bridge = nm_connection_get_setting_bridge(connection);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* Avoid the forwarding delay */
|
|
Packit Service |
5ffa24 |
g_object_set(s_bridge, NM_SETTING_BRIDGE_STP, FALSE, NULL);
|
|
Packit Service |
5ffa24 |
} else if (nm_streq(type_name, NM_SETTING_BOND_SETTING_NAME)) {
|
|
Packit Service |
5ffa24 |
NMSettingBond *s_bond = nm_connection_get_setting_bond(connection);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
opts = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
while (opts && *opts) {
|
|
Packit Service |
5ffa24 |
gs_free_error GError *error = NULL;
|
|
Packit Service |
5ffa24 |
char * opt;
|
|
Packit Service |
5ffa24 |
const char * opt_name;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
opt = get_word(&opts, ',');
|
|
Packit Service |
5ffa24 |
opt_name = get_word(&opt, '=');
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!_nm_setting_bond_validate_option(opt_name, opt, &error)) {
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE,
|
|
Packit Service |
5ffa24 |
"Ignoring invalid bond option: %s%s%s = %s%s%s: %s",
|
|
Packit Service |
5ffa24 |
NM_PRINT_FMT_QUOTE_STRING(opt_name),
|
|
Packit Service |
5ffa24 |
NM_PRINT_FMT_QUOTE_STRING(opt),
|
|
Packit Service |
5ffa24 |
error->message);
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
nm_setting_bond_add_option(s_bond, opt_name, opt);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
mtu = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
do {
|
|
Packit Service |
5ffa24 |
slave = get_word(&slaves, ',');
|
|
Packit Service |
5ffa24 |
if (slave == NULL)
|
|
Packit Service |
5ffa24 |
slave = "eth0";
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
connection = reader_get_connection(reader, slave, NULL, TRUE);
|
|
Packit Service |
5ffa24 |
s_con = nm_connection_get_setting_connection(connection);
|
|
Packit Service |
5ffa24 |
g_object_set(s_con,
|
|
Packit Service |
5ffa24 |
NM_SETTING_CONNECTION_SLAVE_TYPE,
|
|
Packit Service |
5ffa24 |
type_name,
|
|
Packit Service |
5ffa24 |
NM_SETTING_CONNECTION_MASTER,
|
|
Packit Service |
5ffa24 |
master,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
42f71b |
if (mtu)
|
|
Packit Service |
42f71b |
connection_set(connection, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MTU, mtu);
|
|
Packit Service |
5ffa24 |
} while (slaves && *slaves != '\0');
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (argument && *argument)
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
reader_add_routes(Reader *reader, GPtrArray *array)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
guint i;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
for (i = 0; i < array->len; i++) {
|
|
Packit Service |
5ffa24 |
NMConnection * connection = NULL;
|
|
Packit Service |
5ffa24 |
const char * net;
|
|
Packit Service |
5ffa24 |
const char * gateway;
|
|
Packit Service |
5ffa24 |
const char * interface;
|
|
Packit Service |
5ffa24 |
int family = AF_UNSPEC;
|
|
Packit Service |
5ffa24 |
NMIPAddr net_addr = {};
|
|
Packit Service |
5ffa24 |
NMIPAddr gateway_addr = {};
|
|
Packit Service |
5ffa24 |
int net_prefix = -1;
|
|
Packit Service |
5ffa24 |
NMIPRoute * route;
|
|
Packit Service |
5ffa24 |
NMSettingIPConfig *s_ip;
|
|
Packit Service |
5ffa24 |
char * argument;
|
|
Packit Service |
5ffa24 |
gs_free_error GError *error = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
argument = array->pdata[i];
|
|
Packit Service |
5ffa24 |
net = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
gateway = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
interface = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (interface)
|
|
Packit Service |
5ffa24 |
connection = reader_get_connection(reader, interface, NULL, TRUE);
|
|
Packit Service |
5ffa24 |
if (!connection)
|
|
Packit Service |
5ffa24 |
connection = reader->bootdev_connection;
|
|
Packit Service |
5ffa24 |
if (!connection)
|
|
Packit Service |
5ffa24 |
connection = reader_get_connection(reader, interface, NULL, FALSE);
|
|
Packit Service |
5ffa24 |
if (!connection)
|
|
Packit Service |
5ffa24 |
connection = reader_get_default_connection(reader);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (net && *net) {
|
|
Packit Service |
5ffa24 |
if (!nm_utils_parse_inaddr_prefix_bin(family, net, &family, &net_addr, &net_prefix)) {
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Unrecognized address: %s", net);
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (gateway && *gateway) {
|
|
Packit Service |
5ffa24 |
if (!nm_utils_parse_inaddr_bin(family, gateway, &family, &gateway_addr)) {
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Unrecognized address: %s", gateway);
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
switch (family) {
|
|
Packit Service |
5ffa24 |
case AF_INET:
|
|
Packit Service |
5ffa24 |
s_ip = nm_connection_get_setting_ip4_config(connection);
|
|
Packit Service |
5ffa24 |
if (net_prefix == -1)
|
|
Packit Service |
5ffa24 |
net_prefix = 32;
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
case AF_INET6:
|
|
Packit Service |
5ffa24 |
s_ip = nm_connection_get_setting_ip6_config(connection);
|
|
Packit Service |
5ffa24 |
if (net_prefix == -1)
|
|
Packit Service |
5ffa24 |
net_prefix = 128;
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
default:
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Unknown address family: %s", net);
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
route = nm_ip_route_new_binary(family,
|
|
Packit Service |
5ffa24 |
&net_addr.addr_ptr,
|
|
Packit Service |
5ffa24 |
net_prefix,
|
|
Packit Service |
5ffa24 |
&gateway_addr.addr_ptr,
|
|
Packit Service |
5ffa24 |
-1,
|
|
Packit Service |
5ffa24 |
&error);
|
|
Packit Service |
5ffa24 |
if (!route) {
|
|
Packit Service |
5ffa24 |
g_warning("Invalid route '%s via %s': %s\n", net, gateway, error->message);
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_setting_ip_config_add_route(s_ip, route);
|
|
Packit Service |
5ffa24 |
nm_ip_route_unref(route);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
reader_parse_vlan(Reader *reader, char *argument)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMConnection * connection;
|
|
Packit Service |
5ffa24 |
NMSettingVlan *s_vlan;
|
|
Packit Service |
5ffa24 |
const char * vlan;
|
|
Packit Service |
5ffa24 |
const char * phy;
|
|
Packit Service |
5ffa24 |
const char * vlanid;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
vlan = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
phy = get_word(&argument, ':');
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
for (vlanid = vlan + strlen(vlan); vlanid > vlan; vlanid--) {
|
|
Packit Service |
5ffa24 |
if (!g_ascii_isdigit(*(vlanid - 1)))
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
connection = reader_get_connection(reader, vlan, NM_SETTING_VLAN_SETTING_NAME, TRUE);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
s_vlan = nm_connection_get_setting_vlan(connection);
|
|
Packit Service |
5ffa24 |
g_object_set(s_vlan,
|
|
Packit Service |
5ffa24 |
NM_SETTING_VLAN_PARENT,
|
|
Packit Service |
5ffa24 |
phy,
|
|
Packit Service |
5ffa24 |
NM_SETTING_VLAN_ID,
|
|
Packit Service |
5ffa24 |
(guint) _nm_utils_ascii_str_to_int64(vlanid, 10, 0, G_MAXUINT, G_MAXUINT),
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (argument && *argument)
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!nm_strv_ptrarray_contains(reader->vlan_parents, phy))
|
|
Packit Service |
5ffa24 |
g_ptr_array_add(reader->vlan_parents, g_strdup(phy));
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
reader_parse_rd_znet(Reader *reader, char *argument, gboolean net_ifnames)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
const char * nettype;
|
|
Packit Service |
5ffa24 |
const char * subchannels[4] = {0, 0, 0, 0};
|
|
Packit Service |
5ffa24 |
const char * tmp;
|
|
Packit Service |
5ffa24 |
gs_free char * ifname = NULL;
|
|
Packit Service |
5ffa24 |
const char * prefix;
|
|
Packit Service |
5ffa24 |
NMConnection * connection;
|
|
Packit Service |
5ffa24 |
NMSettingWired *s_wired;
|
|
Packit Service |
5ffa24 |
static int count_ctc = 0;
|
|
Packit Service |
5ffa24 |
static int count_eth = 0;
|
|
Packit Service |
5ffa24 |
int index;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nettype = get_word(&argument, ',');
|
|
Packit Service |
5ffa24 |
subchannels[0] = get_word(&argument, ',');
|
|
Packit Service |
5ffa24 |
subchannels[1] = get_word(&argument, ',');
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (nm_streq0(nettype, "ctc")) {
|
|
Packit Service |
5ffa24 |
if (net_ifnames == TRUE) {
|
|
Packit Service |
5ffa24 |
prefix = "sl";
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
prefix = "ctc";
|
|
Packit Service |
5ffa24 |
index = count_ctc++;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
subchannels[2] = get_word(&argument, ',');
|
|
Packit Service |
5ffa24 |
if (net_ifnames == TRUE) {
|
|
Packit Service |
5ffa24 |
prefix = "en";
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
prefix = "eth";
|
|
Packit Service |
5ffa24 |
index = count_eth++;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (net_ifnames == TRUE) {
|
|
Packit Service |
5ffa24 |
const char *bus_id;
|
|
Packit Service |
5ffa24 |
size_t bus_id_len;
|
|
Packit Service |
5ffa24 |
size_t bus_id_start;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* The following logic is taken from names_ccw() in systemd/src/udev/udev-builtin-net_id.c */
|
|
Packit Service |
5ffa24 |
bus_id = subchannels[0];
|
|
Packit Service |
5ffa24 |
bus_id_len = strlen(bus_id);
|
|
Packit Service |
5ffa24 |
bus_id_start = strspn(bus_id, ".0");
|
|
Packit Service |
5ffa24 |
bus_id += bus_id_start < bus_id_len ? bus_id_start : bus_id_len - 1;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
ifname = g_strdup_printf("%sc%s", prefix, bus_id);
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
ifname = g_strdup_printf("%s%d", prefix, index);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
connection = reader_get_connection(reader, ifname, NM_SETTING_WIRED_SETTING_NAME, FALSE);
|
|
Packit Service |
5ffa24 |
if (!connection)
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
s_wired = nm_connection_get_setting_wired(connection);
|
|
Packit Service |
5ffa24 |
g_object_set(s_wired,
|
|
Packit Service |
5ffa24 |
NM_SETTING_WIRED_S390_NETTYPE,
|
|
Packit Service |
5ffa24 |
nettype,
|
|
Packit Service |
5ffa24 |
NM_SETTING_WIRED_S390_SUBCHANNELS,
|
|
Packit Service |
5ffa24 |
&subchannels,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
while ((tmp = get_word(&argument, ',')) != NULL) {
|
|
Packit Service |
5ffa24 |
char *val;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
val = strchr(tmp, '=');
|
|
Packit Service |
5ffa24 |
if (val) {
|
|
Packit Service |
5ffa24 |
gs_free char *key = NULL;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
key = g_strndup(tmp, val - tmp);
|
|
Packit Service |
5ffa24 |
val[0] = '\0';
|
|
Packit Service |
5ffa24 |
val++;
|
|
Packit Service |
5ffa24 |
nm_setting_wired_add_s390_option(s_wired, key, val);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
_normalize_conn(gpointer key, gpointer value, gpointer user_data)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMConnection *connection = value;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_connection_normalize(connection, NULL, NULL, NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
reader_add_nameservers(Reader *reader, GPtrArray *nameservers)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMConnection * connection;
|
|
Packit Service |
5ffa24 |
NMSettingIPConfig *s_ip;
|
|
Packit Service |
5ffa24 |
GHashTableIter iter;
|
|
Packit Service |
5ffa24 |
int addr_family;
|
|
Packit Service |
5ffa24 |
const char * ns;
|
|
Packit Service |
5ffa24 |
guint i;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
for (i = 0; i < nameservers->len; i++) {
|
|
Packit Service |
5ffa24 |
ns = nameservers->pdata[i];
|
|
Packit Service |
5ffa24 |
addr_family = get_ip_address_family(ns, FALSE);
|
|
Packit Service |
5ffa24 |
if (addr_family == AF_UNSPEC) {
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Unknown address family: %s", ns);
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_hash_table_iter_init(&iter, reader->hash);
|
|
Packit Service |
5ffa24 |
while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &connection)) {
|
|
Packit Service |
5ffa24 |
switch (addr_family) {
|
|
Packit Service |
5ffa24 |
case AF_INET:
|
|
Packit Service |
5ffa24 |
s_ip = nm_connection_get_setting_ip4_config(connection);
|
|
Packit Service |
5ffa24 |
if (!NM_IN_STRSET(nm_setting_ip_config_get_method(s_ip),
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP4_CONFIG_METHOD_AUTO,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP4_CONFIG_METHOD_MANUAL))
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
case AF_INET6:
|
|
Packit Service |
5ffa24 |
s_ip = nm_connection_get_setting_ip6_config(connection);
|
|
Packit Service |
5ffa24 |
if (!NM_IN_STRSET(nm_setting_ip_config_get_method(s_ip),
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP6_CONFIG_METHOD_AUTO,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP6_CONFIG_METHOD_DHCP,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP6_CONFIG_METHOD_MANUAL))
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
break;
|
|
Packit Service |
5ffa24 |
default:
|
|
Packit Service |
5ffa24 |
nm_assert_not_reached();
|
|
Packit Service |
5ffa24 |
continue;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
nm_setting_ip_config_add_dns(s_ip, ns);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
connection_set_needed(NMConnection *connection)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
NMSettingConnection *s_con;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
s_con = nm_connection_get_setting_connection(connection);
|
|
Packit Service |
5ffa24 |
if (!nm_streq0(nm_setting_connection_get_connection_type(s_con), NM_SETTING_WIRED_SETTING_NAME))
|
|
Packit Service |
5ffa24 |
return;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_object_set(s_con,
|
|
Packit Service |
5ffa24 |
NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT,
|
|
Packit Service |
5ffa24 |
(int) NMI_WAIT_DEVICE_TIMEOUT_MS,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
static void
|
|
Packit Service |
5ffa24 |
connection_set_needed_cb(gpointer key, gpointer value, gpointer user_data)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
connection_set_needed(value);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
GHashTable *
|
|
Packit Service |
5ffa24 |
nmi_cmdline_reader_parse(const char * sysfs_dir,
|
|
Packit Service |
5ffa24 |
const char *const *argv,
|
|
Packit Service |
5ffa24 |
char ** hostname,
|
|
Packit Service |
5ffa24 |
gint64 * carrier_timeout_sec)
|
|
Packit Service |
5ffa24 |
{
|
|
Packit Service |
5ffa24 |
Reader * reader;
|
|
Packit Service |
5ffa24 |
const char * tag;
|
|
Packit Service |
5ffa24 |
gboolean ignore_bootif = FALSE;
|
|
Packit Service |
5ffa24 |
gboolean neednet = FALSE;
|
|
Packit Service |
5ffa24 |
gs_free char * bootif_val = NULL;
|
|
Packit Service |
5ffa24 |
gs_free char * bootdev = NULL;
|
|
Packit Service |
5ffa24 |
gboolean net_ifnames = TRUE;
|
|
Packit Service |
5ffa24 |
gs_unref_ptrarray GPtrArray *nameservers = NULL;
|
|
Packit Service |
5ffa24 |
gs_unref_ptrarray GPtrArray *routes = NULL;
|
|
Packit Service |
5ffa24 |
gs_unref_ptrarray GPtrArray *znets = NULL;
|
|
Packit Service |
5ffa24 |
int i;
|
|
Packit Service |
f8a693 |
guint64 dhcp_timeout = 90;
|
|
Packit Service |
f8a693 |
guint64 dhcp_num_tries = 1;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
reader = reader_new();
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
for (i = 0; argv[i]; i++) {
|
|
Packit Service |
5ffa24 |
gs_free char *argument_clone = NULL;
|
|
Packit Service |
5ffa24 |
char * argument;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
argument_clone = g_strdup(argv[i]);
|
|
Packit Service |
5ffa24 |
argument = argument_clone;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
tag = get_word(&argument, '=');
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (nm_streq(tag, "net.ifnames"))
|
|
Packit Service |
5ffa24 |
net_ifnames = !nm_streq(argument, "0");
|
|
Packit Service |
5ffa24 |
else if (nm_streq(tag, "rd.peerdns"))
|
|
Packit Service |
5ffa24 |
reader->ignore_auto_dns = !_nm_utils_ascii_str_to_bool(argument, TRUE);
|
|
Packit Service |
5ffa24 |
else if (nm_streq(tag, "rd.net.timeout.dhcp")) {
|
|
Packit Service |
f8a693 |
if (nm_streq0(argument, "infinity")) {
|
|
Packit Service |
f8a693 |
dhcp_timeout = G_MAXINT32;
|
|
Packit Service |
f8a693 |
} else {
|
|
Packit Service |
f8a693 |
dhcp_timeout =
|
|
Packit Service |
f8a693 |
_nm_utils_ascii_str_to_int64(argument, 10, 1, G_MAXINT32, dhcp_timeout);
|
|
Packit Service |
f8a693 |
}
|
|
Packit Service |
f8a693 |
} else if (nm_streq(tag, "rd.net.dhcp.retry")) {
|
|
Packit Service |
f8a693 |
dhcp_num_tries =
|
|
Packit Service |
f8a693 |
_nm_utils_ascii_str_to_int64(argument, 10, 1, G_MAXINT32, dhcp_num_tries);
|
|
Packit Service |
5ffa24 |
} else if (nm_streq(tag, "rd.net.dhcp.vendor-class")) {
|
|
Packit Service |
5ffa24 |
if (nm_utils_validate_dhcp4_vendor_class_id(argument, NULL))
|
|
Packit Service |
5ffa24 |
nm_utils_strdup_reset(&reader->dhcp4_vci, argument);
|
|
Packit Service |
5ffa24 |
} else if (nm_streq(tag, "rd.net.timeout.carrier")) {
|
|
Packit Service |
5ffa24 |
reader->carrier_timeout_sec =
|
|
Packit Service |
5ffa24 |
_nm_utils_ascii_str_to_int64(argument, 10, 0, G_MAXINT32, 0);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
f8a693 |
reader->dhcp_timeout = NM_CLAMP(dhcp_timeout * dhcp_num_tries, 1, G_MAXINT32);
|
|
Packit Service |
f8a693 |
|
|
Packit Service |
5ffa24 |
for (i = 0; argv[i]; i++) {
|
|
Packit Service |
5ffa24 |
gs_free char *argument_clone = NULL;
|
|
Packit Service |
5ffa24 |
char * argument;
|
|
Packit Service |
5ffa24 |
char * word;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
argument_clone = g_strdup(argv[i]);
|
|
Packit Service |
5ffa24 |
argument = argument_clone;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
tag = get_word(&argument, '=');
|
|
Packit Service |
5ffa24 |
if (nm_streq(tag, "ip"))
|
|
Packit Service |
5ffa24 |
reader_parse_ip(reader, sysfs_dir, argument);
|
|
Packit Service |
5ffa24 |
else if (nm_streq(tag, "rd.route")) {
|
|
Packit Service |
5ffa24 |
if (!routes)
|
|
Packit Service |
5ffa24 |
routes = g_ptr_array_new_with_free_func(g_free);
|
|
Packit Service |
5ffa24 |
g_ptr_array_add(routes, g_strdup(argument));
|
|
Packit Service |
5ffa24 |
} else if (nm_streq(tag, "bridge"))
|
|
Packit Service |
5ffa24 |
reader_parse_master(reader, argument, NM_SETTING_BRIDGE_SETTING_NAME, "br");
|
|
Packit Service |
5ffa24 |
else if (nm_streq(tag, "bond"))
|
|
Packit Service |
5ffa24 |
reader_parse_master(reader, argument, NM_SETTING_BOND_SETTING_NAME, NULL);
|
|
Packit Service |
5ffa24 |
else if (nm_streq(tag, "team"))
|
|
Packit Service |
5ffa24 |
reader_parse_master(reader, argument, NM_SETTING_TEAM_SETTING_NAME, NULL);
|
|
Packit Service |
5ffa24 |
else if (nm_streq(tag, "vlan"))
|
|
Packit Service |
5ffa24 |
reader_parse_vlan(reader, argument);
|
|
Packit Service |
5ffa24 |
else if (nm_streq(tag, "bootdev")) {
|
|
Packit Service |
5ffa24 |
g_free(bootdev);
|
|
Packit Service |
5ffa24 |
bootdev = g_strdup(argument);
|
|
Packit Service |
5ffa24 |
} else if (nm_streq(tag, "nameserver")) {
|
|
Packit Service |
5ffa24 |
word = get_word(&argument, '\0');
|
|
Packit Service |
5ffa24 |
if (word) {
|
|
Packit Service |
5ffa24 |
if (!nameservers)
|
|
Packit Service |
5ffa24 |
nameservers = g_ptr_array_new_with_free_func(g_free);
|
|
Packit Service |
5ffa24 |
g_ptr_array_add(nameservers, g_strdup(word));
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
if (argument && *argument)
|
|
Packit Service |
5ffa24 |
_LOGW(LOGD_CORE, "Ignoring extra: '%s'.", argument);
|
|
Packit Service |
5ffa24 |
} else if (nm_streq(tag, "rd.iscsi.ibft") && _nm_utils_ascii_str_to_bool(argument, TRUE))
|
|
Packit Service |
5ffa24 |
reader_read_all_connections_from_fw(reader, sysfs_dir);
|
|
Packit Service |
5ffa24 |
else if (nm_streq(tag, "rd.bootif"))
|
|
Packit Service |
5ffa24 |
ignore_bootif = !_nm_utils_ascii_str_to_bool(argument, TRUE);
|
|
Packit Service |
5ffa24 |
else if (nm_streq(tag, "rd.neednet"))
|
|
Packit Service |
5ffa24 |
neednet = _nm_utils_ascii_str_to_bool(argument, TRUE);
|
|
Packit Service |
5ffa24 |
else if (nm_streq(tag, "rd.znet")) {
|
|
Packit Service |
5ffa24 |
if (!znets)
|
|
Packit Service |
5ffa24 |
znets = g_ptr_array_new_with_free_func(g_free);
|
|
Packit Service |
5ffa24 |
g_ptr_array_add(znets, g_strdup(argument));
|
|
Packit Service |
5ffa24 |
} else if (g_ascii_strcasecmp(tag, "BOOTIF") == 0) {
|
|
Packit Service |
5ffa24 |
nm_clear_g_free(&bootif_val);
|
|
Packit Service |
5ffa24 |
bootif_val = g_strdup(argument);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
for (i = 0; i < reader->vlan_parents->len; i++) {
|
|
Packit Service |
5ffa24 |
NMConnection * connection;
|
|
Packit Service |
5ffa24 |
NMSettingIPConfig *s_ip;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
/* Disable IP configuration for parent connections of VLANs,
|
|
Packit Service |
5ffa24 |
* unless those interfaces were explicitly configured otherwise. */
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
connection = reader_get_connection(reader, reader->vlan_parents->pdata[i], NULL, TRUE);
|
|
Packit Service |
5ffa24 |
if (!g_hash_table_contains(reader->explicit_ip_connections, connection)) {
|
|
Packit Service |
5ffa24 |
s_ip = nm_connection_get_setting_ip4_config(connection);
|
|
Packit Service |
5ffa24 |
if (s_ip) {
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
s_ip = nm_connection_get_setting_ip6_config(connection);
|
|
Packit Service |
5ffa24 |
if (s_ip) {
|
|
Packit Service |
5ffa24 |
g_object_set(s_ip,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP_CONFIG_METHOD,
|
|
Packit Service |
5ffa24 |
NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
|
|
Packit Service |
5ffa24 |
NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (ignore_bootif)
|
|
Packit Service |
5ffa24 |
nm_clear_g_free(&bootif_val);
|
|
Packit Service |
5ffa24 |
if (bootif_val) {
|
|
Packit Service |
5ffa24 |
NMConnection * connection;
|
|
Packit Service |
5ffa24 |
NMSettingWired *s_wired;
|
|
Packit Service |
5ffa24 |
const char * bootif = bootif_val;
|
|
Packit Service |
5ffa24 |
char prefix[4];
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (!nm_utils_hwaddr_valid(bootif, ETH_ALEN)) {
|
|
Packit Service |
5ffa24 |
strncpy(prefix, bootif, 3);
|
|
Packit Service |
5ffa24 |
prefix[3] = '\0';
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (NM_IN_STRSET(prefix, "01-", "01:", "00-", "00:")
|
|
Packit Service |
5ffa24 |
&& nm_utils_hwaddr_valid(&bootif[3], ETH_ALEN)) {
|
|
Packit Service |
5ffa24 |
/*
|
|
Packit Service |
5ffa24 |
* BOOTIF MAC address can be prefixed with a hardware type identifier.
|
|
Packit Service |
5ffa24 |
* "01" stays for "wired", "00" is also accepted as it means "undefined".
|
|
Packit Service |
5ffa24 |
* No others are known.
|
|
Packit Service |
5ffa24 |
*/
|
|
Packit Service |
5ffa24 |
bootif += 3;
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
connection = reader_get_connection(reader, NULL, NM_SETTING_WIRED_SETTING_NAME, FALSE);
|
|
Packit Service |
5ffa24 |
if (!connection)
|
|
Packit Service |
5ffa24 |
connection = reader_get_default_connection(reader);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
s_wired = nm_connection_get_setting_wired(connection);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (nm_connection_get_interface_name(connection)
|
|
Packit Service |
5ffa24 |
|| (nm_setting_wired_get_mac_address(s_wired)
|
|
Packit Service |
5ffa24 |
&& !nm_utils_hwaddr_matches(nm_setting_wired_get_mac_address(s_wired),
|
|
Packit Service |
5ffa24 |
-1,
|
|
Packit Service |
5ffa24 |
bootif,
|
|
Packit Service |
5ffa24 |
-1))) {
|
|
Packit Service |
5ffa24 |
connection = reader_create_connection(reader,
|
|
Packit Service |
5ffa24 |
"bootif_connection",
|
|
Packit Service |
5ffa24 |
"BOOTIF Connection",
|
|
Packit Service |
5ffa24 |
NULL,
|
|
Packit Service |
5ffa24 |
bootif,
|
|
Packit Service |
5ffa24 |
NM_SETTING_WIRED_SETTING_NAME,
|
|
Packit Service |
5ffa24 |
NM_CONNECTION_MULTI_CONNECT_SINGLE);
|
|
Packit Service |
5ffa24 |
} else {
|
|
Packit Service |
5ffa24 |
g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, bootif, NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (bootdev) {
|
|
Packit Service |
5ffa24 |
NMConnection *connection;
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
connection = reader_get_connection(reader, bootdev, NULL, TRUE);
|
|
Packit Service |
5ffa24 |
reader->bootdev_connection = connection;
|
|
Packit Service |
5ffa24 |
connection_set_needed(connection);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (neednet) {
|
|
Packit Service |
5ffa24 |
if (g_hash_table_size(reader->hash) == 0) {
|
|
Packit Service |
5ffa24 |
/* Make sure there's some connection. */
|
|
Packit Service |
5ffa24 |
reader_get_default_connection(reader);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_hash_table_foreach(reader->hash, connection_set_needed_cb, NULL);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (routes)
|
|
Packit Service |
5ffa24 |
reader_add_routes(reader, routes);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (nameservers)
|
|
Packit Service |
5ffa24 |
reader_add_nameservers(reader, nameservers);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
if (znets) {
|
|
Packit Service |
5ffa24 |
for (i = 0; i < znets->len; i++)
|
|
Packit Service |
5ffa24 |
reader_parse_rd_znet(reader, znets->pdata[i], net_ifnames);
|
|
Packit Service |
5ffa24 |
}
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
g_hash_table_foreach(reader->hash, _normalize_conn, NULL);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
NM_SET_OUT(hostname, g_steal_pointer(&reader->hostname));
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
NM_SET_OUT(carrier_timeout_sec, reader->carrier_timeout_sec);
|
|
Packit Service |
5ffa24 |
|
|
Packit Service |
5ffa24 |
return reader_destroy(reader, FALSE);
|
|
Packit Service |
5ffa24 |
}
|