mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-04-25 14:20:43 +02:00
ifcfg-rh: add support for ifcfg alias files (rh #1067170)
This commit is contained in:
commit
cfba0f8693
30 changed files with 1298 additions and 78 deletions
|
|
@ -56,6 +56,7 @@ libnm_util_include_HEADERS = \
|
|||
libnm_util_la_private_headers = \
|
||||
crypto.h \
|
||||
nm-param-spec-specialized.h \
|
||||
nm-util-private.h \
|
||||
nm-utils-private.h \
|
||||
nm-setting-private.h
|
||||
|
||||
|
|
@ -90,6 +91,7 @@ libnm_util_la_csources = \
|
|||
nm-setting-wireless.c \
|
||||
nm-setting-wireless-security.c \
|
||||
nm-setting-vpn.c \
|
||||
nm-util-private.c \
|
||||
nm-utils-enum-types.c \
|
||||
nm-utils.c \
|
||||
nm-value-transforms.c
|
||||
|
|
|
|||
|
|
@ -600,6 +600,7 @@ global:
|
|||
nm_setting_wireless_security_remove_proto;
|
||||
nm_setting_wireless_security_remove_proto_by_value;
|
||||
nm_setting_wireless_security_set_wep_key;
|
||||
nm_util_get_private;
|
||||
nm_utils_ap_mode_security_valid;
|
||||
nm_utils_bin2hexstr;
|
||||
nm_utils_check_virtual_device_compatibility;
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ typedef struct {
|
|||
GArray *dns; /* array of guint32; elements in network byte order */
|
||||
GSList *dns_search; /* list of strings */
|
||||
GSList *addresses; /* array of NMIP4Address */
|
||||
GSList *address_labels; /* list of strings */
|
||||
GSList *routes; /* array of NMIP4Route */
|
||||
gboolean ignore_auto_routes;
|
||||
gboolean ignore_auto_dns;
|
||||
|
|
@ -94,6 +95,7 @@ enum {
|
|||
PROP_DNS,
|
||||
PROP_DNS_SEARCH,
|
||||
PROP_ADDRESSES,
|
||||
PROP_ADDRESS_LABELS,
|
||||
PROP_ROUTES,
|
||||
PROP_IGNORE_AUTO_ROUTES,
|
||||
PROP_IGNORE_AUTO_DNS,
|
||||
|
|
@ -440,6 +442,19 @@ nm_setting_ip4_config_get_address (NMSettingIP4Config *setting, guint32 i)
|
|||
return (NMIP4Address *) g_slist_nth_data (priv->addresses, i);
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_setting_ip4_config_get_address_label (NMSettingIP4Config *setting, guint32 i)
|
||||
{
|
||||
NMSettingIP4ConfigPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), NULL);
|
||||
|
||||
priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting);
|
||||
g_return_val_if_fail (i <= g_slist_length (priv->address_labels), NULL);
|
||||
|
||||
return (const char *) g_slist_nth_data (priv->address_labels, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_ip4_config_add_address:
|
||||
* @setting: the #NMSettingIP4Config
|
||||
|
|
@ -454,6 +469,14 @@ nm_setting_ip4_config_get_address (NMSettingIP4Config *setting, guint32 i)
|
|||
gboolean
|
||||
nm_setting_ip4_config_add_address (NMSettingIP4Config *setting,
|
||||
NMIP4Address *address)
|
||||
{
|
||||
return nm_setting_ip4_config_add_address_with_label (setting, address, NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_setting_ip4_config_add_address_with_label (NMSettingIP4Config *setting,
|
||||
NMIP4Address *address,
|
||||
const char *label)
|
||||
{
|
||||
NMSettingIP4ConfigPrivate *priv;
|
||||
NMIP4Address *copy;
|
||||
|
|
@ -472,6 +495,8 @@ nm_setting_ip4_config_add_address (NMSettingIP4Config *setting,
|
|||
g_return_val_if_fail (copy != NULL, FALSE);
|
||||
|
||||
priv->addresses = g_slist_append (priv->addresses, copy);
|
||||
priv->address_labels = g_slist_append (priv->address_labels, g_strdup (label));
|
||||
|
||||
g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_ADDRESSES);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -487,16 +512,21 @@ void
|
|||
nm_setting_ip4_config_remove_address (NMSettingIP4Config *setting, guint32 i)
|
||||
{
|
||||
NMSettingIP4ConfigPrivate *priv;
|
||||
GSList *elt;
|
||||
GSList *addr, *label;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTING_IP4_CONFIG (setting));
|
||||
|
||||
priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting);
|
||||
elt = g_slist_nth (priv->addresses, i);
|
||||
g_return_if_fail (elt != NULL);
|
||||
addr = g_slist_nth (priv->addresses, i);
|
||||
label = g_slist_nth (priv->address_labels, i);
|
||||
g_return_if_fail (addr != NULL && label != NULL);
|
||||
|
||||
nm_ip4_address_unref ((NMIP4Address *) addr->data);
|
||||
priv->addresses = g_slist_delete_link (priv->addresses, addr);
|
||||
if (label->data)
|
||||
g_free (label->data);
|
||||
priv->address_labels = g_slist_delete_link (priv->address_labels, label);
|
||||
|
||||
nm_ip4_address_unref ((NMIP4Address *) elt->data);
|
||||
priv->addresses = g_slist_delete_link (priv->addresses, elt);
|
||||
g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_ADDRESSES);
|
||||
}
|
||||
|
||||
|
|
@ -548,6 +578,8 @@ nm_setting_ip4_config_clear_addresses (NMSettingIP4Config *setting)
|
|||
|
||||
g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip4_address_unref);
|
||||
priv->addresses = NULL;
|
||||
g_slist_free_full (priv->address_labels, g_free);
|
||||
priv->address_labels = NULL;
|
||||
g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_ADDRESSES);
|
||||
}
|
||||
|
||||
|
|
@ -821,11 +853,35 @@ nm_setting_ip4_config_get_may_fail (NMSettingIP4Config *setting)
|
|||
return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->may_fail;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
verify_label (const char *label)
|
||||
{
|
||||
const char *p;
|
||||
char *iface;
|
||||
|
||||
p = strchr (label, ':');
|
||||
if (!p)
|
||||
return FALSE;
|
||||
iface = g_strndup (label, p - label);
|
||||
if (!nm_utils_iface_valid_name (iface)) {
|
||||
g_free (iface);
|
||||
return FALSE;
|
||||
}
|
||||
g_free (iface);
|
||||
|
||||
for (p++; *p; p++) {
|
||||
if (!g_ascii_isalnum (*p) && *p != '_')
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
verify (NMSetting *setting, GSList *all_settings, GError **error)
|
||||
{
|
||||
NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting);
|
||||
GSList *iter;
|
||||
GSList *iter, *l_iter;
|
||||
int i;
|
||||
|
||||
if (!priv->method) {
|
||||
|
|
@ -912,8 +968,11 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
|
|||
}
|
||||
|
||||
/* Validate addresses */
|
||||
for (iter = priv->addresses, i = 0; iter; iter = g_slist_next (iter), i++) {
|
||||
for (iter = priv->addresses, l_iter = priv->address_labels, i = 0;
|
||||
iter && l_iter;
|
||||
iter = g_slist_next (iter), l_iter = g_slist_next (l_iter), i++) {
|
||||
NMIP4Address *addr = (NMIP4Address *) iter->data;
|
||||
const char *label = (const char *) l_iter->data;
|
||||
guint32 prefix = nm_ip4_address_get_prefix (addr);
|
||||
|
||||
if (!nm_ip4_address_get_address (addr)) {
|
||||
|
|
@ -935,6 +994,27 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
|
|||
g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_ADDRESSES);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (label && !verify_label (label)) {
|
||||
g_set_error (error,
|
||||
NM_SETTING_IP4_CONFIG_ERROR,
|
||||
NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY,
|
||||
_("%d. IPv4 address has invalid label '%s'"),
|
||||
i+1, label);
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, "address-labels");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (iter || l_iter) {
|
||||
g_set_error (error,
|
||||
NM_SETTING_IP4_CONFIG_ERROR,
|
||||
NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY,
|
||||
_("IPv4 address / label count mismatch (%d vs %d)"),
|
||||
g_slist_length (priv->addresses),
|
||||
g_slist_length (priv->address_labels));
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, "address-labels");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Validate routes */
|
||||
|
|
@ -990,6 +1070,7 @@ finalize (GObject *object)
|
|||
|
||||
g_slist_free_full (priv->dns_search, g_free);
|
||||
g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip4_address_unref);
|
||||
g_slist_free_full (priv->address_labels, g_free);
|
||||
g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip4_route_unref);
|
||||
|
||||
G_OBJECT_CLASS (nm_setting_ip4_config_parent_class)->finalize (object);
|
||||
|
|
@ -1001,6 +1082,7 @@ set_property (GObject *object, guint prop_id,
|
|||
{
|
||||
NMSettingIP4Config *setting = NM_SETTING_IP4_CONFIG (object);
|
||||
NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting);
|
||||
GSList *iter;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_METHOD:
|
||||
|
|
@ -1020,6 +1102,24 @@ set_property (GObject *object, guint prop_id,
|
|||
case PROP_ADDRESSES:
|
||||
g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip4_address_unref);
|
||||
priv->addresses = nm_utils_ip4_addresses_from_gvalue (value);
|
||||
|
||||
if (g_slist_length (priv->addresses) != g_slist_length (priv->address_labels)) {
|
||||
g_slist_free_full (priv->address_labels, g_free);
|
||||
priv->address_labels = NULL;
|
||||
for (iter = priv->addresses; iter; iter = iter->next)
|
||||
priv->address_labels = g_slist_prepend (priv->address_labels, NULL);
|
||||
}
|
||||
break;
|
||||
case PROP_ADDRESS_LABELS:
|
||||
g_slist_free_full (priv->address_labels, g_free);
|
||||
priv->address_labels = g_value_dup_boxed (value);
|
||||
/* NULLs get converted to "" when this is sent over D-Bus. */
|
||||
for (iter = priv->address_labels; iter; iter = iter->next) {
|
||||
if (!g_strcmp0 (iter->data, "")) {
|
||||
g_free (iter->data);
|
||||
iter->data = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PROP_ROUTES:
|
||||
g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip4_route_unref);
|
||||
|
|
@ -1074,6 +1174,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_ADDRESSES:
|
||||
nm_utils_ip4_addresses_to_gvalue (priv->addresses, value);
|
||||
break;
|
||||
case PROP_ADDRESS_LABELS:
|
||||
g_value_set_boxed (value, priv->address_labels);
|
||||
break;
|
||||
case PROP_ROUTES:
|
||||
nm_utils_ip4_routes_to_gvalue (priv->routes, value);
|
||||
break;
|
||||
|
|
@ -1239,6 +1342,14 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_ADDRESS_LABELS,
|
||||
_nm_param_spec_specialized ("address-labels",
|
||||
"Address labels",
|
||||
"Internal use only",
|
||||
DBUS_TYPE_G_LIST_OF_STRING,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE));
|
||||
|
||||
/**
|
||||
* NMSettingIP4Config:routes:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef NM_SETTING_PRIVATE_H
|
||||
#define NM_SETTING_PRIVATE_H
|
||||
|
||||
#include "nm-setting.h"
|
||||
#include "nm-glib-compat.h"
|
||||
|
||||
#define NM_SETTING_SECRET_FLAGS_ALL \
|
||||
|
|
@ -86,5 +87,10 @@ static void __attribute__((constructor)) register_setting (void) \
|
|||
|
||||
NMSetting *nm_setting_find_in_list (GSList *settings_list, const char *setting_name);
|
||||
|
||||
/* Private NMSettingIP4Config methods */
|
||||
#include "nm-setting-ip4-config.h"
|
||||
const char *nm_setting_ip4_config_get_address_label (NMSettingIP4Config *setting, guint32 i);
|
||||
gboolean nm_setting_ip4_config_add_address_with_label (NMSettingIP4Config *setting, NMIP4Address *address, const char *label);
|
||||
|
||||
#endif /* NM_SETTING_PRIVATE_H */
|
||||
|
||||
|
|
|
|||
44
libnm-util/nm-util-private.c
Normal file
44
libnm-util/nm-util-private.c
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2014 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-util-private.h"
|
||||
|
||||
static const NMUtilPrivateData data = {
|
||||
.nm_setting_ip4_config_get_address_label = nm_setting_ip4_config_get_address_label,
|
||||
.nm_setting_ip4_config_add_address_with_label = nm_setting_ip4_config_add_address_with_label,
|
||||
};
|
||||
|
||||
/**
|
||||
* nm_util_get_private:
|
||||
*
|
||||
* Entry point for NetworkManager-internal API. Although this symbol is exported,
|
||||
* it is only useful if you have access to "nm-util-private.h", which is only
|
||||
* available inside the NetworkManager tree.
|
||||
*
|
||||
* Return value: Who knows? It's a mystery.
|
||||
*
|
||||
* Since: 0.9.10
|
||||
*/
|
||||
const NMUtilPrivateData *
|
||||
nm_util_get_private (void)
|
||||
{
|
||||
return &data;
|
||||
}
|
||||
60
libnm-util/nm-util-private.h
Normal file
60
libnm-util/nm-util-private.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2014 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_UTIL_PRIVATE_H__
|
||||
#define __NM_UTIL_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "nm-setting-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct NMUtilPrivateData {
|
||||
const char * (*nm_setting_ip4_config_get_address_label) (NMSettingIP4Config *setting,
|
||||
guint32 i);
|
||||
gboolean (*nm_setting_ip4_config_add_address_with_label) (NMSettingIP4Config *setting,
|
||||
NMIP4Address *address,
|
||||
const char *label);
|
||||
} NMUtilPrivateData;
|
||||
|
||||
const NMUtilPrivateData *nm_util_get_private (void);
|
||||
|
||||
|
||||
/**
|
||||
* NM_UTIL_PRIVATE_CALL:
|
||||
* @call: a call to a private libnm-util function
|
||||
*
|
||||
* Used to call private libnm-util functions. Eg, if there was a
|
||||
* private function called nm_foo_get_bar(), you could call it like:
|
||||
*
|
||||
* bar = NM_UTIL_PRIVATE_CALL (nm_foo_get_bar (foo, x, y, z));
|
||||
*
|
||||
* This macro only exists inside the NetworkManager source tree and
|
||||
* is not part of the public API.
|
||||
*
|
||||
* Since: 0.9.10
|
||||
*/
|
||||
#define NM_UTIL_PRIVATE_CALL(call) (nm_util_get_private ()->call)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -42,6 +42,7 @@
|
|||
#include "nm-setting-vlan.h"
|
||||
#include "nm-setting-bond.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-util-private.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
#include "nm-glib-compat.h"
|
||||
|
||||
|
|
@ -272,6 +273,153 @@ test_setting_vpn_modify_during_foreach (void)
|
|||
g_object_unref (s_vpn);
|
||||
}
|
||||
|
||||
static void
|
||||
test_setting_ip4_config_labels (void)
|
||||
{
|
||||
NMSettingIP4Config *s_ip4;
|
||||
NMIP4Address *addr;
|
||||
const char *label;
|
||||
GPtrArray *addrs;
|
||||
GSList *labels;
|
||||
GError *error = NULL;
|
||||
|
||||
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
|
||||
g_object_set (G_OBJECT (s_ip4),
|
||||
NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
|
||||
NULL);
|
||||
|
||||
/* addr 1 */
|
||||
addr = nm_ip4_address_new ();
|
||||
nm_ip4_address_set_address (addr, 0x01010101);
|
||||
nm_ip4_address_set_prefix (addr, 24);
|
||||
|
||||
nm_setting_ip4_config_add_address (s_ip4, addr);
|
||||
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
|
||||
g_assert_cmpstr (label, ==, NULL);
|
||||
|
||||
/* addr 2 */
|
||||
addr = nm_ip4_address_new ();
|
||||
nm_ip4_address_set_address (addr, 0x02020202);
|
||||
nm_ip4_address_set_prefix (addr, 24);
|
||||
|
||||
NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, "eth0:1"));
|
||||
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
|
||||
g_assert_cmpstr (label, ==, "eth0:1");
|
||||
|
||||
/* addr 3 */
|
||||
addr = nm_ip4_address_new ();
|
||||
nm_ip4_address_set_address (addr, 0x03030303);
|
||||
nm_ip4_address_set_prefix (addr, 24);
|
||||
|
||||
NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, NULL));
|
||||
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 2));
|
||||
g_assert_cmpstr (label, ==, NULL);
|
||||
|
||||
/* Remove addr 1 and re-verify remaining addresses */
|
||||
nm_setting_ip4_config_remove_address (s_ip4, 0);
|
||||
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, 0);
|
||||
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x02020202);
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
|
||||
g_assert_cmpstr (label, ==, "eth0:1");
|
||||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, 1);
|
||||
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x03030303);
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
|
||||
g_assert_cmpstr (label, ==, NULL);
|
||||
|
||||
|
||||
/* Test explicit property assignment */
|
||||
g_object_get (G_OBJECT (s_ip4),
|
||||
NM_SETTING_IP4_CONFIG_ADDRESSES, &addrs,
|
||||
"address-labels", &labels,
|
||||
NULL);
|
||||
|
||||
nm_setting_ip4_config_clear_addresses (s_ip4);
|
||||
g_assert_cmpint (nm_setting_ip4_config_get_num_addresses (s_ip4), ==, 0);
|
||||
|
||||
/* Setting addrs but not labels will result in empty labels */
|
||||
g_object_set (G_OBJECT (s_ip4),
|
||||
NM_SETTING_IP4_CONFIG_ADDRESSES, addrs,
|
||||
NULL);
|
||||
g_boxed_free (DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, addrs);
|
||||
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (nm_setting_ip4_config_get_num_addresses (s_ip4), ==, 2);
|
||||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, 0);
|
||||
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x02020202);
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
|
||||
g_assert_cmpstr (label, ==, NULL);
|
||||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, 1);
|
||||
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x03030303);
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
|
||||
g_assert_cmpstr (label, ==, NULL);
|
||||
|
||||
/* Setting labels now will leave addresses untouched */
|
||||
g_object_set (G_OBJECT (s_ip4),
|
||||
"address-labels", labels,
|
||||
NULL);
|
||||
g_boxed_free (DBUS_TYPE_G_LIST_OF_STRING, labels);
|
||||
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (nm_setting_ip4_config_get_num_addresses (s_ip4), ==, 2);
|
||||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, 0);
|
||||
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x02020202);
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0));
|
||||
g_assert_cmpstr (label, ==, "eth0:1");
|
||||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, 1);
|
||||
g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x03030303);
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1));
|
||||
g_assert_cmpstr (label, ==, NULL);
|
||||
|
||||
/* Setting labels to a value that's too short or too long will result in
|
||||
* the setting not verifying.
|
||||
*/
|
||||
labels = g_slist_append (NULL, "eth0:2");
|
||||
g_object_set (G_OBJECT (s_ip4),
|
||||
"address-labels", labels,
|
||||
NULL);
|
||||
|
||||
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
|
||||
g_assert_error (error, NM_SETTING_IP4_CONFIG_ERROR, NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY);
|
||||
g_assert (g_str_has_prefix (error->message, "ipv4.address-labels:"));
|
||||
g_clear_error (&error);
|
||||
|
||||
labels = g_slist_append (labels, "eth0:3");
|
||||
g_object_set (G_OBJECT (s_ip4),
|
||||
"address-labels", labels,
|
||||
NULL);
|
||||
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
labels = g_slist_append (labels, "eth0:4");
|
||||
g_object_set (G_OBJECT (s_ip4),
|
||||
"address-labels", labels,
|
||||
NULL);
|
||||
nm_setting_verify (NM_SETTING (s_ip4), NULL, &error);
|
||||
g_assert_error (error, NM_SETTING_IP4_CONFIG_ERROR, NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY);
|
||||
g_assert (g_str_has_prefix (error->message, "ipv4.address-labels:"));
|
||||
g_clear_error (&error);
|
||||
|
||||
|
||||
g_object_unref (s_ip4);
|
||||
}
|
||||
|
||||
#define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
|
||||
#define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS))
|
||||
|
||||
|
|
@ -1197,6 +1345,7 @@ test_connection_diff_a_only (void)
|
|||
{ NM_SETTING_IP4_CONFIG_DNS, NM_SETTING_DIFF_RESULT_IN_A },
|
||||
{ NM_SETTING_IP4_CONFIG_DNS_SEARCH, NM_SETTING_DIFF_RESULT_IN_A },
|
||||
{ NM_SETTING_IP4_CONFIG_ADDRESSES, NM_SETTING_DIFF_RESULT_IN_A },
|
||||
{ "address-labels", NM_SETTING_DIFF_RESULT_IN_A },
|
||||
{ NM_SETTING_IP4_CONFIG_ROUTES, NM_SETTING_DIFF_RESULT_IN_A },
|
||||
{ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, NM_SETTING_DIFF_RESULT_IN_A },
|
||||
{ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, NM_SETTING_DIFF_RESULT_IN_A },
|
||||
|
|
@ -2232,6 +2381,7 @@ int main (int argc, char **argv)
|
|||
test_setting_vpn_items ();
|
||||
test_setting_vpn_update_secrets ();
|
||||
test_setting_vpn_modify_during_foreach ();
|
||||
test_setting_ip4_config_labels ();
|
||||
test_setting_ip6_config_old_address_array ();
|
||||
test_setting_gsm_apn_spaces ();
|
||||
test_setting_gsm_apn_bad_chars ();
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "nm-dbus-glib-types.h"
|
||||
#include "nm-ip4-config-glue.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
#include "nm-util-private.h"
|
||||
|
||||
G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, G_TYPE_OBJECT)
|
||||
|
||||
|
|
@ -333,6 +333,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting)
|
|||
/* Addresses */
|
||||
for (i = 0; i < naddresses; i++) {
|
||||
NMIP4Address *s_addr = nm_setting_ip4_config_get_address (setting, i);
|
||||
const char *label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (setting, i));
|
||||
NMPlatformIP4Address address;
|
||||
|
||||
memset (&address, 0, sizeof (address));
|
||||
|
|
@ -341,6 +342,8 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting)
|
|||
address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
|
||||
address.preferred = NM_PLATFORM_LIFETIME_PERMANENT;
|
||||
address.source = NM_PLATFORM_SOURCE_USER;
|
||||
if (label)
|
||||
g_strlcpy (address.label, label, sizeof (address.label));
|
||||
|
||||
nm_ip4_config_add_address (config, &address);
|
||||
}
|
||||
|
|
@ -418,7 +421,10 @@ nm_ip4_config_update_setting (const NMIP4Config *config, NMSettingIP4Config *set
|
|||
if (same_prefix (address->address, gateway, address->plen))
|
||||
nm_ip4_address_set_gateway (s_addr, gateway);
|
||||
|
||||
nm_setting_ip4_config_add_address (setting, s_addr);
|
||||
if (*address->label)
|
||||
NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (setting, s_addr, address->label));
|
||||
else
|
||||
nm_setting_ip4_config_add_address (setting, s_addr);
|
||||
nm_ip4_address_unref (s_addr);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -738,7 +738,8 @@ ip6_address_get_all (NMPlatform *platform, int ifindex)
|
|||
static gboolean
|
||||
ip4_address_add (NMPlatform *platform, int ifindex,
|
||||
in_addr_t addr, in_addr_t peer_addr,
|
||||
int plen, guint32 lifetime, guint32 preferred)
|
||||
int plen, guint32 lifetime, guint32 preferred,
|
||||
const char *label)
|
||||
{
|
||||
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
|
||||
NMPlatformIP4Address address;
|
||||
|
|
@ -752,6 +753,8 @@ ip4_address_add (NMPlatform *platform, int ifindex,
|
|||
address.timestamp = nm_utils_get_monotonic_timestamp_s ();
|
||||
address.lifetime = lifetime;
|
||||
address.preferred = preferred;
|
||||
if (label)
|
||||
g_strlcpy (address.label, label, sizeof (address.label));
|
||||
|
||||
for (i = 0; i < priv->ip4_addresses->len; i++) {
|
||||
NMPlatformIP4Address *item = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i);
|
||||
|
|
|
|||
|
|
@ -868,6 +868,7 @@ init_ip4_address (NMPlatformIP4Address *address, struct rtnl_addr *rtnladdr)
|
|||
{
|
||||
struct nl_addr *nladdr = rtnl_addr_get_local (rtnladdr);
|
||||
struct nl_addr *nlpeer = rtnl_addr_get_peer (rtnladdr);
|
||||
const char *label;
|
||||
|
||||
g_return_val_if_fail (nladdr, FALSE);
|
||||
|
||||
|
|
@ -890,6 +891,9 @@ init_ip4_address (NMPlatformIP4Address *address, struct rtnl_addr *rtnladdr)
|
|||
}
|
||||
memcpy (&address->peer_address, nl_addr_get_binary_addr (nlpeer), sizeof (address->peer_address));
|
||||
}
|
||||
label = rtnl_addr_get_label (rtnladdr);
|
||||
if (label && *label)
|
||||
g_strlcpy (address->label, label, sizeof (address->label));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -2783,7 +2787,8 @@ build_rtnl_addr (int family,
|
|||
int plen,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
guint flags)
|
||||
guint flags,
|
||||
const char *label)
|
||||
{
|
||||
struct rtnl_addr *rtnladdr = rtnl_addr_alloc ();
|
||||
int addrlen = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr);
|
||||
|
|
@ -2824,6 +2829,8 @@ build_rtnl_addr (int family,
|
|||
}
|
||||
if (flags)
|
||||
rtnl_addr_set_flags (rtnladdr, flags);
|
||||
if (label && *label)
|
||||
rtnl_addr_set_label (rtnladdr, label);
|
||||
|
||||
return (struct nl_object *) rtnladdr;
|
||||
}
|
||||
|
|
@ -2835,11 +2842,13 @@ ip4_address_add (NMPlatform *platform,
|
|||
in_addr_t peer_addr,
|
||||
int plen,
|
||||
guint32 lifetime,
|
||||
guint32 preferred)
|
||||
guint32 preferred,
|
||||
const char *label)
|
||||
{
|
||||
return add_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr,
|
||||
peer_addr ? &peer_addr : NULL,
|
||||
plen, lifetime, preferred, 0));
|
||||
plen, lifetime, preferred, 0,
|
||||
label));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -2854,25 +2863,26 @@ ip6_address_add (NMPlatform *platform,
|
|||
{
|
||||
return add_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr,
|
||||
IN6_IS_ADDR_UNSPECIFIED (&peer_addr) ? NULL : &peer_addr,
|
||||
plen, lifetime, preferred, flags));
|
||||
plen, lifetime, preferred, flags,
|
||||
NULL));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen)
|
||||
{
|
||||
return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, NULL, plen, 0, 0, 0));
|
||||
return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, NULL, plen, 0, 0, 0, NULL));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen)
|
||||
{
|
||||
return delete_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, NULL, plen, 0, 0, 0));
|
||||
return delete_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, NULL, plen, 0, 0, 0, NULL));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ip_address_exists (NMPlatform *platform, int family, int ifindex, gconstpointer addr, int plen)
|
||||
{
|
||||
auto_nl_object struct nl_object *object = build_rtnl_addr (family, ifindex, addr, NULL, plen, 0, 0, 0);
|
||||
auto_nl_object struct nl_object *object = build_rtnl_addr (family, ifindex, addr, NULL, plen, 0, 0, 0, NULL);
|
||||
auto_nl_object struct nl_object *cached_object = nl_cache_search (choose_cache (platform, object), object);
|
||||
|
||||
return !!cached_object;
|
||||
|
|
|
|||
|
|
@ -1230,7 +1230,8 @@ nm_platform_ip4_address_add (int ifindex,
|
|||
in_addr_t peer_address,
|
||||
int plen,
|
||||
guint32 lifetime,
|
||||
guint32 preferred)
|
||||
guint32 preferred,
|
||||
const char *label)
|
||||
{
|
||||
reset_error ();
|
||||
|
||||
|
|
@ -1238,6 +1239,7 @@ nm_platform_ip4_address_add (int ifindex,
|
|||
g_return_val_if_fail (plen > 0, FALSE);
|
||||
g_return_val_if_fail (lifetime > 0, FALSE);
|
||||
g_return_val_if_fail (klass->ip4_address_add, FALSE);
|
||||
g_return_val_if_fail (!label || strlen (label) < sizeof (((NMPlatformIP4Address *) NULL)->label), FALSE);
|
||||
|
||||
if (nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) {
|
||||
NMPlatformIP4Address addr = { 0 };
|
||||
|
|
@ -1248,10 +1250,12 @@ nm_platform_ip4_address_add (int ifindex,
|
|||
addr.plen = plen;
|
||||
addr.lifetime = lifetime;
|
||||
addr.preferred = preferred;
|
||||
if (label)
|
||||
g_strlcpy (addr.label, label, sizeof (addr.label));
|
||||
|
||||
debug ("address: adding or updating IPv4 address: %s", nm_platform_ip4_address_to_string (&addr));
|
||||
}
|
||||
return klass->ip4_address_add (platform, ifindex, address, peer_address, plen, lifetime, preferred);
|
||||
return klass->ip4_address_add (platform, ifindex, address, peer_address, plen, lifetime, preferred, label);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
@ -1422,7 +1426,7 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses)
|
|||
} else
|
||||
lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT;
|
||||
|
||||
if (!nm_platform_ip4_address_add (ifindex, known_address->address, known_address->peer_address, known_address->plen, lifetime, preferred))
|
||||
if (!nm_platform_ip4_address_add (ifindex, known_address->address, known_address->peer_address, known_address->plen, lifetime, preferred, known_address->label))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -1914,6 +1918,7 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address)
|
|||
char s_address[INET_ADDRSTRLEN];
|
||||
char s_peer[INET_ADDRSTRLEN];
|
||||
char str_dev[TO_STRING_DEV_BUF_SIZE];
|
||||
char str_label[32];
|
||||
char *str_peer = NULL;
|
||||
|
||||
g_return_val_if_fail (address, "(unknown)");
|
||||
|
|
@ -1927,11 +1932,17 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address)
|
|||
|
||||
_to_string_dev (address->ifindex, str_dev, sizeof (str_dev));
|
||||
|
||||
g_snprintf (to_string_buffer, sizeof (to_string_buffer), "%s/%d lft %u pref %u time %u%s%s src %s",
|
||||
if (*address->label)
|
||||
g_snprintf (str_label, sizeof (str_label), " label %s", address->label);
|
||||
else
|
||||
str_label[0] = 0;
|
||||
|
||||
g_snprintf (to_string_buffer, sizeof (to_string_buffer), "%s/%d lft %u pref %u time %u%s%s%s src %s",
|
||||
s_address, address->plen, (guint)address->lifetime, (guint)address->preferred,
|
||||
(guint)address->timestamp,
|
||||
str_peer ? str_peer : "",
|
||||
str_dev,
|
||||
str_label,
|
||||
source_to_string (address->source));
|
||||
g_free (str_peer);
|
||||
return to_string_buffer;
|
||||
|
|
@ -2092,6 +2103,13 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route)
|
|||
return (((a)->field) < ((b)->field)) ? -1 : 1; \
|
||||
} G_STMT_END
|
||||
|
||||
#define _CMP_FIELD_STR(a, b, field) \
|
||||
G_STMT_START { \
|
||||
int c = strcmp ((a)->field, (b)->field); \
|
||||
if (c != 0) \
|
||||
return c < 0 ? -1 : 1; \
|
||||
} G_STMT_END
|
||||
|
||||
#define _CMP_FIELD_MEMCMP(a, b, field) \
|
||||
G_STMT_START { \
|
||||
int c = memcmp (&((a)->field), &((b)->field), \
|
||||
|
|
@ -2112,6 +2130,7 @@ nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4A
|
|||
_CMP_FIELD (a, b, timestamp);
|
||||
_CMP_FIELD (a, b, lifetime);
|
||||
_CMP_FIELD (a, b, preferred);
|
||||
_CMP_FIELD_STR (a, b, label);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ typedef struct {
|
|||
guint32 timestamp;
|
||||
guint32 lifetime; /* seconds */
|
||||
guint32 preferred; /* seconds */
|
||||
char label[IFNAMSIZ];
|
||||
} NMPlatformIP4Address;
|
||||
|
||||
/**
|
||||
|
|
@ -346,7 +347,8 @@ typedef struct {
|
|||
GArray * (*ip6_address_get_all) (NMPlatform *, int ifindex);
|
||||
gboolean (*ip4_address_add) (NMPlatform *, int ifindex,
|
||||
in_addr_t address, in_addr_t peer_address, int plen,
|
||||
guint32 lifetime, guint32 preferred_lft);
|
||||
guint32 lifetime, guint32 preferred_lft,
|
||||
const char *label);
|
||||
gboolean (*ip6_address_add) (NMPlatform *, int ifindex,
|
||||
struct in6_addr address, struct in6_addr peer_address, int plen,
|
||||
guint32 lifetime, guint32 preferred_lft, guint flags);
|
||||
|
|
@ -475,7 +477,8 @@ GArray *nm_platform_ip4_address_get_all (int ifindex);
|
|||
GArray *nm_platform_ip6_address_get_all (int ifindex);
|
||||
gboolean nm_platform_ip4_address_add (int ifindex,
|
||||
in_addr_t address, in_addr_t peer_address, int plen,
|
||||
guint32 lifetime, guint32 preferred_lft);
|
||||
guint32 lifetime, guint32 preferred_lft,
|
||||
const char *label);
|
||||
gboolean nm_platform_ip6_address_add (int ifindex,
|
||||
struct in6_addr address, struct in6_addr peer_address, int plen,
|
||||
guint32 lifetime, guint32 preferred_lft, guint flags);
|
||||
|
|
|
|||
|
|
@ -570,7 +570,7 @@ do_ip4_address_add (char **argv)
|
|||
guint32 lifetime = strtol (*argv++, NULL, 10);
|
||||
guint32 preferred = strtol (*argv++, NULL, 10);
|
||||
|
||||
gboolean value = nm_platform_ip4_address_add (ifindex, address, 0, plen, lifetime, preferred);
|
||||
gboolean value = nm_platform_ip4_address_add (ifindex, address, 0, plen, lifetime, preferred, NULL);
|
||||
return value;
|
||||
} else
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -60,14 +60,14 @@ test_ip4_address (void)
|
|||
/* Add address */
|
||||
g_assert (!nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN));
|
||||
no_error ();
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred));
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred, NULL));
|
||||
no_error ();
|
||||
g_assert (nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN));
|
||||
no_error ();
|
||||
accept_signal (address_added);
|
||||
|
||||
/* Add address again (aka update) */
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred));
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred, NULL));
|
||||
no_error ();
|
||||
accept_signal (address_changed);
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ test_ip4_address_external (void)
|
|||
/* Add/delete conflict */
|
||||
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
|
||||
IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred);
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred));
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred, NULL));
|
||||
no_error ();
|
||||
g_assert (nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN));
|
||||
accept_signal (address_added);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ test_cleanup_internal ()
|
|||
g_assert (ifindex > 0);
|
||||
|
||||
/* Add routes and addresses */
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr4, 0, plen4, lifetime, preferred));
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr4, 0, plen4, lifetime, preferred, NULL));
|
||||
g_assert (nm_platform_ip6_address_add (ifindex, addr6, in6addr_any, plen6, lifetime, preferred, flags));
|
||||
g_assert (nm_platform_ip4_route_add (ifindex, gateway4, 32, INADDR_ANY, metric, mss));
|
||||
g_assert (nm_platform_ip4_route_add (ifindex, network4, plen4, gateway4, metric, mss));
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ ifcfg_dir_changed (GFileMonitor *monitor,
|
|||
gpointer user_data)
|
||||
{
|
||||
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data);
|
||||
char *path, *ifcfg_path;
|
||||
char *path, *base, *ifcfg_path;
|
||||
NMIfcfgConnection *connection;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
|
|
@ -386,8 +386,14 @@ ifcfg_dir_changed (GFileMonitor *monitor,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Given any ifcfg, keys, or routes file, get the ifcfg file path */
|
||||
ifcfg_path = utils_get_ifcfg_path (path);
|
||||
base = g_file_get_basename (file);
|
||||
if (utils_is_ifcfg_alias_file (base, NULL)) {
|
||||
/* Alias file changed. Get the base ifcfg file from it */
|
||||
ifcfg_path = utils_get_ifcfg_from_alias (path);
|
||||
} else {
|
||||
/* Given any ifcfg, keys, or routes file, get the ifcfg file path */
|
||||
ifcfg_path = utils_get_ifcfg_path (path);
|
||||
}
|
||||
if (ifcfg_path) {
|
||||
connection = find_by_path (plugin, ifcfg_path);
|
||||
switch (event_type) {
|
||||
|
|
@ -407,6 +413,7 @@ ifcfg_dir_changed (GFileMonitor *monitor,
|
|||
g_free (ifcfg_path);
|
||||
}
|
||||
g_free (path);
|
||||
g_free (base);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -459,6 +466,8 @@ read_connections (SCPluginIfcfg *plugin)
|
|||
|
||||
if (utils_should_ignore_file (item, TRUE))
|
||||
continue;
|
||||
if (utils_is_ifcfg_alias_file (item, NULL))
|
||||
continue;
|
||||
|
||||
full_path = g_build_filename (IFCFG_DIR, item, NULL);
|
||||
if (!utils_get_ifcfg_name (full_path, TRUE))
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include <nm-setting-bridge-port.h>
|
||||
#include <nm-setting-dcb.h>
|
||||
#include <nm-setting-generic.h>
|
||||
#include <nm-util-private.h>
|
||||
#include <nm-utils.h>
|
||||
|
||||
#include "wifi-utils.h"
|
||||
|
|
@ -641,10 +642,9 @@ static gboolean
|
|||
read_full_ip4_address (shvarFile *ifcfg,
|
||||
const char *network_file,
|
||||
gint32 which,
|
||||
NMIP4Address **out_address,
|
||||
NMIP4Address *addr,
|
||||
GError **error)
|
||||
{
|
||||
NMIP4Address *addr;
|
||||
char *ip_tag, *prefix_tag, *netmask_tag, *gw_tag;
|
||||
guint32 tmp;
|
||||
gboolean success = FALSE;
|
||||
|
|
@ -654,12 +654,10 @@ read_full_ip4_address (shvarFile *ifcfg,
|
|||
g_return_val_if_fail (which >= -1, FALSE);
|
||||
g_return_val_if_fail (ifcfg != NULL, FALSE);
|
||||
g_return_val_if_fail (network_file != NULL, FALSE);
|
||||
g_return_val_if_fail (out_address != NULL, FALSE);
|
||||
g_return_val_if_fail (*out_address == NULL, FALSE);
|
||||
g_return_val_if_fail (addr != NULL, FALSE);
|
||||
if (error)
|
||||
g_return_val_if_fail (*error == NULL, FALSE);
|
||||
|
||||
addr = nm_ip4_address_new ();
|
||||
ip_tag = get_numbered_tag ("IPADDR", which);
|
||||
prefix_tag = get_numbered_tag ("PREFIX", which);
|
||||
netmask_tag = get_numbered_tag ("NETMASK", which);
|
||||
|
|
@ -668,13 +666,12 @@ read_full_ip4_address (shvarFile *ifcfg,
|
|||
/* IP address */
|
||||
if (!read_ip4_address (ifcfg, ip_tag, &tmp, error))
|
||||
goto done;
|
||||
if (!tmp) {
|
||||
nm_ip4_address_unref (addr);
|
||||
addr = NULL;
|
||||
success = TRUE; /* done */
|
||||
if (tmp)
|
||||
nm_ip4_address_set_address (addr, tmp);
|
||||
else if (!nm_ip4_address_get_address (addr)) {
|
||||
success = TRUE;
|
||||
goto done;
|
||||
}
|
||||
nm_ip4_address_set_address (addr, tmp);
|
||||
|
||||
/* Gateway */
|
||||
if (!read_ip4_address (ifcfg, gw_tag, &tmp, error))
|
||||
|
|
@ -741,13 +738,9 @@ read_full_ip4_address (shvarFile *ifcfg,
|
|||
goto done;
|
||||
}
|
||||
|
||||
*out_address = addr;
|
||||
success = TRUE;
|
||||
|
||||
done:
|
||||
if (!success && addr)
|
||||
nm_ip4_address_unref (addr);
|
||||
|
||||
g_free (ip_tag);
|
||||
g_free (prefix_tag);
|
||||
g_free (netmask_tag);
|
||||
|
|
@ -1387,9 +1380,12 @@ make_ip4_setting (shvarFile *ifcfg,
|
|||
for (i = -1; i < 256; i++) {
|
||||
NMIP4Address *addr = NULL;
|
||||
|
||||
if (!read_full_ip4_address (ifcfg, network_file, i, &addr, error))
|
||||
addr = nm_ip4_address_new ();
|
||||
if (!read_full_ip4_address (ifcfg, network_file, i, addr, error))
|
||||
goto done;
|
||||
if (!addr) {
|
||||
if (!nm_ip4_address_get_address (addr)) {
|
||||
nm_ip4_address_unref (addr);
|
||||
|
||||
/* The first mandatory variable is 2-indexed (IPADDR2)
|
||||
* Variables IPADDR, IPADDR0 and IPADDR1 are optional */
|
||||
if (i > 1)
|
||||
|
|
@ -1516,6 +1512,101 @@ done:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
read_aliases (NMSettingIP4Config *s_ip4, const char *filename, const char *network_file)
|
||||
{
|
||||
GDir *dir;
|
||||
char *dirname, *base;
|
||||
shvarFile *parsed;
|
||||
NMIP4Address *base_addr;
|
||||
GError *err = NULL;
|
||||
|
||||
g_return_if_fail (s_ip4 != NULL);
|
||||
g_return_if_fail (filename != NULL);
|
||||
|
||||
base_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
|
||||
if (!base_addr)
|
||||
return;
|
||||
|
||||
dirname = g_path_get_dirname (filename);
|
||||
g_return_if_fail (dirname != NULL);
|
||||
base = g_path_get_basename (filename);
|
||||
g_return_if_fail (base != NULL);
|
||||
|
||||
dir = g_dir_open (dirname, 0, &err);
|
||||
if (dir) {
|
||||
const char *item;
|
||||
NMIP4Address *addr;
|
||||
gboolean ok;
|
||||
|
||||
while ((item = g_dir_read_name (dir))) {
|
||||
char *full_path, *device;
|
||||
const char *p;
|
||||
|
||||
if (!utils_is_ifcfg_alias_file (item, base))
|
||||
continue;
|
||||
|
||||
full_path = g_build_filename (dirname, item, NULL);
|
||||
|
||||
p = strchr (item, ':');
|
||||
g_assert (p != NULL); /* we know this is true from utils_is_ifcfg_alias_file() */
|
||||
for (p++; *p; p++) {
|
||||
if (!g_ascii_isalnum (*p) && *p != '_') {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " alias: ignoring alias file '%s' with invalid name", full_path);
|
||||
g_free (full_path);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
parsed = svNewFile (full_path);
|
||||
if (!parsed) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " alias: couldn't parse file '%s'", full_path);
|
||||
g_free (full_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
device = svGetValue (parsed, "DEVICE", FALSE);
|
||||
if (!device) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " alias: file '%s' has no DEVICE", full_path);
|
||||
svCloseFile (parsed);
|
||||
g_free (full_path);
|
||||
continue;
|
||||
}
|
||||
/* We know that item starts with IFCFG_TAG from utils_is_ifcfg_alias_file() */
|
||||
if (strcmp (device, item + strlen (IFCFG_TAG)) != 0) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " alias: file '%s' has invalid DEVICE (%s) for filename", full_path, device);
|
||||
g_free (device);
|
||||
svCloseFile (parsed);
|
||||
g_free (full_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
addr = nm_ip4_address_dup (base_addr);
|
||||
ok = read_full_ip4_address (parsed, network_file, -1, addr, &err);
|
||||
svCloseFile (parsed);
|
||||
if (ok) {
|
||||
if (!NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, device)))
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " alias: duplicate IP4 address in alias file %s", item);
|
||||
} else {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " alias: error reading IP4 address from '%s': %s", full_path, err ? err->message : "no address")
|
||||
g_clear_error (&err);
|
||||
}
|
||||
nm_ip4_address_unref (addr);
|
||||
|
||||
g_free (device);
|
||||
g_free (full_path);
|
||||
}
|
||||
|
||||
g_dir_close (dir);
|
||||
} else {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " alias: can not read directory '%s': %s", dirname, err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
|
||||
g_free (base);
|
||||
g_free (dirname);
|
||||
}
|
||||
|
||||
static NMSetting *
|
||||
make_ip6_setting (shvarFile *ifcfg,
|
||||
const char *network_file,
|
||||
|
|
@ -5106,8 +5197,10 @@ connection_from_file (const char *filename,
|
|||
g_object_unref (connection);
|
||||
connection = NULL;
|
||||
goto done;
|
||||
} else
|
||||
} else {
|
||||
read_aliases (NM_SETTING_IP4_CONFIG (s_ip4), filename, network_file);
|
||||
nm_connection_add_setting (connection, s_ip4);
|
||||
}
|
||||
|
||||
/* There is only one DOMAIN variable and it is read and put to IPv4 config
|
||||
* But if IPv4 is disabled or the config fails for some reason, we read
|
||||
|
|
|
|||
|
|
@ -117,8 +117,24 @@ EXTRA_DIST = \
|
|||
ifcfg-test-team-port \
|
||||
ifcfg-test-team-port-empty-config
|
||||
|
||||
# make target dependencies can't have colons in their names, which ends up
|
||||
# meaning that we can't add the alias files to EXTRA_DIST
|
||||
ALIAS_FILES = \
|
||||
ifcfg-aliasem0 \
|
||||
ifcfg-aliasem0:1 \
|
||||
ifcfg-aliasem0:2 \
|
||||
ifcfg-aliasem0:99 \
|
||||
ifcfg-aliasem1 \
|
||||
ifcfg-aliasem1:1 \
|
||||
ifcfg-aliasem1:2
|
||||
|
||||
dist-hook:
|
||||
@for f in $(ALIAS_FILES); do \
|
||||
cp $(abs_srcdir)/$$f $(distdir)/; \
|
||||
done
|
||||
|
||||
check-local:
|
||||
@for f in $(EXTRA_DIST); do \
|
||||
@for f in $(EXTRA_DIST) $(ALIAS_FILES); do \
|
||||
chmod 0600 $(abs_srcdir)/$$f; \
|
||||
done
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=aliasem0
|
||||
HWADDR=00:11:22:33:44:55
|
||||
BOOTPROTO=none
|
||||
ONBOOT=yes
|
||||
DNS1=4.2.2.1
|
||||
DNS2=4.2.2.2
|
||||
IPADDR=192.168.1.5
|
||||
PREFIX=24
|
||||
NETMASK=255.255.255.0
|
||||
GATEWAY=192.168.1.1
|
||||
IPV6INIT=no
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
DEVICE=aliasem0:1
|
||||
IPADDR=192.168.1.6
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
DEVICE=aliasem0:2
|
||||
IPADDR=192.168.1.9
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
DEVICE=aliasem0:99
|
||||
IPADDR=192.168.1.99
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=aliasem1
|
||||
HWADDR=00:11:22:33:44:55
|
||||
BOOTPROTO=none
|
||||
ONBOOT=yes
|
||||
DNS1=4.2.2.1
|
||||
DNS2=4.2.2.2
|
||||
IPADDR=192.168.1.5
|
||||
PREFIX=24
|
||||
NETMASK=255.255.255.0
|
||||
GATEWAY=192.168.1.1
|
||||
IPV6INIT=no
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# bad, no DEVICE
|
||||
IPADDR=192.168.1.12
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# bad: wrong DEVICE
|
||||
DEVICE=aliasem0:2
|
||||
IPADDR=192.168.1.20
|
||||
|
|
@ -46,6 +46,7 @@
|
|||
#include <nm-setting-serial.h>
|
||||
#include <nm-setting-vlan.h>
|
||||
#include <nm-setting-dcb.h>
|
||||
#include <nm-util-private.h>
|
||||
|
||||
#include "nm-test-helpers.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
|
@ -2829,6 +2830,271 @@ test_read_write_802_1X_subj_matches (void)
|
|||
g_object_unref (reread);
|
||||
}
|
||||
|
||||
#define TEST_IFCFG_ALIASES_GOOD TEST_IFCFG_DIR"/network-scripts/ifcfg-aliasem0"
|
||||
|
||||
static void
|
||||
test_read_wired_aliases_good (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
char *unmanaged = NULL;
|
||||
char *keyfile = NULL;
|
||||
char *routefile = NULL;
|
||||
char *route6file = NULL;
|
||||
gboolean ignore_error = FALSE;
|
||||
GError *error = NULL;
|
||||
const char *tmp;
|
||||
const char *expected_id = "System aliasem0";
|
||||
int expected_num_addresses = 4, expected_prefix = 24;
|
||||
const char *expected_address[4] = { "192.168.1.5", "192.168.1.6", "192.168.1.9", "192.168.1.99" };
|
||||
const char *expected_label[4] = { NULL, "aliasem0:1", "aliasem0:2", "aliasem0:99" };
|
||||
const char *expected_gateway[4] = { "192.168.1.1", "192.168.1.1", "192.168.1.1", "192.168.1.1" };
|
||||
int i, j;
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_ALIASES_GOOD,
|
||||
NULL,
|
||||
TYPE_ETHERNET,
|
||||
NULL,
|
||||
&unmanaged,
|
||||
&keyfile,
|
||||
&routefile,
|
||||
&route6file,
|
||||
&error,
|
||||
&ignore_error);
|
||||
ASSERT (connection != NULL,
|
||||
"aliases-good-read", "failed to read %s: %s", TEST_IFCFG_ALIASES_GOOD, error->message);
|
||||
|
||||
ASSERT (nm_connection_verify (connection, &error),
|
||||
"aliases-good-verify", "failed to verify %s: %s", TEST_IFCFG_ALIASES_GOOD, error->message);
|
||||
|
||||
/* ===== CONNECTION SETTING ===== */
|
||||
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
ASSERT (s_con != NULL,
|
||||
"aliases-good-verify-connection", "failed to verify %s: missing %s setting",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
NM_SETTING_CONNECTION_SETTING_NAME);
|
||||
|
||||
/* ID */
|
||||
tmp = nm_setting_connection_get_id (s_con);
|
||||
ASSERT (tmp != NULL,
|
||||
"aliases-good-verify-connection", "failed to verify %s: missing %s / %s key",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
NM_SETTING_CONNECTION_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_ID);
|
||||
ASSERT (strcmp (tmp, expected_id) == 0,
|
||||
"aliases-good-verify-connection", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
NM_SETTING_CONNECTION_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_ID);
|
||||
|
||||
/* ===== IPv4 SETTING ===== */
|
||||
|
||||
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
||||
ASSERT (s_ip4 != NULL,
|
||||
"aliases-good-verify-ip4", "failed to verify %s: missing %s setting",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME);
|
||||
|
||||
/* Method */
|
||||
tmp = nm_setting_ip4_config_get_method (s_ip4);
|
||||
ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
|
||||
"aliases-good-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_METHOD);
|
||||
|
||||
ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == expected_num_addresses,
|
||||
"aliases-good-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_ADDRESSES);
|
||||
|
||||
/* Addresses */
|
||||
for (i = 0; i < expected_num_addresses; i++) {
|
||||
NMIP4Address *ip4_addr;
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
struct in_addr addr;
|
||||
|
||||
ip4_addr = nm_setting_ip4_config_get_address (s_ip4, i);
|
||||
ASSERT (ip4_addr,
|
||||
"aliases-good-verify-ip4", "failed to verify %s: missing IP4 address #%d",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
i);
|
||||
|
||||
addr.s_addr = nm_ip4_address_get_address (ip4_addr);
|
||||
ASSERT (inet_ntop (AF_INET, &addr, buf, sizeof (buf)) > 0,
|
||||
"aliases-good-verify-ip4", "failed to verify %s: couldn't convert IP address #%d",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
i);
|
||||
|
||||
for (j = 0; j < expected_num_addresses; j++) {
|
||||
if (!g_strcmp0 (buf, expected_address[j]))
|
||||
break;
|
||||
}
|
||||
|
||||
ASSERT (j < expected_num_addresses,
|
||||
"aliases-good-verify-ip4", "failed to verify %s: unexpected IP4 address #%d",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
i);
|
||||
|
||||
ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix,
|
||||
"aliases-good-verify-ip4", "failed to verify %s: unexpected IP4 address prefix #%d",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
i);
|
||||
|
||||
if (expected_gateway[j]) {
|
||||
ASSERT (inet_pton (AF_INET, expected_gateway[j], &addr) > 0,
|
||||
"aliases-good-verify-ip4", "failed to verify %s: couldn't convert IP address gateway #%d",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
i);
|
||||
} else
|
||||
addr.s_addr = 0;
|
||||
ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr,
|
||||
"aliases-good-verify-ip4", "failed to verify %s: unexpected IP4 address gateway #%d",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
i);
|
||||
|
||||
ASSERT (g_strcmp0 (NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)), expected_label[j]) == 0,
|
||||
"aliases-good-verify-ip4", "failed to verify %s: unexpected IP4 address label #%d",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
i);
|
||||
|
||||
expected_address[j] = NULL;
|
||||
expected_gateway[j] = NULL;
|
||||
expected_label[j] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < expected_num_addresses; i++) {
|
||||
ASSERT (expected_address[i] == NULL,
|
||||
"aliases-good-verify-ip4", "failed to verify %s: did not find IP4 address %s",
|
||||
TEST_IFCFG_ALIASES_GOOD,
|
||||
expected_address[i]);
|
||||
}
|
||||
|
||||
g_free (keyfile);
|
||||
g_free (routefile);
|
||||
g_free (route6file);
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
#define TEST_IFCFG_ALIASES_BAD TEST_IFCFG_DIR"/network-scripts/ifcfg-aliasem1"
|
||||
|
||||
static void
|
||||
test_read_wired_aliases_bad (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
char *unmanaged = NULL;
|
||||
char *keyfile = NULL;
|
||||
char *routefile = NULL;
|
||||
char *route6file = NULL;
|
||||
gboolean ignore_error = FALSE;
|
||||
GError *error = NULL;
|
||||
const char *tmp;
|
||||
const char *expected_id = "System aliasem1";
|
||||
int expected_num_addresses = 1, expected_prefix = 24;
|
||||
const char *expected_address = "192.168.1.5";
|
||||
const char *expected_label = NULL;
|
||||
const char *expected_gateway = "192.168.1.1";
|
||||
NMIP4Address *ip4_addr;
|
||||
struct in_addr addr;
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_ALIASES_BAD,
|
||||
NULL,
|
||||
TYPE_ETHERNET,
|
||||
NULL,
|
||||
&unmanaged,
|
||||
&keyfile,
|
||||
&routefile,
|
||||
&route6file,
|
||||
&error,
|
||||
&ignore_error);
|
||||
ASSERT (connection != NULL,
|
||||
"aliases-bad-read", "failed to read %s: %s", TEST_IFCFG_ALIASES_BAD, error->message);
|
||||
|
||||
ASSERT (nm_connection_verify (connection, &error),
|
||||
"aliases-bad-verify", "failed to verify %s: %s", TEST_IFCFG_ALIASES_BAD, error->message);
|
||||
|
||||
/* ===== CONNECTION SETTING ===== */
|
||||
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
ASSERT (s_con != NULL,
|
||||
"aliases-bad-verify-connection", "failed to verify %s: missing %s setting",
|
||||
TEST_IFCFG_ALIASES_BAD,
|
||||
NM_SETTING_CONNECTION_SETTING_NAME);
|
||||
|
||||
/* ID */
|
||||
tmp = nm_setting_connection_get_id (s_con);
|
||||
ASSERT (tmp != NULL,
|
||||
"aliases-bad-verify-connection", "failed to verify %s: missing %s / %s key",
|
||||
TEST_IFCFG_ALIASES_BAD,
|
||||
NM_SETTING_CONNECTION_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_ID);
|
||||
ASSERT (strcmp (tmp, expected_id) == 0,
|
||||
"aliases-bad-verify-connection", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_IFCFG_ALIASES_BAD,
|
||||
NM_SETTING_CONNECTION_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_ID);
|
||||
|
||||
/* ===== IPv4 SETTING ===== */
|
||||
|
||||
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
||||
ASSERT (s_ip4 != NULL,
|
||||
"aliases-bad-verify-ip4", "failed to verify %s: missing %s setting",
|
||||
TEST_IFCFG_ALIASES_BAD,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME);
|
||||
|
||||
/* Method */
|
||||
tmp = nm_setting_ip4_config_get_method (s_ip4);
|
||||
ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
|
||||
"aliases-bad-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_IFCFG_ALIASES_BAD,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_METHOD);
|
||||
|
||||
ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == expected_num_addresses,
|
||||
"aliases-bad-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_IFCFG_ALIASES_BAD,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_ADDRESSES);
|
||||
|
||||
/* Addresses */
|
||||
ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
|
||||
ASSERT (ip4_addr,
|
||||
"aliases-bad-verify-ip4", "failed to verify %s: missing IP4 address",
|
||||
TEST_IFCFG_ALIASES_BAD);
|
||||
|
||||
ASSERT (inet_pton (AF_INET, expected_address, &addr) > 0,
|
||||
"aliases-bad-verify-ip4", "failed to verify %s: couldn't convert IP address",
|
||||
TEST_IFCFG_ALIASES_BAD);
|
||||
ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr,
|
||||
"aliases-bad-verify-ip4", "failed to verify %s: unexpected IP4 address",
|
||||
TEST_IFCFG_ALIASES_BAD);
|
||||
|
||||
ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix,
|
||||
"aliases-bad-verify-ip4", "failed to verify %s: unexpected IP4 address prefix",
|
||||
TEST_IFCFG_ALIASES_BAD);
|
||||
|
||||
ASSERT (inet_pton (AF_INET, expected_gateway, &addr) > 0,
|
||||
"aliases-bad-verify-ip4", "failed to verify %s: couldn't convert IP address gateway",
|
||||
TEST_IFCFG_ALIASES_BAD);
|
||||
ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr,
|
||||
"aliases-bad-verify-ip4", "failed to verify %s: unexpected IP4 address gateway",
|
||||
TEST_IFCFG_ALIASES_BAD);
|
||||
|
||||
ASSERT (g_strcmp0 (NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0)), expected_label) == 0,
|
||||
"aliases-bad-verify-ip4", "failed to verify %s: unexpected IP4 address label",
|
||||
TEST_IFCFG_ALIASES_BAD);
|
||||
|
||||
g_free (keyfile);
|
||||
g_free (routefile);
|
||||
g_free (route6file);
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
#define TEST_IFCFG_WIFI_OPEN TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open"
|
||||
|
||||
static void
|
||||
|
|
@ -7799,6 +8065,208 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme,
|
|||
g_object_unref (reread);
|
||||
}
|
||||
|
||||
#define TEST_SCRATCH_ALIAS_BASE TEST_SCRATCH_DIR "/network-scripts/ifcfg-alias0"
|
||||
|
||||
static void
|
||||
test_write_wired_aliases (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMConnection *reread;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingWired *s_wired;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
char *uuid;
|
||||
int num_addresses = 4;
|
||||
guint32 ip[] = { 0x01010101, 0x01010102, 0x01010103, 0x01010104 };
|
||||
const char *label[] = { NULL, "alias0:2", NULL, "alias0:3" };
|
||||
const guint32 gw = htonl (0x01010101);
|
||||
const guint32 prefix = 24;
|
||||
NMIP4Address *addr;
|
||||
gboolean success;
|
||||
GError *error = NULL;
|
||||
char *testfile = NULL;
|
||||
char *unmanaged = NULL;
|
||||
char *keyfile = NULL;
|
||||
char *routefile = NULL;
|
||||
char *route6file = NULL;
|
||||
gboolean ignore_error = FALSE;
|
||||
shvarFile *ifcfg;
|
||||
int i, j;
|
||||
|
||||
connection = nm_connection_new ();
|
||||
ASSERT (connection != NULL,
|
||||
"wired-aliases-write", "failed to allocate new connection");
|
||||
|
||||
/* Connection setting */
|
||||
s_con = (NMSettingConnection *) nm_setting_connection_new ();
|
||||
ASSERT (s_con != NULL,
|
||||
"wired-aliases-write", "failed to allocate new %s setting",
|
||||
NM_SETTING_CONNECTION_SETTING_NAME);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_con));
|
||||
|
||||
uuid = nm_utils_uuid_generate ();
|
||||
g_object_set (s_con,
|
||||
NM_SETTING_CONNECTION_ID, "alias0",
|
||||
NM_SETTING_CONNECTION_UUID, uuid,
|
||||
NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
|
||||
NULL);
|
||||
g_free (uuid);
|
||||
|
||||
/* Wired setting */
|
||||
s_wired = (NMSettingWired *) nm_setting_wired_new ();
|
||||
ASSERT (s_wired != NULL,
|
||||
"wired-aliases-write", "failed to allocate new %s setting",
|
||||
NM_SETTING_WIRED_SETTING_NAME);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_wired));
|
||||
|
||||
/* IP4 setting */
|
||||
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
|
||||
ASSERT (s_ip4 != NULL,
|
||||
"wired-aliases-write", "failed to allocate new %s setting",
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
|
||||
|
||||
g_object_set (s_ip4,
|
||||
NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
|
||||
NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE,
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < num_addresses; i++) {
|
||||
addr = nm_ip4_address_new ();
|
||||
nm_ip4_address_set_address (addr, ip[i]);
|
||||
nm_ip4_address_set_prefix (addr, prefix);
|
||||
nm_ip4_address_set_gateway (addr, gw);
|
||||
NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, label[i]));
|
||||
nm_ip4_address_unref (addr);
|
||||
}
|
||||
|
||||
ASSERT (nm_connection_verify (connection, &error) == TRUE,
|
||||
"wired-aliases-write", "failed to verify connection: %s",
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
|
||||
/* Create some pre-existing alias files, to make sure they get overwritten / deleted. */
|
||||
ifcfg = svCreateFile (TEST_SCRATCH_ALIAS_BASE ":2");
|
||||
svSetValue (ifcfg, "DEVICE", "alias0:2", FALSE);
|
||||
svSetValue (ifcfg, "IPADDR", "192.168.1.2", FALSE);
|
||||
svWriteFile (ifcfg, 0644);
|
||||
svCloseFile (ifcfg);
|
||||
ASSERT (g_file_test (TEST_SCRATCH_ALIAS_BASE ":2", G_FILE_TEST_EXISTS),
|
||||
"wired-aliases-write", "failed to write extra alias file");
|
||||
|
||||
ifcfg = svCreateFile (TEST_SCRATCH_ALIAS_BASE ":5");
|
||||
svSetValue (ifcfg, "DEVICE", "alias0:5", FALSE);
|
||||
svSetValue (ifcfg, "IPADDR", "192.168.1.5", FALSE);
|
||||
svWriteFile (ifcfg, 0644);
|
||||
svCloseFile (ifcfg);
|
||||
ASSERT (g_file_test (TEST_SCRATCH_ALIAS_BASE ":5", G_FILE_TEST_EXISTS),
|
||||
"wired-aliases-write", "failed to write extra alias file");
|
||||
|
||||
/* Save the ifcfg */
|
||||
success = writer_new_connection (connection,
|
||||
TEST_SCRATCH_DIR "/network-scripts/",
|
||||
&testfile,
|
||||
&error);
|
||||
ASSERT (success == TRUE,
|
||||
"wired-aliases-write", "failed to write connection to disk: %s",
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
|
||||
ASSERT (testfile != NULL,
|
||||
"wired-aliases-write", "didn't get ifcfg file path back after writing connection");
|
||||
|
||||
/* Re-check the alias files */
|
||||
ASSERT (g_file_test (TEST_SCRATCH_ALIAS_BASE ":2", G_FILE_TEST_EXISTS),
|
||||
"wired-aliases-write", "saving failed to write ifcfg-alias0:2");
|
||||
ASSERT (g_file_test (TEST_SCRATCH_ALIAS_BASE ":3", G_FILE_TEST_EXISTS),
|
||||
"wired-aliases-write", "saving failed to write ifcfg-alias0:3");
|
||||
ASSERT (!g_file_test (TEST_SCRATCH_ALIAS_BASE ":5", G_FILE_TEST_EXISTS),
|
||||
"wired-aliases-write", "saving failed to delete unused ifcfg-alias0:5");
|
||||
|
||||
/* re-read the connection for comparison */
|
||||
reread = connection_from_file (testfile,
|
||||
NULL,
|
||||
TYPE_ETHERNET,
|
||||
NULL,
|
||||
&unmanaged,
|
||||
&keyfile,
|
||||
&routefile,
|
||||
&route6file,
|
||||
&error,
|
||||
&ignore_error);
|
||||
unlink (testfile);
|
||||
unlink (TEST_SCRATCH_ALIAS_BASE ":2");
|
||||
unlink (TEST_SCRATCH_ALIAS_BASE ":3");
|
||||
|
||||
ASSERT (reread != NULL,
|
||||
"wired-aliases-write-reread", "failed to read %s: %s", testfile, error->message);
|
||||
|
||||
ASSERT (nm_connection_verify (reread, &error),
|
||||
"wired-aliases-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
|
||||
|
||||
/* nm_connection_compare() is not guaranteed to succeed, because the
|
||||
* aliases get read back in essentially random order. So just
|
||||
* verify the aliases manually.
|
||||
*/
|
||||
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
||||
ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == num_addresses,
|
||||
"wired-aliases-write-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
|
||||
testfile,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_ADDRESSES);
|
||||
|
||||
/* Addresses */
|
||||
for (i = 0; i < num_addresses; i++) {
|
||||
guint32 addrbytes;
|
||||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, i);
|
||||
ASSERT (addr,
|
||||
"wired-aliases-write-verify-ip4", "failed to verify %s: missing IP4 address #%d",
|
||||
testfile,
|
||||
i);
|
||||
|
||||
addrbytes = nm_ip4_address_get_address (addr);
|
||||
for (j = 0; j < num_addresses; j++) {
|
||||
if (addrbytes == ip[j])
|
||||
break;
|
||||
}
|
||||
|
||||
ASSERT (j < num_addresses,
|
||||
"wired-aliases-write-verify-ip4", "failed to verify %s: unexpected IP4 address #%d",
|
||||
testfile,
|
||||
i);
|
||||
|
||||
ASSERT (nm_ip4_address_get_prefix (addr) == prefix,
|
||||
"wired-aliases-write-verify-ip4", "failed to verify %s: unexpected IP4 address prefix #%d",
|
||||
testfile,
|
||||
i);
|
||||
|
||||
ASSERT (nm_ip4_address_get_gateway (addr) == gw,
|
||||
"wired-aliases-write-verify-ip4", "failed to verify %s: unexpected IP4 address gateway #%d",
|
||||
testfile,
|
||||
i);
|
||||
|
||||
ASSERT (g_strcmp0 (NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)), label[j]) == 0,
|
||||
"wired-aliases-write-verify-ip4", "failed to verify %s: unexpected IP4 address label #%d",
|
||||
testfile,
|
||||
i);
|
||||
|
||||
ip[j] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_addresses; i++) {
|
||||
ASSERT (ip[i] == 0,
|
||||
"wired-aliases-write-verify-ip4", "failed to verify %s: did not find IP4 address 0x%08x",
|
||||
testfile,
|
||||
ip[i]);
|
||||
}
|
||||
|
||||
g_free (testfile);
|
||||
g_free (keyfile);
|
||||
g_free (routefile);
|
||||
g_free (route6file);
|
||||
g_object_unref (connection);
|
||||
g_object_unref (reread);
|
||||
}
|
||||
|
||||
static void
|
||||
test_write_wifi_open (void)
|
||||
{
|
||||
|
|
@ -13869,6 +14337,8 @@ int main (int argc, char **argv)
|
|||
test_read_wired_8021x_tls_secret_flags (TEST_IFCFG_WIRED_8021X_TLS_ALWAYS,
|
||||
NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED);
|
||||
g_test_add_func (TPATH "802-1x/subj-mathes", test_read_write_802_1X_subj_matches);
|
||||
test_read_wired_aliases_good ();
|
||||
test_read_wired_aliases_bad ();
|
||||
test_read_wifi_open ();
|
||||
test_read_wifi_open_auto ();
|
||||
test_read_wifi_open_ssid_hex ();
|
||||
|
|
@ -13918,6 +14388,7 @@ int main (int argc, char **argv)
|
|||
test_write_wired_8021x_tls (NM_SETTING_802_1X_CK_SCHEME_PATH, NM_SETTING_SECRET_FLAG_NOT_SAVED);
|
||||
test_write_wired_8021x_tls (NM_SETTING_802_1X_CK_SCHEME_PATH, NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED);
|
||||
test_write_wired_8021x_tls (NM_SETTING_802_1X_CK_SCHEME_BLOB, NM_SETTING_SECRET_FLAG_NONE);
|
||||
test_write_wired_aliases ();
|
||||
test_write_wifi_open ();
|
||||
test_write_wifi_open_hex_ssid ();
|
||||
test_write_wifi_wep ();
|
||||
|
|
|
|||
|
|
@ -367,3 +367,49 @@ utils_ignore_ip_config (NMConnection *connection)
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Find out if the 'alias' file name might be an alias file for 'ifcfg' file name,
|
||||
* or any alias when 'ifcfg' is NULL. Does not check that it's actually a valid
|
||||
* alias name; that happens in reader.c
|
||||
*/
|
||||
gboolean
|
||||
utils_is_ifcfg_alias_file (const char *alias, const char *ifcfg)
|
||||
{
|
||||
g_return_val_if_fail (alias != NULL, FALSE);
|
||||
|
||||
if (strncmp (alias, IFCFG_TAG, strlen (IFCFG_TAG)))
|
||||
return FALSE;
|
||||
|
||||
if (ifcfg) {
|
||||
size_t len = strlen (ifcfg);
|
||||
|
||||
return (strncmp (alias, ifcfg, len) == 0 && alias[len] == ':');
|
||||
} else {
|
||||
return (strchr (alias, ':') != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
utils_get_ifcfg_from_alias (const char *alias)
|
||||
{
|
||||
char *base, *ptr, *ifcfg = NULL;
|
||||
|
||||
g_return_val_if_fail (alias != NULL, NULL);
|
||||
|
||||
base = g_path_get_basename (alias);
|
||||
g_return_val_if_fail (base != NULL, NULL);
|
||||
|
||||
if (utils_is_ifcfg_alias_file (base, NULL)) {
|
||||
ifcfg = g_strdup (alias);
|
||||
ptr = strrchr (ifcfg, ':');
|
||||
if (ptr)
|
||||
*ptr = '\0';
|
||||
else {
|
||||
g_free (ifcfg);
|
||||
ifcfg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (base);
|
||||
return ifcfg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,5 +50,8 @@ gboolean utils_has_route_file_new_syntax (const char *filename);
|
|||
|
||||
gboolean utils_ignore_ip_config (NMConnection *connection);
|
||||
|
||||
gboolean utils_is_ifcfg_alias_file (const char *alias, const char *ifcfg);
|
||||
char *utils_get_ifcfg_from_alias (const char *alias);
|
||||
|
||||
#endif /* _UTILS_H_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include <nm-setting-vlan.h>
|
||||
#include <nm-setting-team.h>
|
||||
#include <nm-setting-team-port.h>
|
||||
#include <nm-util-private.h>
|
||||
#include <nm-utils.h>
|
||||
|
||||
#include "common.h"
|
||||
|
|
@ -1845,7 +1846,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
|||
char *addr_key, *prefix_key, *netmask_key, *gw_key, *metric_key, *tmp;
|
||||
char *route_path = NULL;
|
||||
gint32 j;
|
||||
guint32 i, num;
|
||||
guint32 i, n, num;
|
||||
GString *searches;
|
||||
gboolean success = FALSE;
|
||||
gboolean fake_ip4 = FALSE;
|
||||
|
|
@ -1909,48 +1910,68 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
|||
else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED))
|
||||
svSetValue (ifcfg, "BOOTPROTO", "shared", FALSE);
|
||||
|
||||
/* Write out IPADDR0 .. IPADDR255, PREFIX0 .. PREFIX255, GATEWAY0 .. GATEWAY255
|
||||
* Possible NETMASK<n> is removed only (it's obsolete) */
|
||||
num = nm_setting_ip4_config_get_num_addresses (s_ip4);
|
||||
/* Clear out un-numbered IP address fields */
|
||||
svSetValue (ifcfg, "IPADDR", NULL, FALSE);
|
||||
svSetValue (ifcfg, "PREFIX", NULL, FALSE);
|
||||
svSetValue (ifcfg, "NETMASK", NULL, FALSE);
|
||||
svSetValue (ifcfg, "GATEWAY", NULL, FALSE);
|
||||
for (i = 0; i < 256; i++) {
|
||||
|
||||
/* Write out IPADDR<n>, PREFIX<n>, GATEWAY<n> for current IP addresses
|
||||
* without labels. Unset obsolete NETMASK<n>.
|
||||
*/
|
||||
num = nm_setting_ip4_config_get_num_addresses (s_ip4);
|
||||
for (i = n = 0; i < num; i++) {
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
NMIP4Address *addr;
|
||||
guint32 ip;
|
||||
|
||||
addr_key = g_strdup_printf ("IPADDR%d", i);
|
||||
prefix_key = g_strdup_printf ("PREFIX%d", i);
|
||||
netmask_key = g_strdup_printf ("NETMASK%d", i);
|
||||
gw_key = g_strdup_printf ("GATEWAY%d", i);
|
||||
if (i > 0 && NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)))
|
||||
continue;
|
||||
|
||||
if (i >= num) {
|
||||
svSetValue (ifcfg, addr_key, NULL, FALSE);
|
||||
svSetValue (ifcfg, prefix_key, NULL, FALSE);
|
||||
svSetValue (ifcfg, netmask_key, NULL, FALSE);
|
||||
svSetValue (ifcfg, gw_key, NULL, FALSE);
|
||||
} else {
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, i);
|
||||
addr_key = g_strdup_printf ("IPADDR%d", n);
|
||||
prefix_key = g_strdup_printf ("PREFIX%d", n);
|
||||
netmask_key = g_strdup_printf ("NETMASK%d", n);
|
||||
gw_key = g_strdup_printf ("GATEWAY%d", n);
|
||||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, i);
|
||||
|
||||
memset (buf, 0, sizeof (buf));
|
||||
ip = nm_ip4_address_get_address (addr);
|
||||
inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf));
|
||||
svSetValue (ifcfg, addr_key, &buf[0], FALSE);
|
||||
|
||||
tmp = g_strdup_printf ("%u", nm_ip4_address_get_prefix (addr));
|
||||
svSetValue (ifcfg, prefix_key, tmp, FALSE);
|
||||
g_free (tmp);
|
||||
|
||||
svSetValue (ifcfg, netmask_key, NULL, FALSE);
|
||||
|
||||
if (nm_ip4_address_get_gateway (addr)) {
|
||||
memset (buf, 0, sizeof (buf));
|
||||
ip = nm_ip4_address_get_address (addr);
|
||||
ip = nm_ip4_address_get_gateway (addr);
|
||||
inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf));
|
||||
svSetValue (ifcfg, addr_key, &buf[0], FALSE);
|
||||
svSetValue (ifcfg, gw_key, &buf[0], FALSE);
|
||||
} else
|
||||
svSetValue (ifcfg, gw_key, NULL, FALSE);
|
||||
|
||||
tmp = g_strdup_printf ("%u", nm_ip4_address_get_prefix (addr));
|
||||
svSetValue (ifcfg, prefix_key, tmp, FALSE);
|
||||
g_free (tmp);
|
||||
g_free (addr_key);
|
||||
g_free (prefix_key);
|
||||
g_free (netmask_key);
|
||||
g_free (gw_key);
|
||||
n++;
|
||||
}
|
||||
|
||||
if (nm_ip4_address_get_gateway (addr)) {
|
||||
memset (buf, 0, sizeof (buf));
|
||||
ip = nm_ip4_address_get_gateway (addr);
|
||||
inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf));
|
||||
svSetValue (ifcfg, gw_key, &buf[0], FALSE);
|
||||
} else
|
||||
svSetValue (ifcfg, gw_key, NULL, FALSE);
|
||||
}
|
||||
/* Clear remaining IPADDR<n..255>, etc */
|
||||
for (; n < 256; n++) {
|
||||
addr_key = g_strdup_printf ("IPADDR%d", n);
|
||||
prefix_key = g_strdup_printf ("PREFIX%d", n);
|
||||
netmask_key = g_strdup_printf ("NETMASK%d", n);
|
||||
gw_key = g_strdup_printf ("GATEWAY%d", n);
|
||||
|
||||
svSetValue (ifcfg, addr_key, NULL, FALSE);
|
||||
svSetValue (ifcfg, prefix_key, NULL, FALSE);
|
||||
svSetValue (ifcfg, netmask_key, NULL, FALSE);
|
||||
svSetValue (ifcfg, gw_key, NULL, FALSE);
|
||||
|
||||
g_free (addr_key);
|
||||
g_free (prefix_key);
|
||||
|
|
@ -2120,6 +2141,102 @@ out:
|
|||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
write_ip4_aliases (NMConnection *connection, char *base_ifcfg_path)
|
||||
{
|
||||
NMSettingIP4Config *s_ip4;
|
||||
char *base_ifcfg_dir, *base_ifcfg_name, *base_name;
|
||||
int i, num, base_ifcfg_path_len, base_ifcfg_name_len, base_name_len;
|
||||
GDir *dir;
|
||||
|
||||
base_ifcfg_path_len = strlen (base_ifcfg_path);
|
||||
base_ifcfg_dir = g_path_get_dirname (base_ifcfg_path);
|
||||
base_ifcfg_name = g_path_get_basename (base_ifcfg_path);
|
||||
base_ifcfg_name_len = strlen (base_ifcfg_name);
|
||||
base_name = base_ifcfg_name + strlen (IFCFG_TAG);
|
||||
base_name_len = strlen (base_name);
|
||||
|
||||
/* Remove all existing aliases for this file first */
|
||||
dir = g_dir_open (base_ifcfg_dir, 0, NULL);
|
||||
if (dir) {
|
||||
const char *item;
|
||||
|
||||
while ((item = g_dir_read_name (dir))) {
|
||||
char *full_path;
|
||||
|
||||
if ( strncmp (item, base_ifcfg_name, base_ifcfg_name_len) != 0
|
||||
|| item[base_ifcfg_name_len] != ':')
|
||||
continue;
|
||||
|
||||
full_path = g_build_filename (base_ifcfg_dir, item, NULL);
|
||||
unlink (full_path);
|
||||
g_free (full_path);
|
||||
}
|
||||
|
||||
g_dir_close (dir);
|
||||
}
|
||||
|
||||
if (utils_ignore_ip_config (connection))
|
||||
return;
|
||||
|
||||
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
||||
if (!s_ip4)
|
||||
return;
|
||||
|
||||
num = nm_setting_ip4_config_get_num_addresses (s_ip4);
|
||||
for (i = 0; i < num; i++) {
|
||||
const char *label, *p;
|
||||
char buf[INET_ADDRSTRLEN], *path, *tmp;
|
||||
NMIP4Address *addr;
|
||||
guint32 ip;
|
||||
shvarFile *ifcfg;
|
||||
|
||||
label = NM_UTIL_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i));
|
||||
if (!label)
|
||||
continue;
|
||||
if ( strncmp (label, base_name, base_name_len) != 0
|
||||
|| label[base_name_len] != ':')
|
||||
continue;
|
||||
|
||||
for (p = label; *p; p++) {
|
||||
if (!g_ascii_isalnum (*p) && *p != '_' && *p != ':')
|
||||
break;
|
||||
}
|
||||
if (*p)
|
||||
continue;
|
||||
|
||||
path = g_strdup_printf ("%s%s", base_ifcfg_path, label + base_name_len);
|
||||
ifcfg = svCreateFile (path);
|
||||
g_free (path);
|
||||
|
||||
svSetValue (ifcfg, "DEVICE", label, FALSE);
|
||||
|
||||
addr = nm_setting_ip4_config_get_address (s_ip4, i);
|
||||
|
||||
memset (buf, 0, sizeof (buf));
|
||||
ip = nm_ip4_address_get_address (addr);
|
||||
inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf));
|
||||
svSetValue (ifcfg, "IPADDR", &buf[0], FALSE);
|
||||
|
||||
tmp = g_strdup_printf ("%u", nm_ip4_address_get_prefix (addr));
|
||||
svSetValue (ifcfg, "PREFIX", tmp, FALSE);
|
||||
g_free (tmp);
|
||||
|
||||
if (nm_ip4_address_get_gateway (addr)) {
|
||||
memset (buf, 0, sizeof (buf));
|
||||
ip = nm_ip4_address_get_gateway (addr);
|
||||
inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf));
|
||||
svSetValue (ifcfg, "GATEWAY", &buf[0], FALSE);
|
||||
}
|
||||
|
||||
svWriteFile (ifcfg, 0644);
|
||||
svCloseFile (ifcfg);
|
||||
}
|
||||
|
||||
g_free (base_ifcfg_name);
|
||||
g_free (base_ifcfg_dir);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
write_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **error)
|
||||
{
|
||||
|
|
@ -2517,6 +2634,7 @@ write_connection (NMConnection *connection,
|
|||
|
||||
if (!write_ip4_setting (connection, ifcfg, error))
|
||||
goto out;
|
||||
write_ip4_aliases (connection, ifcfg_name);
|
||||
|
||||
if (!write_ip6_setting (connection, ifcfg, error))
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -194,6 +194,17 @@ ip4_addr_writer (GKeyFile *file,
|
|||
write_ip4_values (file, setting_name, array, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
ip4_addr_label_writer (GKeyFile *file,
|
||||
const char *keyfile_dir,
|
||||
const char *uuid,
|
||||
NMSetting *setting,
|
||||
const char *key,
|
||||
const GValue *value)
|
||||
{
|
||||
/* skip */
|
||||
}
|
||||
|
||||
static void
|
||||
ip4_route_writer (GKeyFile *file,
|
||||
const char *keyfile_dir,
|
||||
|
|
@ -773,6 +784,9 @@ static KeyWriter key_writers[] = {
|
|||
{ NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_ADDRESSES,
|
||||
ip4_addr_writer },
|
||||
{ NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
"address-labels",
|
||||
ip4_addr_label_writer },
|
||||
{ NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_ADDRESSES,
|
||||
ip6_addr_writer },
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue