2019-09-10 11:19:01 +02:00
|
|
|
// SPDX-License-Identifier: LGPL-2.1+
|
2019-09-25 13:13:40 +02:00
|
|
|
/*
|
2018-08-09 18:02:51 +02:00
|
|
|
* Copyright (C) 2018 Red Hat, Inc.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "nm-default.h"
|
|
|
|
|
|
2019-01-31 13:44:13 +01:00
|
|
|
#include "nm-core-internal.h"
|
2018-08-09 18:02:51 +02:00
|
|
|
#include "nm-initrd-generator.h"
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#define _NMLOG(level, domain, ...) \
|
|
|
|
|
nm_log ((level), (domain), NULL, NULL, \
|
|
|
|
|
"cmdline-reader: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__) \
|
|
|
|
|
_NM_UTILS_MACRO_REST (__VA_ARGS__))
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-07-02 10:03:00 +02:00
|
|
|
static gboolean
|
|
|
|
|
_connection_matches_type (gpointer key, gpointer value, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection = value;
|
|
|
|
|
const char *type_name = user_data;
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
|
|
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
|
|
|
|
if (type_name == NULL)
|
|
|
|
|
return nm_setting_connection_get_master (s_con) == NULL;
|
|
|
|
|
else
|
|
|
|
|
return strcmp (nm_setting_connection_get_connection_type (s_con), type_name) == 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-11 10:56:31 +01:00
|
|
|
static NMConnection *
|
|
|
|
|
add_conn (GHashTable *connections,
|
|
|
|
|
const char *basename,
|
|
|
|
|
const char *id,
|
|
|
|
|
const char *ifname,
|
|
|
|
|
const char *type_name,
|
|
|
|
|
NMConnectionMultiConnect multi_connect)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSetting *setting;
|
|
|
|
|
|
|
|
|
|
connection = nm_simple_connection_new ();
|
|
|
|
|
g_hash_table_insert (connections, g_strdup (basename), connection);
|
|
|
|
|
|
|
|
|
|
/* Start off assuming dynamic IP configurations. */
|
|
|
|
|
|
|
|
|
|
setting = nm_setting_ip4_config_new ();
|
|
|
|
|
nm_connection_add_setting (connection, setting);
|
|
|
|
|
g_object_set (setting,
|
|
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
|
|
|
|
|
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
setting = nm_setting_ip6_config_new ();
|
|
|
|
|
nm_connection_add_setting (connection, setting);
|
|
|
|
|
g_object_set (setting,
|
|
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
|
|
|
|
|
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
|
2019-12-04 18:25:39 +01:00
|
|
|
NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, (int) NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64,
|
2019-11-11 10:56:31 +01:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
setting = nm_setting_connection_new ();
|
|
|
|
|
nm_connection_add_setting (connection, setting);
|
|
|
|
|
g_object_set (setting,
|
|
|
|
|
NM_SETTING_CONNECTION_ID, id,
|
|
|
|
|
NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (),
|
|
|
|
|
NM_SETTING_CONNECTION_INTERFACE_NAME, ifname,
|
|
|
|
|
NM_SETTING_CONNECTION_TYPE, type_name,
|
|
|
|
|
NM_SETTING_CONNECTION_MULTI_CONNECT, multi_connect,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-09 18:02:51 +02:00
|
|
|
static NMConnection *
|
|
|
|
|
get_conn (GHashTable *connections, const char *ifname, const char *type_name)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSetting *setting;
|
2019-01-14 16:10:44 +01:00
|
|
|
const char *basename;
|
|
|
|
|
NMConnectionMultiConnect multi_connect;
|
|
|
|
|
|
|
|
|
|
if (ifname) {
|
|
|
|
|
basename = ifname;
|
|
|
|
|
multi_connect = NM_CONNECTION_MULTI_CONNECT_SINGLE;
|
|
|
|
|
} else {
|
|
|
|
|
/* This is essentially for the "ip=dhcp" scenario. */
|
|
|
|
|
basename = "default_connection";
|
|
|
|
|
multi_connect = NM_CONNECTION_MULTI_CONNECT_MULTIPLE;
|
|
|
|
|
}
|
2018-08-09 18:02:51 +02:00
|
|
|
|
2019-07-02 10:03:00 +02:00
|
|
|
connection = g_hash_table_lookup (connections, (gpointer) basename);
|
|
|
|
|
if (!connection && !ifname) {
|
|
|
|
|
/*
|
|
|
|
|
* If ifname was not given, we'll match the connection by type.
|
|
|
|
|
* If the type was not given either, then we're happy with any connection but slaves.
|
|
|
|
|
* This is so that things like "bond=bond0:eth1,eth2 nameserver=1.3.3.7 end up
|
|
|
|
|
* slapping the nameserver to the most reasonable connection (bond0).
|
|
|
|
|
*/
|
|
|
|
|
connection = g_hash_table_find (connections,
|
|
|
|
|
_connection_matches_type,
|
|
|
|
|
(gpointer) type_name);
|
|
|
|
|
}
|
2018-08-09 18:02:51 +02:00
|
|
|
|
2019-11-11 10:56:31 +01:00
|
|
|
if (!connection) {
|
2018-08-09 18:02:51 +02:00
|
|
|
if (!type_name)
|
|
|
|
|
type_name = NM_SETTING_WIRED_SETTING_NAME;
|
2019-11-11 10:56:31 +01:00
|
|
|
|
|
|
|
|
connection = add_conn (connections, basename,
|
|
|
|
|
ifname ?: "Wired Connection",
|
|
|
|
|
ifname, type_name, multi_connect);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
2019-11-11 10:56:31 +01:00
|
|
|
setting = (NMSetting *)nm_connection_get_setting_connection (connection);
|
2018-08-09 18:02:51 +02:00
|
|
|
|
|
|
|
|
if (type_name) {
|
|
|
|
|
g_object_set (setting, NM_SETTING_CONNECTION_TYPE, type_name, NULL);
|
|
|
|
|
if (!nm_connection_get_setting_by_name (connection, type_name)) {
|
|
|
|
|
setting = g_object_new (nm_setting_lookup_type (type_name), NULL);
|
|
|
|
|
nm_connection_add_setting (connection, setting);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
get_word (char **argument, const char separator)
|
|
|
|
|
{
|
|
|
|
|
char *word;
|
|
|
|
|
int nest = 0;
|
|
|
|
|
|
|
|
|
|
if (*argument == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
if (**argument == '[') {
|
|
|
|
|
nest++;
|
|
|
|
|
(*argument)++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
word = *argument;
|
|
|
|
|
|
|
|
|
|
while (**argument != '\0') {
|
|
|
|
|
if (nest && **argument == ']') {
|
|
|
|
|
**argument = '\0';
|
|
|
|
|
(*argument)++;
|
|
|
|
|
nest--;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nest == 0 && **argument == separator) {
|
|
|
|
|
**argument = '\0';
|
|
|
|
|
(*argument)++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
(*argument)++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return *word ? word : NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_base_setting_set (NMConnection *connection, const char *property, const char *value)
|
|
|
|
|
{
|
|
|
|
|
NMSetting *setting;
|
|
|
|
|
const char *type_name = nm_connection_get_connection_type (connection);
|
|
|
|
|
GObjectClass *object_class = g_type_class_ref (nm_setting_lookup_type (type_name));
|
|
|
|
|
GParamSpec *spec = g_object_class_find_property (object_class, property);
|
|
|
|
|
|
|
|
|
|
if (!spec) {
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "'%s' does not support setting %s", type_name, property);
|
2018-08-09 18:02:51 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setting = nm_connection_get_setting_by_name (connection, type_name);
|
|
|
|
|
|
2018-10-22 08:26:45 +02:00
|
|
|
if (G_IS_PARAM_SPEC_UINT (spec)) {
|
|
|
|
|
guint v;
|
|
|
|
|
|
|
|
|
|
v = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT, 0);
|
|
|
|
|
if ( errno
|
|
|
|
|
|| !nm_g_object_set_property_uint (G_OBJECT (setting), property, v, NULL)) {
|
|
|
|
|
_LOGW (LOGD_CORE,
|
|
|
|
|
"Could not set property '%s.%s' to '%s'",
|
|
|
|
|
type_name, property, value);
|
|
|
|
|
}
|
|
|
|
|
} else if (G_IS_PARAM_SPEC_STRING (spec))
|
2018-08-09 18:02:51 +02:00
|
|
|
g_object_set (setting, property, value, NULL);
|
|
|
|
|
else
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Don't know how to set '%s' of %s", property, type_name);
|
2018-08-09 18:02:51 +02:00
|
|
|
|
|
|
|
|
g_type_class_unref (object_class);
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-11 14:13:19 +01:00
|
|
|
static void
|
|
|
|
|
read_all_connections_from_fw (GHashTable *connections, const char *sysfs_dir)
|
|
|
|
|
{
|
|
|
|
|
gs_unref_hashtable GHashTable *ibft = NULL;
|
2020-03-25 18:34:01 +01:00
|
|
|
NMConnection *dt_connection;
|
2020-01-11 14:13:19 +01:00
|
|
|
GHashTableIter iter;
|
|
|
|
|
const char *mac;
|
|
|
|
|
GHashTable *nic;
|
|
|
|
|
const char *index;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
ibft = nmi_ibft_read (sysfs_dir);
|
|
|
|
|
|
|
|
|
|
g_hash_table_iter_init (&iter, ibft);
|
2020-01-14 16:39:42 +01:00
|
|
|
while (g_hash_table_iter_next (&iter, (gpointer *) &mac, (gpointer *) &nic)) {
|
2020-03-25 18:34:01 +01:00
|
|
|
gs_unref_object NMConnection *connection = NULL;
|
2020-01-11 14:13:19 +01:00
|
|
|
|
2020-03-25 18:34:01 +01:00
|
|
|
connection = nm_simple_connection_new ();
|
2020-01-11 14:13:19 +01:00
|
|
|
index = g_hash_table_lookup (nic, "index");
|
|
|
|
|
if (!index) {
|
|
|
|
|
_LOGW (LOGD_CORE, "Ignoring an iBFT entry without an index");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!nmi_ibft_update_connection_from_nic (connection, nic, &error)) {
|
|
|
|
|
_LOGW (LOGD_CORE, "Unable to merge iBFT configuration: %s", error->message);
|
|
|
|
|
g_error_free (error);
|
2020-03-25 18:34:01 +01:00
|
|
|
continue;
|
2020-01-11 14:13:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_hash_table_insert (connections,
|
|
|
|
|
g_strdup_printf ("ibft%s", index),
|
2020-03-25 18:34:01 +01:00
|
|
|
g_steal_pointer (&connection));
|
2020-01-11 14:13:19 +01:00
|
|
|
}
|
|
|
|
|
|
2020-03-25 18:34:01 +01:00
|
|
|
dt_connection = nmi_dt_reader_parse (sysfs_dir);
|
|
|
|
|
if (dt_connection) {
|
2020-01-11 14:13:19 +01:00
|
|
|
g_hash_table_insert (connections,
|
|
|
|
|
g_strdup ("ofw"),
|
2020-03-25 18:34:01 +01:00
|
|
|
dt_connection);
|
2020-01-11 14:13:19 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-09 18:02:51 +02:00
|
|
|
static void
|
|
|
|
|
parse_ip (GHashTable *connections, const char *sysfs_dir, char *argument)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingIPConfig *s_ip4 = NULL, *s_ip6 = NULL;
|
|
|
|
|
gs_unref_hashtable GHashTable *ibft = NULL;
|
|
|
|
|
const char *tmp;
|
|
|
|
|
const char *kind = NULL;
|
|
|
|
|
const char *client_ip = NULL;
|
|
|
|
|
const char *peer = NULL;
|
|
|
|
|
const char *gateway_ip = NULL;
|
|
|
|
|
const char *netmask = NULL;
|
|
|
|
|
const char *client_hostname = NULL;
|
|
|
|
|
const char *ifname = NULL;
|
|
|
|
|
const char *mtu = NULL;
|
|
|
|
|
const char *macaddr = NULL;
|
|
|
|
|
int client_ip_family = AF_UNSPEC;
|
|
|
|
|
int client_ip_prefix = -1;
|
|
|
|
|
const char *dns[2] = { 0, };
|
|
|
|
|
int dns_addr_family[2] = { 0, };
|
|
|
|
|
int i;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
if (!*argument)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
tmp = get_word (&argument, ':');
|
|
|
|
|
if (!*argument) {
|
|
|
|
|
/* ip={dhcp|on|any|dhcp6|auto6|ibft} */
|
|
|
|
|
kind = tmp;
|
|
|
|
|
} else {
|
|
|
|
|
client_ip_family = guess_ip_address_family (tmp);
|
|
|
|
|
if (client_ip_family != AF_UNSPEC) {
|
|
|
|
|
/* <client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>: */
|
|
|
|
|
client_ip = tmp;
|
|
|
|
|
peer = get_word (&argument, ':');
|
|
|
|
|
gateway_ip = get_word (&argument, ':');
|
|
|
|
|
netmask = get_word (&argument, ':');
|
|
|
|
|
client_hostname = get_word (&argument, ':');
|
|
|
|
|
ifname = get_word (&argument, ':');
|
|
|
|
|
} else {
|
|
|
|
|
ifname = tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* <ifname>:{none|off|dhcp|on|any|dhcp6|auto6|ibft} */
|
|
|
|
|
|
|
|
|
|
kind = get_word (&argument, ':');
|
|
|
|
|
|
|
|
|
|
tmp = get_word (&argument, ':');
|
|
|
|
|
dns_addr_family[0] = guess_ip_address_family (tmp);
|
|
|
|
|
if (dns_addr_family[0] != AF_UNSPEC) {
|
|
|
|
|
dns[0] = tmp;
|
|
|
|
|
dns[1] = get_word (&argument, ':');
|
|
|
|
|
dns_addr_family[1] = guess_ip_address_family (dns[1]);
|
2019-08-02 09:24:01 +02:00
|
|
|
if (*argument)
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Ignoring extra: '%s'.", argument);
|
2018-08-09 18:02:51 +02:00
|
|
|
} else {
|
|
|
|
|
mtu = tmp;
|
|
|
|
|
macaddr = argument;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-02 17:11:05 +02:00
|
|
|
if (ifname == NULL && ( g_strcmp0 (kind, "fw") == 0
|
|
|
|
|
|| g_strcmp0 (kind, "ibft") == 0)) {
|
2020-01-11 14:13:19 +01:00
|
|
|
read_all_connections_from_fw (connections, sysfs_dir);
|
2018-08-09 18:02:51 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Parsing done, construct the NMConnection. */
|
|
|
|
|
connection = get_conn (connections, ifname, NULL);
|
|
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
|
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
|
|
|
|
|
|
|
|
|
if (netmask && *netmask) {
|
|
|
|
|
NMIPAddr addr;
|
|
|
|
|
|
2019-07-02 09:45:22 +02:00
|
|
|
if (nm_utils_parse_inaddr_bin (AF_INET, netmask, NULL, &addr))
|
2018-08-09 18:02:51 +02:00
|
|
|
client_ip_prefix = nm_utils_ip4_netmask_to_prefix (addr.addr4);
|
2019-07-02 09:45:22 +02:00
|
|
|
else
|
|
|
|
|
client_ip_prefix = _nm_utils_ascii_str_to_int64 (netmask, 10, 0, 32, -1);
|
|
|
|
|
|
|
|
|
|
if (client_ip_prefix == -1)
|
2019-07-02 09:31:46 +02:00
|
|
|
_LOGW (LOGD_CORE, "Invalid IP mask: %s", netmask);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Static IP configuration might be present. */
|
|
|
|
|
if (client_ip && *client_ip) {
|
|
|
|
|
NMIPAddress *address = NULL;
|
|
|
|
|
NMIPAddr addr;
|
|
|
|
|
|
2018-09-18 18:14:09 +02:00
|
|
|
if (nm_utils_parse_inaddr_prefix_bin (client_ip_family, client_ip, NULL, &addr,
|
2018-08-09 18:02:51 +02:00
|
|
|
client_ip_prefix == -1 ? &client_ip_prefix : NULL)) {
|
|
|
|
|
if (client_ip_prefix == -1) {
|
|
|
|
|
switch (client_ip_family) {
|
|
|
|
|
case AF_INET:
|
|
|
|
|
client_ip_prefix = _nm_utils_ip4_get_default_prefix (addr.addr4);
|
|
|
|
|
break;
|
|
|
|
|
case AF_INET6:
|
|
|
|
|
client_ip_prefix = 64;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
address = nm_ip_address_new_binary (client_ip_family, &addr.addr_ptr, client_ip_prefix, &error);
|
|
|
|
|
if (!address) {
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Invalid address '%s': %s", client_ip, error->message);
|
2018-08-09 18:02:51 +02:00
|
|
|
g_clear_error (&error);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Unrecognized address: %s", client_ip);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (address) {
|
|
|
|
|
switch (client_ip_family) {
|
|
|
|
|
case AF_INET:
|
|
|
|
|
g_object_set (s_ip4,
|
2018-09-18 18:44:42 +02:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
|
|
|
|
|
NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE,
|
|
|
|
|
NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
nm_setting_ip_config_add_address (s_ip4, address);
|
|
|
|
|
break;
|
|
|
|
|
case AF_INET6:
|
|
|
|
|
g_object_set (s_ip6,
|
2018-09-18 18:44:42 +02:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
|
|
|
|
|
NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE,
|
|
|
|
|
NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
nm_setting_ip_config_add_address (s_ip6, address);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Unknown address family: %s", client_ip);
|
2018-08-09 18:02:51 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
nm_ip_address_unref (address);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Dynamic IP configuration configured explicitly. */
|
|
|
|
|
if (g_strcmp0 (kind, "none") == 0 || (g_strcmp0 (kind, "off") == 0)) {
|
|
|
|
|
if (nm_setting_ip_config_get_num_addresses (s_ip6) == 0) {
|
|
|
|
|
g_object_set (s_ip6,
|
2019-04-26 13:25:21 +02:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
|
2018-09-18 18:44:42 +02:00
|
|
|
NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
if (nm_setting_ip_config_get_num_addresses (s_ip4) == 0) {
|
|
|
|
|
g_object_set (s_ip4,
|
2018-09-18 18:44:42 +02:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
|
|
|
|
NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
} else if (g_strcmp0 (kind, "dhcp") == 0) {
|
|
|
|
|
g_object_set (s_ip4,
|
2018-09-18 18:44:42 +02:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
|
|
|
|
|
NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE,
|
|
|
|
|
NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
if (nm_setting_ip_config_get_num_addresses (s_ip6) == 0) {
|
|
|
|
|
g_object_set (s_ip6,
|
2019-04-26 13:25:21 +02:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
|
2018-09-18 18:44:42 +02:00
|
|
|
NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
} else if (g_strcmp0 (kind, "dhcp6") == 0) {
|
|
|
|
|
g_object_set (s_ip6,
|
2018-09-18 18:44:42 +02:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_DHCP,
|
|
|
|
|
NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE,
|
|
|
|
|
NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
if (nm_setting_ip_config_get_num_addresses (s_ip4) == 0) {
|
|
|
|
|
g_object_set (s_ip4,
|
2018-09-18 18:44:42 +02:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
|
|
|
|
NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
} else if (g_strcmp0 (kind, "auto6") == 0) {
|
|
|
|
|
g_object_set (s_ip4,
|
2018-09-18 18:44:42 +02:00
|
|
|
NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE,
|
|
|
|
|
NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
if (nm_setting_ip_config_get_num_addresses (s_ip4) == 0) {
|
|
|
|
|
g_object_set (s_ip4,
|
2018-09-18 18:44:42 +02:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
|
|
|
|
NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
} else if (g_strcmp0 (kind, "ibft") == 0) {
|
|
|
|
|
gs_free char *address_path = g_build_filename (sysfs_dir, "class", "net", ifname, "address", NULL);
|
|
|
|
|
gs_free char *mac, *mac_up = NULL;
|
|
|
|
|
GHashTable *nic = NULL;
|
|
|
|
|
|
|
|
|
|
if (!g_file_get_contents (address_path, &mac, NULL, &error)) {
|
|
|
|
|
_LOGW (LOGD_CORE, "Can't get a MAC address for %s: %s", ifname, error->message);
|
|
|
|
|
g_clear_error (&error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mac) {
|
|
|
|
|
g_strchomp (mac);
|
|
|
|
|
mac_up = g_ascii_strup (mac, -1);
|
2020-01-11 14:13:19 +01:00
|
|
|
ibft = nmi_ibft_read (sysfs_dir);
|
2018-08-09 18:02:51 +02:00
|
|
|
nic = g_hash_table_lookup (ibft, mac_up);
|
|
|
|
|
if (!nic)
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "No iBFT NIC for %s (%s)", ifname, mac_up);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nic) {
|
|
|
|
|
if (!nmi_ibft_update_connection_from_nic (connection, nic, &error)) {
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Unable to merge iBFT configuration: %s", error->message);
|
2018-08-09 18:02:51 +02:00
|
|
|
g_clear_error (&error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (peer && *peer)
|
2019-07-02 09:33:20 +02:00
|
|
|
_LOGW (LOGD_CORE, "Ignoring peer: %s (not implemented)\n", peer);
|
2018-08-09 18:02:51 +02:00
|
|
|
|
|
|
|
|
if (gateway_ip && *gateway_ip) {
|
|
|
|
|
int addr_family = guess_ip_address_family (gateway_ip);
|
|
|
|
|
|
2020-01-09 12:17:41 +01:00
|
|
|
if (nm_utils_ipaddr_is_valid (addr_family, gateway_ip)) {
|
2018-08-09 18:02:51 +02:00
|
|
|
switch (addr_family) {
|
|
|
|
|
case AF_INET:
|
|
|
|
|
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway_ip, NULL);
|
|
|
|
|
break;
|
|
|
|
|
case AF_INET6:
|
|
|
|
|
g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, gateway_ip, NULL);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Unknown address family: %s", gateway_ip);
|
2018-08-09 18:02:51 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Invalid gateway: %s", gateway_ip);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (client_hostname && *client_hostname) {
|
|
|
|
|
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, client_hostname, NULL);
|
|
|
|
|
g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, client_hostname, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
|
if (dns_addr_family[i] == AF_UNSPEC)
|
|
|
|
|
break;
|
2020-01-09 12:17:41 +01:00
|
|
|
if (nm_utils_ipaddr_is_valid (dns_addr_family[i], dns[i])) {
|
2018-08-09 18:02:51 +02:00
|
|
|
switch (dns_addr_family[i]) {
|
|
|
|
|
case AF_INET:
|
|
|
|
|
nm_setting_ip_config_add_dns (s_ip4, dns[i]);
|
|
|
|
|
break;
|
|
|
|
|
case AF_INET6:
|
|
|
|
|
nm_setting_ip_config_add_dns (s_ip6, dns[i]);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Unknown address family: %s", dns[i]);
|
2018-08-09 18:02:51 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Invalid name server: %s", dns[i]);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mtu && *mtu)
|
|
|
|
|
_base_setting_set (connection, "mtu", mtu);
|
|
|
|
|
|
|
|
|
|
if (macaddr && *macaddr)
|
|
|
|
|
_base_setting_set (connection, "cloned-mac-address", macaddr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2019-11-07 15:29:31 +01:00
|
|
|
parse_master (GHashTable *connections,
|
|
|
|
|
char *argument,
|
|
|
|
|
const char *type_name,
|
|
|
|
|
const char *default_name)
|
2018-08-09 18:02:51 +02:00
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
NMSettingBond *s_bond;
|
|
|
|
|
gs_free char *master_to_free = NULL;
|
|
|
|
|
const char *master;
|
|
|
|
|
char *slaves;
|
|
|
|
|
const char *slave;
|
|
|
|
|
char *opts;
|
|
|
|
|
char *opt;
|
|
|
|
|
const char *opt_name;
|
|
|
|
|
const char *mtu = NULL;
|
|
|
|
|
|
|
|
|
|
master = get_word (&argument, ':');
|
|
|
|
|
if (!master)
|
2019-11-07 15:29:31 +01:00
|
|
|
master = master_to_free = g_strdup_printf ("%s0", default_name ?: type_name);
|
2018-08-09 18:02:51 +02:00
|
|
|
slaves = get_word (&argument, ':');
|
|
|
|
|
|
|
|
|
|
connection = get_conn (connections, master, type_name);
|
|
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
|
|
|
|
master = nm_setting_connection_get_uuid (s_con);
|
|
|
|
|
|
|
|
|
|
if (strcmp (type_name, NM_SETTING_BOND_SETTING_NAME) == 0) {
|
|
|
|
|
s_bond = (NMSettingBond *)nm_connection_get_setting_by_name (connection, type_name);
|
|
|
|
|
|
|
|
|
|
opts = get_word (&argument, ':');
|
|
|
|
|
while (opts && *opts) {
|
|
|
|
|
opt = get_word (&opts, ',');
|
|
|
|
|
opt_name = get_word (&opt, '=');
|
|
|
|
|
nm_setting_bond_add_option (s_bond, opt_name, opt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mtu = get_word (&argument, ':');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
slave = get_word (&slaves, ',');
|
|
|
|
|
if (slave == NULL)
|
|
|
|
|
slave = "eth0";
|
|
|
|
|
|
|
|
|
|
connection = get_conn (connections, slave, NULL);
|
|
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
|
|
|
|
g_object_set (s_con,
|
|
|
|
|
NM_SETTING_CONNECTION_SLAVE_TYPE, type_name,
|
|
|
|
|
NM_SETTING_CONNECTION_MASTER, master,
|
|
|
|
|
NULL);
|
|
|
|
|
if (mtu)
|
|
|
|
|
_base_setting_set (connection, "mtu", mtu);
|
|
|
|
|
} while (slaves && *slaves != '\0');
|
|
|
|
|
|
|
|
|
|
if (argument && *argument)
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Ignoring extra: '%s'.", argument);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
parse_rd_route (GHashTable *connections, char *argument)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
const char *net;
|
|
|
|
|
const char *gateway;
|
|
|
|
|
const char *interface;
|
|
|
|
|
int family = AF_UNSPEC;
|
2019-02-08 12:24:07 +01:00
|
|
|
NMIPAddr net_addr = { };
|
|
|
|
|
NMIPAddr gateway_addr = { };
|
2018-08-09 18:02:51 +02:00
|
|
|
int net_prefix = -1;
|
|
|
|
|
NMIPRoute *route;
|
|
|
|
|
NMSettingIPConfig *s_ip;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
net = get_word (&argument, ':');
|
|
|
|
|
gateway = get_word (&argument, ':');
|
|
|
|
|
interface = get_word (&argument, ':');
|
|
|
|
|
|
|
|
|
|
connection = get_conn (connections, interface, NULL);
|
|
|
|
|
|
|
|
|
|
if (net && *net) {
|
2018-09-18 18:14:09 +02:00
|
|
|
if (!nm_utils_parse_inaddr_prefix_bin (family, net, &family, &net_addr, &net_prefix)) {
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Unrecognized address: %s", net);
|
2018-08-09 18:02:51 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-18 18:14:09 +02:00
|
|
|
if (gateway && *gateway) {
|
|
|
|
|
if (!nm_utils_parse_inaddr_bin (family, gateway, &family, &gateway_addr)) {
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Unrecognized address: %s", gateway);
|
2018-08-09 18:02:51 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (family) {
|
|
|
|
|
case AF_INET:
|
|
|
|
|
s_ip = nm_connection_get_setting_ip4_config (connection);
|
|
|
|
|
if (net_prefix == -1)
|
|
|
|
|
net_prefix = 32;
|
|
|
|
|
break;
|
|
|
|
|
case AF_INET6:
|
|
|
|
|
s_ip = nm_connection_get_setting_ip6_config (connection);
|
|
|
|
|
if (net_prefix == -1)
|
|
|
|
|
net_prefix = 128;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Unknown address family: %s", net);
|
2018-08-09 18:02:51 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
route = nm_ip_route_new_binary (family, &net_addr.addr_ptr, net_prefix, &gateway_addr.addr_ptr, -1, &error);
|
|
|
|
|
if (!route) {
|
|
|
|
|
g_warning ("Invalid route '%s via %s': %s\n", net, gateway, error->message);
|
|
|
|
|
g_clear_error (&error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_setting_ip_config_add_route (s_ip, route);
|
|
|
|
|
nm_ip_route_unref (route);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
parse_vlan (GHashTable *connections, char *argument)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingVlan *s_vlan;
|
|
|
|
|
const char *vlan;
|
|
|
|
|
const char *phy;
|
|
|
|
|
const char *vlanid;
|
|
|
|
|
|
|
|
|
|
vlan = get_word (&argument, ':');
|
|
|
|
|
phy = get_word (&argument, ':');
|
|
|
|
|
|
|
|
|
|
for (vlanid = vlan + strlen (vlan); vlanid > vlan; vlanid--) {
|
|
|
|
|
if (!g_ascii_isdigit (*(vlanid - 1)))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
connection = get_conn (connections, vlan, NM_SETTING_VLAN_SETTING_NAME);
|
|
|
|
|
|
|
|
|
|
s_vlan = nm_connection_get_setting_vlan (connection);
|
|
|
|
|
g_object_set (s_vlan,
|
|
|
|
|
NM_SETTING_VLAN_PARENT, phy,
|
|
|
|
|
NM_SETTING_VLAN_ID, g_ascii_strtoull (vlanid, NULL, 10),
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
if (argument && *argument)
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Ignoring extra: '%s'.", argument);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
parse_bootdev (GHashTable *connections, char *argument)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
|
|
|
|
|
connection = get_conn (connections, NULL, NULL);
|
|
|
|
|
|
2019-11-07 18:54:54 +01:00
|
|
|
if ( nm_connection_get_interface_name (connection)
|
|
|
|
|
&& strcmp (nm_connection_get_interface_name (connection), argument) != 0) {
|
|
|
|
|
/* If the default connection already has an interface name,
|
|
|
|
|
* we should not overwrite it. Create a new one instead. */
|
|
|
|
|
connection = get_conn (connections, argument, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-09 18:02:51 +02:00
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
|
|
|
|
g_object_set (s_con,
|
|
|
|
|
NM_SETTING_CONNECTION_INTERFACE_NAME, argument,
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
parse_nameserver (GHashTable *connections, char *argument)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingIPConfig *s_ip = NULL;
|
|
|
|
|
char *dns;
|
|
|
|
|
|
|
|
|
|
connection = get_conn (connections, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
dns = get_word (&argument, '\0');
|
|
|
|
|
|
|
|
|
|
switch (guess_ip_address_family (dns)) {
|
|
|
|
|
case AF_INET:
|
|
|
|
|
s_ip = nm_connection_get_setting_ip4_config (connection);
|
|
|
|
|
break;
|
|
|
|
|
case AF_INET6:
|
|
|
|
|
s_ip = nm_connection_get_setting_ip6_config (connection);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Unknown address family: %s", dns);
|
2018-08-09 18:02:51 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_setting_ip_config_add_dns (s_ip, dns);
|
|
|
|
|
|
|
|
|
|
if (argument && *argument)
|
2018-10-06 11:26:42 +02:00
|
|
|
_LOGW (LOGD_CORE, "Ignoring extra: '%s'.", argument);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
parse_rd_peerdns (GHashTable *connections, char *argument)
|
|
|
|
|
{
|
|
|
|
|
gboolean auto_dns = !_nm_utils_ascii_str_to_bool (argument, TRUE);
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingIPConfig *s_ip = NULL;
|
|
|
|
|
|
|
|
|
|
connection = get_conn (connections, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
s_ip = nm_connection_get_setting_ip4_config (connection);
|
|
|
|
|
g_object_set (s_ip,
|
|
|
|
|
NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, auto_dns,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
s_ip = nm_connection_get_setting_ip6_config (connection);
|
|
|
|
|
g_object_set (s_ip,
|
|
|
|
|
NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, auto_dns,
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-20 16:25:17 +02:00
|
|
|
static void
|
2019-10-22 16:56:38 +02:00
|
|
|
parse_rd_znet (GHashTable *connections, char *argument, gboolean net_ifnames)
|
2019-09-20 16:25:17 +02:00
|
|
|
{
|
initrd: avoid assertion inparse_rd_znet() and cleanup
- nm_setting_wired_add_s390_option() asserts that a "value" argument
is given. Check that the string contains a '=' where we can split.
- pass the requested NM_SETTING_WIRED_SETTING_NAME type to get_conn().
Otherwise, @s_wired might be %NULL, resulting in an assertion.
I do wonder whether this always retrieves a connection of the
appropriate type for modification, or whether a profile could
be returned that was created for a different purpose. But that
isn't changed.
- avoid "g_strcmp0 (nettype, "ctc") != 0". I find it unexpected, that we add the
3rd subchannel component, if the nettype is "ctc" (intuitively, I'd expect it
to be the opposite). The reasons for this are not documented, but I
presume it is correct.
Anyway, using streq() makes this slightly more clear to me, as with
strcmp() I would wonder whether this was just a typo while with
streq() I'd be more confident that this is indeed intended.
- don't initialize local variables unnecessarily. The compiler would
warn if we would forget about this. Also, don'\''t use { } for a
one-line block.
2019-09-27 07:58:58 +02:00
|
|
|
const char *nettype;
|
2019-09-20 16:25:17 +02:00
|
|
|
const char *subchannels[4] = { 0, 0, 0, 0 };
|
initrd: avoid assertion inparse_rd_znet() and cleanup
- nm_setting_wired_add_s390_option() asserts that a "value" argument
is given. Check that the string contains a '=' where we can split.
- pass the requested NM_SETTING_WIRED_SETTING_NAME type to get_conn().
Otherwise, @s_wired might be %NULL, resulting in an assertion.
I do wonder whether this always retrieves a connection of the
appropriate type for modification, or whether a profile could
be returned that was created for a different purpose. But that
isn't changed.
- avoid "g_strcmp0 (nettype, "ctc") != 0". I find it unexpected, that we add the
3rd subchannel component, if the nettype is "ctc" (intuitively, I'd expect it
to be the opposite). The reasons for this are not documented, but I
presume it is correct.
Anyway, using streq() makes this slightly more clear to me, as with
strcmp() I would wonder whether this was just a typo while with
streq() I'd be more confident that this is indeed intended.
- don't initialize local variables unnecessarily. The compiler would
warn if we would forget about this. Also, don'\''t use { } for a
one-line block.
2019-09-27 07:58:58 +02:00
|
|
|
const char *tmp;
|
2019-10-22 16:56:38 +02:00
|
|
|
gs_free char *ifname = NULL;
|
|
|
|
|
const char *prefix;
|
2019-09-20 16:25:17 +02:00
|
|
|
NMConnection *connection;
|
initrd: avoid assertion inparse_rd_znet() and cleanup
- nm_setting_wired_add_s390_option() asserts that a "value" argument
is given. Check that the string contains a '=' where we can split.
- pass the requested NM_SETTING_WIRED_SETTING_NAME type to get_conn().
Otherwise, @s_wired might be %NULL, resulting in an assertion.
I do wonder whether this always retrieves a connection of the
appropriate type for modification, or whether a profile could
be returned that was created for a different purpose. But that
isn't changed.
- avoid "g_strcmp0 (nettype, "ctc") != 0". I find it unexpected, that we add the
3rd subchannel component, if the nettype is "ctc" (intuitively, I'd expect it
to be the opposite). The reasons for this are not documented, but I
presume it is correct.
Anyway, using streq() makes this slightly more clear to me, as with
strcmp() I would wonder whether this was just a typo while with
streq() I'd be more confident that this is indeed intended.
- don't initialize local variables unnecessarily. The compiler would
warn if we would forget about this. Also, don'\''t use { } for a
one-line block.
2019-09-27 07:58:58 +02:00
|
|
|
NMSettingWired *s_wired;
|
2019-10-23 11:56:47 +02:00
|
|
|
static int count_ctc = 0;
|
|
|
|
|
static int count_eth = 0;
|
|
|
|
|
int index;
|
2019-09-20 16:25:17 +02:00
|
|
|
|
|
|
|
|
nettype = get_word (&argument, ',');
|
|
|
|
|
subchannels[0] = get_word (&argument, ',');
|
|
|
|
|
subchannels[1] = get_word (&argument, ',');
|
2019-10-22 11:18:09 +02:00
|
|
|
|
|
|
|
|
if (nm_streq0 (nettype, "ctc")) {
|
2019-10-23 11:56:47 +02:00
|
|
|
if (net_ifnames == TRUE) {
|
|
|
|
|
prefix = "sl";
|
|
|
|
|
} else {
|
|
|
|
|
prefix = "ctc";
|
|
|
|
|
index = count_ctc++;
|
|
|
|
|
}
|
2019-10-22 11:18:09 +02:00
|
|
|
} else {
|
2019-09-20 16:25:17 +02:00
|
|
|
subchannels[2] = get_word (&argument, ',');
|
2019-10-23 11:56:47 +02:00
|
|
|
if (net_ifnames == TRUE) {
|
|
|
|
|
prefix = "en";
|
|
|
|
|
} else {
|
|
|
|
|
prefix = "eth";
|
|
|
|
|
index = count_eth++;
|
|
|
|
|
}
|
2019-10-22 11:18:09 +02:00
|
|
|
}
|
2019-09-20 16:25:17 +02:00
|
|
|
|
2019-10-22 16:56:38 +02:00
|
|
|
if (net_ifnames == TRUE) {
|
|
|
|
|
const char *bus_id;
|
|
|
|
|
size_t bus_id_len;
|
|
|
|
|
size_t bus_id_start;
|
|
|
|
|
|
|
|
|
|
/* The following logic is taken from names_ccw() in systemd/src/udev/udev-builtin-net_id.c */
|
|
|
|
|
bus_id = subchannels[0];
|
|
|
|
|
bus_id_len = strlen (bus_id);
|
|
|
|
|
bus_id_start = strspn (bus_id, ".0");
|
|
|
|
|
bus_id += bus_id_start < bus_id_len ? bus_id_start : bus_id_len - 1;
|
|
|
|
|
|
|
|
|
|
ifname = g_strdup_printf ("%sc%s", prefix, bus_id);
|
2019-10-23 11:56:47 +02:00
|
|
|
} else {
|
|
|
|
|
ifname = g_strdup_printf ("%s%d", prefix, index);
|
2019-10-22 16:56:38 +02:00
|
|
|
}
|
|
|
|
|
|
2019-10-22 11:18:09 +02:00
|
|
|
connection = get_conn (connections, ifname, NM_SETTING_WIRED_SETTING_NAME);
|
2019-09-20 16:25:17 +02:00
|
|
|
s_wired = nm_connection_get_setting_wired (connection);
|
|
|
|
|
g_object_set (s_wired,
|
|
|
|
|
NM_SETTING_WIRED_S390_NETTYPE, nettype,
|
|
|
|
|
NM_SETTING_WIRED_S390_SUBCHANNELS, &subchannels,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
while ((tmp = get_word (&argument, ',')) != NULL) {
|
initrd: avoid assertion inparse_rd_znet() and cleanup
- nm_setting_wired_add_s390_option() asserts that a "value" argument
is given. Check that the string contains a '=' where we can split.
- pass the requested NM_SETTING_WIRED_SETTING_NAME type to get_conn().
Otherwise, @s_wired might be %NULL, resulting in an assertion.
I do wonder whether this always retrieves a connection of the
appropriate type for modification, or whether a profile could
be returned that was created for a different purpose. But that
isn't changed.
- avoid "g_strcmp0 (nettype, "ctc") != 0". I find it unexpected, that we add the
3rd subchannel component, if the nettype is "ctc" (intuitively, I'd expect it
to be the opposite). The reasons for this are not documented, but I
presume it is correct.
Anyway, using streq() makes this slightly more clear to me, as with
strcmp() I would wonder whether this was just a typo while with
streq() I'd be more confident that this is indeed intended.
- don't initialize local variables unnecessarily. The compiler would
warn if we would forget about this. Also, don'\''t use { } for a
one-line block.
2019-09-27 07:58:58 +02:00
|
|
|
char *val;
|
2019-09-20 16:25:17 +02:00
|
|
|
|
initrd: avoid assertion inparse_rd_znet() and cleanup
- nm_setting_wired_add_s390_option() asserts that a "value" argument
is given. Check that the string contains a '=' where we can split.
- pass the requested NM_SETTING_WIRED_SETTING_NAME type to get_conn().
Otherwise, @s_wired might be %NULL, resulting in an assertion.
I do wonder whether this always retrieves a connection of the
appropriate type for modification, or whether a profile could
be returned that was created for a different purpose. But that
isn't changed.
- avoid "g_strcmp0 (nettype, "ctc") != 0". I find it unexpected, that we add the
3rd subchannel component, if the nettype is "ctc" (intuitively, I'd expect it
to be the opposite). The reasons for this are not documented, but I
presume it is correct.
Anyway, using streq() makes this slightly more clear to me, as with
strcmp() I would wonder whether this was just a typo while with
streq() I'd be more confident that this is indeed intended.
- don't initialize local variables unnecessarily. The compiler would
warn if we would forget about this. Also, don'\''t use { } for a
one-line block.
2019-09-27 07:58:58 +02:00
|
|
|
val = strchr (tmp, '=');
|
|
|
|
|
if (val) {
|
|
|
|
|
gs_free char *key = NULL;
|
|
|
|
|
|
|
|
|
|
key = g_strndup (tmp, val - tmp);
|
|
|
|
|
val[0] = '\0';
|
|
|
|
|
val++;
|
|
|
|
|
nm_setting_wired_add_s390_option (s_wired, key, val);
|
|
|
|
|
}
|
2019-09-20 16:25:17 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-09 18:02:51 +02:00
|
|
|
static void
|
|
|
|
|
_normalize_conn (gpointer key, gpointer value, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection = value;
|
|
|
|
|
|
|
|
|
|
nm_connection_normalize (connection, NULL, NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GHashTable *
|
2019-09-27 08:32:08 +02:00
|
|
|
nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv)
|
2018-08-09 18:02:51 +02:00
|
|
|
{
|
|
|
|
|
GHashTable *connections;
|
|
|
|
|
const char *tag;
|
|
|
|
|
gboolean ignore_bootif = FALSE;
|
2019-05-27 11:24:45 +02:00
|
|
|
gboolean neednet = FALSE;
|
2019-09-27 08:36:49 +02:00
|
|
|
gs_free char *bootif_val = NULL;
|
2019-10-22 16:56:38 +02:00
|
|
|
gboolean net_ifnames = TRUE;
|
2018-08-09 18:02:51 +02:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
connections = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref);
|
|
|
|
|
|
2019-10-22 16:56:38 +02:00
|
|
|
for (i = 0; argv[i]; i++) {
|
|
|
|
|
if (strcmp (argv[i], "net.ifnames=0") == 0)
|
|
|
|
|
net_ifnames = FALSE;
|
|
|
|
|
else if (g_str_has_prefix (argv[i], "net.ifnames="))
|
|
|
|
|
net_ifnames = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-09 18:02:51 +02:00
|
|
|
for (i = 0; argv[i]; i++) {
|
2019-09-27 08:36:49 +02:00
|
|
|
gs_free char *argument_clone = NULL;
|
|
|
|
|
char *argument;
|
|
|
|
|
|
|
|
|
|
argument_clone = g_strdup (argv[i]);
|
|
|
|
|
argument = argument_clone;
|
|
|
|
|
|
2018-08-09 18:02:51 +02:00
|
|
|
tag = get_word (&argument, '=');
|
|
|
|
|
if (strcmp (tag, "ip") == 0)
|
|
|
|
|
parse_ip (connections, sysfs_dir, argument);
|
|
|
|
|
else if (strcmp (tag, "rd.route") == 0)
|
|
|
|
|
parse_rd_route (connections, argument);
|
|
|
|
|
else if (strcmp (tag, "bridge") == 0)
|
2019-11-07 15:29:31 +01:00
|
|
|
parse_master (connections, argument, NM_SETTING_BRIDGE_SETTING_NAME, "br");
|
2018-08-09 18:02:51 +02:00
|
|
|
else if (strcmp (tag, "bond") == 0)
|
2019-11-07 15:29:31 +01:00
|
|
|
parse_master (connections, argument, NM_SETTING_BOND_SETTING_NAME, NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
else if (strcmp (tag, "team") == 0)
|
2019-11-07 15:29:31 +01:00
|
|
|
parse_master (connections, argument, NM_SETTING_TEAM_SETTING_NAME, NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
else if (strcmp (tag, "vlan") == 0)
|
|
|
|
|
parse_vlan (connections, argument);
|
|
|
|
|
else if (strcmp (tag, "bootdev") == 0)
|
|
|
|
|
parse_bootdev (connections, argument);
|
|
|
|
|
else if (strcmp (tag, "nameserver") == 0)
|
|
|
|
|
parse_nameserver (connections, argument);
|
|
|
|
|
else if (strcmp (tag, "rd.peerdns") == 0)
|
|
|
|
|
parse_rd_peerdns (connections, argument);
|
2020-01-11 14:13:19 +01:00
|
|
|
else if (strcmp (tag, "rd.iscsi.ibft") == 0 && _nm_utils_ascii_str_to_bool (argument, TRUE))
|
|
|
|
|
read_all_connections_from_fw (connections, sysfs_dir);
|
2018-08-09 18:02:51 +02:00
|
|
|
else if (strcmp (tag, "rd.bootif") == 0)
|
|
|
|
|
ignore_bootif = !_nm_utils_ascii_str_to_bool (argument, TRUE);
|
2019-05-27 11:24:45 +02:00
|
|
|
else if (strcmp (tag, "rd.neednet") == 0)
|
|
|
|
|
neednet = _nm_utils_ascii_str_to_bool (argument, TRUE);
|
2019-09-20 16:25:17 +02:00
|
|
|
else if (strcmp (tag, "rd.znet") == 0)
|
2019-10-22 16:56:38 +02:00
|
|
|
parse_rd_znet (connections, argument, net_ifnames);
|
2020-02-11 15:17:03 +01:00
|
|
|
else if (g_ascii_strcasecmp (tag, "BOOTIF") == 0) {
|
2019-09-27 08:36:49 +02:00
|
|
|
nm_clear_g_free (&bootif_val);
|
|
|
|
|
bootif_val = g_strdup (argument);
|
|
|
|
|
}
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ignore_bootif)
|
2019-09-27 08:36:49 +02:00
|
|
|
nm_clear_g_free (&bootif_val);
|
|
|
|
|
if (bootif_val) {
|
2018-08-09 18:02:51 +02:00
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingWired *s_wired;
|
2019-09-27 08:36:49 +02:00
|
|
|
const char *bootif = bootif_val;
|
2018-08-09 18:02:51 +02:00
|
|
|
|
2019-07-02 15:56:38 +02:00
|
|
|
if ( !nm_utils_hwaddr_valid (bootif, ETH_ALEN)
|
|
|
|
|
&& g_str_has_prefix (bootif, "01-")
|
|
|
|
|
&& nm_utils_hwaddr_valid (&bootif[3], ETH_ALEN)) {
|
|
|
|
|
/*
|
|
|
|
|
* BOOTIF MAC address can be prefixed with a hardware type identifier.
|
|
|
|
|
* "01" stays for "wired", no other are known.
|
|
|
|
|
*/
|
|
|
|
|
bootif += 3;
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-09 18:02:51 +02:00
|
|
|
connection = get_conn (connections, NULL, NM_SETTING_WIRED_SETTING_NAME);
|
|
|
|
|
s_wired = nm_connection_get_setting_wired (connection);
|
2019-11-11 11:23:53 +01:00
|
|
|
|
|
|
|
|
if ( nm_connection_get_interface_name (connection)
|
|
|
|
|
|| ( nm_setting_wired_get_mac_address (s_wired)
|
|
|
|
|
&& !nm_utils_hwaddr_matches (nm_setting_wired_get_mac_address (s_wired), -1,
|
|
|
|
|
bootif, -1))) {
|
|
|
|
|
connection = add_conn (connections, "bootif_connection", "BOOTIF Connection",
|
|
|
|
|
NULL, NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_CONNECTION_MULTI_CONNECT_SINGLE);
|
|
|
|
|
s_wired = (NMSettingWired *) nm_setting_wired_new ();
|
|
|
|
|
nm_connection_add_setting (connection, (NMSetting *) s_wired);
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-09 18:02:51 +02:00
|
|
|
g_object_set (s_wired,
|
2018-09-18 18:44:42 +02:00
|
|
|
NM_SETTING_WIRED_MAC_ADDRESS, bootif,
|
|
|
|
|
NULL);
|
2018-08-09 18:02:51 +02:00
|
|
|
}
|
2019-05-27 11:24:45 +02:00
|
|
|
if (neednet && g_hash_table_size (connections) == 0) {
|
|
|
|
|
/* Make sure there's some connection. */
|
|
|
|
|
get_conn (connections, NULL, NM_SETTING_WIRED_SETTING_NAME);
|
|
|
|
|
}
|
2018-08-09 18:02:51 +02:00
|
|
|
|
|
|
|
|
g_hash_table_foreach (connections, _normalize_conn, NULL);
|
|
|
|
|
|
|
|
|
|
return connections;
|
|
|
|
|
}
|