summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2016-05-30 16:40:41 +0200
committerLubomir Rintel <lkundrak@v3.sk>2016-05-30 16:40:41 +0200
commit2edaf35f1296b4b8f140365b4b40d5d89e57128a (patch)
tree33baf5059104b891cb9895ed1abbe303f6690d87
parent28938155e0133ae31c2f8b498d9b985160ca3ab4 (diff)
parent6fd1bf07499cea02de050f3d3906547090f4589d (diff)
downloadNetworkManager-2edaf35f1296b4b8f140365b4b40d5d89e57128a.tar.gz
merge: branch 'lr/connection-token'
https://bugzilla.gnome.org/show_bug.cgi?id=765851
-rw-r--r--clients/cli/settings.c13
-rw-r--r--libnm-core/nm-connection.c27
-rw-r--r--libnm-core/nm-core-internal.h4
-rw-r--r--libnm-core/nm-setting-ip6-config.c104
-rw-r--r--libnm-core/nm-setting-ip6-config.h4
-rw-r--r--libnm-core/nm-utils.c34
-rw-r--r--libnm-glib/nm-vpn-plugin.c2
-rw-r--r--libnm-util/nm-setting.c2
-rw-r--r--src/devices/nm-device.c108
-rw-r--r--src/dhcp-manager/nm-dhcp-client.c2
-rw-r--r--src/nm-core-utils.c76
-rw-r--r--src/nm-core-utils.h18
-rw-r--r--src/platform/nm-linux-platform.c83
-rw-r--r--src/platform/nm-platform.c32
-rw-r--r--src/platform/nm-platform.h10
-rw-r--r--src/ppp-manager/nm-ppp-manager.c2
-rw-r--r--src/rdisc/nm-rdisc.c2
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c7
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.c6
19 files changed, 437 insertions, 99 deletions
diff --git a/clients/cli/settings.c b/clients/cli/settings.c
index f2a504cc5c..0f75d2a791 100644
--- a/clients/cli/settings.c
+++ b/clients/cli/settings.c
@@ -330,6 +330,7 @@ NmcOutputField nmc_fields_setting_ip6_config[] = {
SETTING_FIELD (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE), /* 15 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME), /* 16 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME), /* 17 */
+ SETTING_FIELD (NM_SETTING_IP6_CONFIG_TOKEN), /* 18 */
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTING_IP6_CONFIG_ALL "name"","\
@@ -349,7 +350,8 @@ NmcOutputField nmc_fields_setting_ip6_config[] = {
NM_SETTING_IP6_CONFIG_IP6_PRIVACY","\
NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE","\
NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME","\
- NM_SETTING_IP_CONFIG_DHCP_HOSTNAME
+ NM_SETTING_IP_CONFIG_DHCP_HOSTNAME","\
+ NM_SETTING_IP6_CONFIG_TOKEN
/* Available fields for NM_SETTING_SERIAL_SETTING_NAME */
NmcOutputField nmc_fields_setting_serial[] = {
@@ -1629,6 +1631,7 @@ DEFINE_GETTER (nmc_property_ipv6_get_never_default, NM_SETTING_IP_CONFIG_NEVER_D
DEFINE_GETTER (nmc_property_ipv6_get_may_fail, NM_SETTING_IP_CONFIG_MAY_FAIL)
DEFINE_GETTER (nmc_property_ipv6_get_dhcp_send_hostname, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME)
DEFINE_GETTER (nmc_property_ipv6_get_dhcp_hostname, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME)
+DEFINE_GETTER (nmc_property_ipv6_get_token, NM_SETTING_IP6_CONFIG_TOKEN)
static char *
nmc_property_ipv6_get_ip6_privacy (NMSetting *setting, NmcPropertyGetType get_type)
@@ -6728,6 +6731,13 @@ nmc_properties_init (void)
NULL,
NULL,
NULL);
+ nmc_add_prop_funcs (GLUE (IP6_CONFIG, TOKEN),
+ nmc_property_ipv6_get_token,
+ nmc_property_set_string,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
/* Add editable properties for NM_SETTING_OLPC_MESH_SETTING_NAME */
nmc_add_prop_funcs (GLUE (OLPC_MESH, SSID),
@@ -8256,6 +8266,7 @@ setting_ip6_config_details (NMSetting *setting, NmCli *nmc, const char *one_pro
set_val_str (arr, 15, nmc_property_ipv6_get_addr_gen_mode (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 16, nmc_property_ipv6_get_dhcp_send_hostname (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 17, nmc_property_ipv6_get_dhcp_hostname (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 18, nmc_property_ipv6_get_token (setting, NMC_PROPERTY_GET_PRETTY));
g_ptr_array_add (nmc->output_data, arr);
print_data (nmc); /* Print all data */
diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c
index b2c4d4eea0..a823af9bea 100644
--- a/libnm-core/nm-connection.c
+++ b/libnm-core/nm-connection.c
@@ -23,6 +23,7 @@
#include "nm-default.h"
#include <string.h>
+#include <arpa/inet.h>
#include "nm-connection.h"
#include "nm-connection-private.h"
@@ -724,7 +725,7 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters)
const char *default_ip6_method = NULL;
NMSettingIPConfig *s_ip4, *s_ip6;
NMSetting *setting;
- gboolean gateway_removed = FALSE;
+ gboolean changed = FALSE;
if (parameters)
default_ip6_method = g_hash_table_lookup (parameters, NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD);
@@ -761,7 +762,7 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters)
if ( nm_setting_ip_config_get_gateway (s_ip4)
&& nm_setting_ip_config_get_never_default (s_ip4)) {
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, NULL, NULL);
- gateway_removed = TRUE;
+ changed = TRUE;
}
}
if (!s_ip6) {
@@ -773,13 +774,31 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters)
NULL);
nm_connection_add_setting (self, setting);
} else {
+ const char *token;
+
+ token = nm_setting_ip6_config_get_token ((NMSettingIP6Config *) s_ip6);
+ if ( token
+ && nm_setting_ip6_config_get_addr_gen_mode ((NMSettingIP6Config *) s_ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) {
+ struct in6_addr i6_token;
+ char normalized[NM_UTILS_INET_ADDRSTRLEN];
+
+ if ( inet_pton (AF_INET6, token, &i6_token) == 1
+ && _nm_utils_inet6_is_token (&i6_token)) {
+ nm_utils_inet6_ntop (&i6_token, normalized);
+ if (g_strcmp0 (token, normalized)) {
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, normalized, NULL);
+ changed = TRUE;
+ }
+ }
+ }
+
if ( nm_setting_ip_config_get_gateway (s_ip6)
&& nm_setting_ip_config_get_never_default (s_ip6)) {
g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, NULL, NULL);
- gateway_removed = TRUE;
+ changed = TRUE;
}
}
- return !s_ip4 || !s_ip6 || gateway_removed;
+ return !s_ip4 || !s_ip6 || changed;
}
}
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index 2041a1d3a1..a09ee26c48 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -296,4 +296,8 @@ typedef enum {
NMBondOptionType
_nm_setting_bond_get_option_type (NMSettingBond *setting, const char *name);
+/***********************************************************/
+
+gboolean _nm_utils_inet6_is_token (const struct in6_addr *in6addr);
+
#endif
diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c
index f583255382..a5826eb3b1 100644
--- a/libnm-core/nm-setting-ip6-config.c
+++ b/libnm-core/nm-setting-ip6-config.c
@@ -24,6 +24,7 @@
#include "nm-setting-ip6-config.h"
#include <string.h>
+#include <arpa/inet.h>
#include "nm-setting-private.h"
#include "nm-core-enum-types.h"
@@ -59,6 +60,7 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_IP6_CONFIG)
typedef struct {
NMSettingIP6ConfigPrivacy ip6_privacy;
NMSettingIP6ConfigAddrGenMode addr_gen_mode;
+ char *token;
} NMSettingIP6ConfigPrivate;
@@ -66,6 +68,7 @@ enum {
PROP_0,
PROP_IP6_PRIVACY,
PROP_ADDR_GEN_MODE,
+ PROP_TOKEN,
LAST_PROP
};
@@ -120,6 +123,25 @@ nm_setting_ip6_config_get_addr_gen_mode (NMSettingIP6Config *setting)
return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->addr_gen_mode;
}
+/**
+ * nm_setting_ip6_config_get_token:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Returns the value contained in the #NMSettingIP6Config:token
+ * property.
+ *
+ * Returns: A string.
+ *
+ * Since: 1.4
+ **/
+const char *
+nm_setting_ip6_config_get_token (NMSettingIP6Config *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), NULL);
+
+ return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->token;
+}
+
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
@@ -127,6 +149,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting);
NMSettingVerifyResult ret;
const char *method;
+ gboolean token_needs_normalization = FALSE;
ret = NM_SETTING_CLASS (nm_setting_ip6_config_parent_class)->verify (setting, connection, error);
if (ret != NM_SETTING_VERIFY_SUCCESS)
@@ -201,6 +224,44 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
+ if (priv->token) {
+ if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) {
+ struct in6_addr i6_token;
+ char s_token[NM_UTILS_INET_ADDRSTRLEN];
+
+ if ( inet_pton (AF_INET6, priv->token, &i6_token) != 1
+ || !_nm_utils_inet6_is_token (&i6_token)) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("value is not a valid token"));
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_TOKEN);
+ return FALSE;
+ }
+
+ if (g_strcmp0 (priv->token, nm_utils_inet6_ntop (&i6_token, s_token)))
+ token_needs_normalization = TRUE;
+ } else {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("only makes sense with EUI64 address generation mode"));
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_TOKEN);
+ return FALSE;
+ }
+ }
+
+ /* Failures from here on, are NORMALIZABLE_ERROR... */
+
+ if (token_needs_normalization) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("token is not in canonical form"));
+ g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_TOKEN);
+ return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
+ }
+
return TRUE;
}
@@ -388,6 +449,10 @@ set_property (GObject *object, guint prop_id,
case PROP_ADDR_GEN_MODE:
priv->addr_gen_mode = g_value_get_int (value);
break;
+ case PROP_TOKEN:
+ g_free (priv->token);
+ priv->token = g_value_dup_string (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -407,6 +472,9 @@ get_property (GObject *object, guint prop_id,
case PROP_ADDR_GEN_MODE:
g_value_set_int (value, priv->addr_gen_mode);
break;
+ case PROP_TOKEN:
+ g_value_set_string (value, priv->token);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -414,6 +482,17 @@ get_property (GObject *object, guint prop_id,
}
static void
+finalize (GObject *object)
+{
+ NMSettingIP6Config *self = NM_SETTING_IP6_CONFIG (object);
+ NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (self);
+
+ g_free (priv->token);
+
+ G_OBJECT_CLASS (nm_setting_ip6_config_parent_class)->finalize (object);
+}
+
+static void
nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (ip6_class);
@@ -424,6 +503,7 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
/* virtual methods */
object_class->set_property = set_property;
object_class->get_property = get_property;
+ object_class->finalize = finalize;
setting_class->verify = verify;
/* Properties */
@@ -656,6 +736,30 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
+ /**
+ * NMSettingIP6Config:token:
+ *
+ * Configure the token for draft-chown-6man-tokenised-ipv6-identifiers-02
+ * IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode.
+ *
+ * Since: 1.4
+ **/
+ /* ---ifcfg-rh---
+ * property: token
+ * variable: IPV6_TOKEN
+ * description: The IPv6 tokenized interface identifier token
+ * example: IPV6_TOKEN=::53
+ * ---end---
+ */
+ g_object_class_install_property
+ (object_class, PROP_TOKEN,
+ g_param_spec_string (NM_SETTING_IP6_CONFIG_TOKEN, "", "",
+ NULL,
+ G_PARAM_READWRITE |
+ NM_SETTING_PARAM_INFERRABLE |
+ G_PARAM_STATIC_STRINGS));
+
+
/* IP6-specific property overrides */
/* ---dbus---
diff --git a/libnm-core/nm-setting-ip6-config.h b/libnm-core/nm-setting-ip6-config.h
index 2966e558cb..3b29aaa226 100644
--- a/libnm-core/nm-setting-ip6-config.h
+++ b/libnm-core/nm-setting-ip6-config.h
@@ -43,6 +43,8 @@ G_BEGIN_DECLS
#define NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE "addr-gen-mode"
+#define NM_SETTING_IP6_CONFIG_TOKEN "token"
+
/**
* NM_SETTING_IP6_CONFIG_METHOD_IGNORE:
*
@@ -156,6 +158,8 @@ NMSetting *nm_setting_ip6_config_new (void);
NMSettingIP6ConfigPrivacy nm_setting_ip6_config_get_ip6_privacy (NMSettingIP6Config *setting);
NM_AVAILABLE_IN_1_2
NMSettingIP6ConfigAddrGenMode nm_setting_ip6_config_get_addr_gen_mode (NMSettingIP6Config *setting);
+NM_AVAILABLE_IN_1_4
+const char *nm_setting_ip6_config_get_token (NMSettingIP6Config *setting);
G_END_DECLS
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index 81676e9f1f..7a87dc18c4 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -3566,6 +3566,40 @@ nm_utils_ipaddr_valid (int family, const char *ip)
}
/**
+ * nm_utils_iinet6_is_token:
+ * @in6addr: the AF_INET6 address structure
+ *
+ * Checks if only the bottom 64bits of the address are set.
+ *
+ * Return value: %TRUE or %FALSE
+ */
+gboolean
+_nm_utils_inet6_is_token (const struct in6_addr *in6addr)
+{
+ if ( in6addr->s6_addr[0]
+ || in6addr->s6_addr[1]
+ || in6addr->s6_addr[2]
+ || in6addr->s6_addr[3]
+ || in6addr->s6_addr[4]
+ || in6addr->s6_addr[5]
+ || in6addr->s6_addr[6]
+ || in6addr->s6_addr[7])
+ return FALSE;
+
+ if ( in6addr->s6_addr[8]
+ || in6addr->s6_addr[9]
+ || in6addr->s6_addr[10]
+ || in6addr->s6_addr[11]
+ || in6addr->s6_addr[12]
+ || in6addr->s6_addr[13]
+ || in6addr->s6_addr[14]
+ || in6addr->s6_addr[15])
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
* nm_utils_check_virtual_device_compatibility:
* @virtual_type: a virtual connection type
* @other_type: a connection type to test against @virtual_type
diff --git a/libnm-glib/nm-vpn-plugin.c b/libnm-glib/nm-vpn-plugin.c
index 2af9deb4bd..0534b766e8 100644
--- a/libnm-glib/nm-vpn-plugin.c
+++ b/libnm-glib/nm-vpn-plugin.c
@@ -800,7 +800,7 @@ set_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_DBUS_SERVICE_NAME:
/* Construct-only */
- priv->dbus_service_name = g_strdup (g_value_get_string (value));
+ priv->dbus_service_name = g_value_dup_string (value);
break;
case PROP_STATE:
nm_vpn_plugin_set_state (NM_VPN_PLUGIN (object),
diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c
index 990d6fe73b..c0d82b4263 100644
--- a/libnm-util/nm-setting.c
+++ b/libnm-util/nm-setting.c
@@ -1403,7 +1403,7 @@ _nm_setting_verify_deprecated_virtual_iface_name (const char *interface_name,
e_invalid_property,
_("property is invalid"));
g_prefix_error (error, "%s.%s: ", setting_name, setting_property);
- /* we would like to make this a NORMALIZEABLE_ERROR, but that might
+ /* we would like to make this a NORMALIZABLE_ERROR, but that might
* break older connections. */
return NM_SETTING_VERIFY_NORMALIZABLE;
}
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index dfbf3ebbc8..5234d24cdd 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -735,39 +735,72 @@ static gboolean
get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- NMLinkType link_type;
- const guint8 *hwaddr = NULL;
- size_t hwaddr_len = 0;
+ const NMPlatformLink *pllink;
int ifindex;
gboolean success;
/* If we get here, we *must* have a kernel netdev, which implies an ifindex */
ifindex = nm_device_get_ip_ifindex (self);
- g_assert (ifindex);
+ g_return_val_if_fail (ifindex > 0, FALSE);
- link_type = nm_platform_link_get_type (NM_PLATFORM_GET, ifindex);
- g_return_val_if_fail (link_type > NM_LINK_TYPE_UNKNOWN, 0);
+ pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex);
+ if ( !pllink
+ || NM_IN_SET (pllink->type, NM_LINK_TYPE_NONE, NM_LINK_TYPE_UNKNOWN))
+ return FALSE;
- hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddr_len);
- if (!hwaddr_len)
+ if (pllink->addr.len <= 0)
return FALSE;
+ if (pllink->addr.len > NM_UTILS_HWADDR_LEN_MAX)
+ g_return_val_if_reached (FALSE);
- success = nm_utils_get_ipv6_interface_identifier (link_type,
- hwaddr,
- hwaddr_len,
+ success = nm_utils_get_ipv6_interface_identifier (pllink->type,
+ pllink->addr.data,
+ pllink->addr.len,
priv->dev_id,
out_iid);
if (!success) {
_LOGW (LOGD_HW, "failed to generate interface identifier "
- "for link type %u hwaddr_len %zu", link_type, hwaddr_len);
+ "for link type %u hwaddr_len %u", pllink->type, (unsigned) pllink->addr.len);
}
return success;
}
+/**
+ * nm_device_get_ip_iface_identifier:
+ * @self: an #NMDevice
+ * @iid: where to place the interface identifier
+ * @ignore_token: force creation of a non-tokenized address
+ *
+ * Return the interface's identifier for the EUI64 address generation mode.
+ * It's either a manually set token or and identifier generated in a
+ * hardware-specific way.
+ *
+ * Unless @ignore_token is set the token is preferred. That is the case
+ * for link-local addresses (to mimic kernel behavior).
+ *
+ * Returns: #TRUE if the @iid could be set
+ */
static gboolean
-nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid)
+nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid, gboolean ignore_token)
{
- return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid);
+ NMSettingIP6Config *s_ip6;
+ const char *token = NULL;
+ NMConnection *connection;
+
+ g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
+
+ connection = nm_device_get_applied_connection (self);
+ nm_assert (connection);
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection));
+ nm_assert (s_ip6);
+
+ if (!ignore_token)
+ token = nm_setting_ip6_config_get_token (s_ip6);
+ if (token)
+ return nm_utils_ipv6_interface_identifier_get_from_token (iid, token);
+ else
+ return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid);
}
const char *
@@ -1606,7 +1639,6 @@ device_link_changed (NMDevice *self)
{
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- NMUtilsIPv6IfaceId token_iid;
gboolean ip_ifname_changed = FALSE;
const char *udi;
NMPlatformLink info;
@@ -1678,10 +1710,11 @@ device_link_changed (NMDevice *self)
nm_device_emit_recheck_auto_activate (self);
}
- if (priv->rdisc && nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &token_iid)) {
- _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
- if (nm_rdisc_set_iid (priv->rdisc, token_iid))
+ if (priv->rdisc && info.inet6_token.id) {
+ if (nm_rdisc_set_iid (priv->rdisc, info.inet6_token)) {
+ _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
nm_rdisc_start (priv->rdisc);
+ }
}
if (klass->link_changed)
@@ -3061,6 +3094,7 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master)
gs_free char *uuid = NULL;
const char *ip4_method, *ip6_method;
GError *error = NULL;
+ const NMPlatformLink *pllink;
/* If update_connection() is not implemented, just fail. */
if (!klass->update_connection)
@@ -3107,6 +3141,15 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master)
s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
nm_connection_add_setting (connection, s_ip6);
+
+ pllink = nm_platform_link_get (NM_PLATFORM_GET, priv->ifindex);
+ if (pllink && pllink->inet6_token.id) {
+ _LOGD (LOGD_IP6, "IPv6 tokenized identifier present");
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, NM_IN6_ADDR_GEN_MODE_EUI64,
+ NM_SETTING_IP6_CONFIG_TOKEN, nm_utils_inet6_interface_identifier_to_token (pllink->inet6_token, NULL),
+ NULL);
+ }
}
klass->update_connection (self, connection);
@@ -5194,6 +5237,7 @@ ip6_config_merge_and_apply (NMDevice *self,
gboolean ignore_auto_routes = FALSE;
gboolean ignore_auto_dns = FALSE;
gboolean auto_method = FALSE;
+ const char *token = NULL;
/* Apply ignore-auto-routes and ignore-auto-dns settings */
connection = nm_device_get_applied_connection (self);
@@ -5201,9 +5245,14 @@ ip6_config_merge_and_apply (NMDevice *self,
NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection);
if (s_ip6) {
+ NMSettingIP6Config *ip6 = NM_SETTING_IP6_CONFIG (s_ip6);
+
ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip6);
ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip6);
+ if (nm_setting_ip6_config_get_addr_gen_mode (ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64)
+ token = nm_setting_ip6_config_get_token (ip6);
+
if (NM_IN_STRSET (nm_setting_ip_config_get_method (s_ip6),
NM_SETTING_IP6_CONFIG_METHOD_AUTO,
NM_SETTING_IP6_CONFIG_METHOD_DHCP))
@@ -5351,6 +5400,14 @@ END_ADD_DEFAULT_ROUTE:
/* Allow setting MTU etc */
if (commit) {
+ NMUtilsIPv6IfaceId iid;
+
+ if (token && nm_utils_ipv6_interface_identifier_get_from_token (&iid, token)) {
+ nm_platform_link_set_ipv6_token (NM_PLATFORM_GET,
+ nm_device_get_ip_ifindex (self),
+ iid);
+ }
+
if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit)
NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self, composite);
}
@@ -5823,13 +5880,13 @@ check_and_add_ipv6ll_addr (NMDevice *self)
return;
}
- if (!nm_device_get_ip_iface_identifier (self, &iid)) {
+ if (!nm_device_get_ip_iface_identifier (self, &iid, TRUE)) {
_LOGW (LOGD_IP6, "linklocal6: failed to get interface identifier; IPv6 cannot continue");
return;
}
_LOGD (LOGD_IP6, "linklocal6: using EUI-64 identifier to generate IPv6LL address");
- nm_utils_ipv6_addr_set_interface_identfier (&lladdr, iid);
+ nm_utils_ipv6_addr_set_interface_identifier (&lladdr, iid);
}
_LOGD (LOGD_IP6, "linklocal6: adding IPv6LL address %s", nm_utils_inet6_ntop (&lladdr, NULL));
@@ -6108,10 +6165,7 @@ addrconf6_start_with_link_ready (NMDevice *self)
g_assert (priv->rdisc);
- if (nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &iid)) {
- _LOGD (LOGD_IP6, "addrconf6: IPv6 tokenized identifier present");
- nm_rdisc_set_iid (priv->rdisc, iid);
- } else if (nm_device_get_ip_iface_identifier (self, &iid)) {
+ if (nm_device_get_ip_iface_identifier (self, &iid, FALSE)) {
_LOGD (LOGD_IP6, "addrconf6: using the device EUI-64 identifier");
nm_rdisc_set_iid (priv->rdisc, iid);
} else {
@@ -10658,7 +10712,7 @@ nm_device_spawn_iface_helper (NMDevice *self)
g_ptr_array_add (argv, g_strdup ("--slaac-tempaddr"));
g_ptr_array_add (argv, g_strdup_printf ("%d", priv->rdisc_use_tempaddr));
- if (nm_device_get_ip_iface_identifier (self, &iid)) {
+ if (nm_device_get_ip_iface_identifier (self, &iid, FALSE)) {
g_ptr_array_add (argv, g_strdup ("--iid"));
hex_iid = bin2hexstr ((const char *) iid.id_u8, sizeof (NMUtilsIPv6IfaceId));
g_ptr_array_add (argv, hex_iid);
@@ -11693,11 +11747,11 @@ set_property (GObject *object, guint prop_id,
break;
case PROP_DRIVER_VERSION:
g_free (priv->driver_version);
- priv->driver_version = g_strdup (g_value_get_string (value));
+ priv->driver_version = g_value_dup_string (value);
break;
case PROP_FIRMWARE_VERSION:
g_free (priv->firmware_version);
- priv->firmware_version = g_strdup (g_value_get_string (value));
+ priv->firmware_version = g_value_dup_string (value);
break;
case PROP_MTU:
priv->mtu = g_value_get_uint (value);
diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c
index 3490c0d235..9f66c93144 100644
--- a/src/dhcp-manager/nm-dhcp-client.c
+++ b/src/dhcp-manager/nm-dhcp-client.c
@@ -834,7 +834,7 @@ set_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_IFACE:
/* construct-only */
- priv->iface = g_strdup (g_value_get_string (value));
+ priv->iface = g_value_dup_string (value);
break;
case PROP_IFINDEX:
/* construct-only */
diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c
index 40081677df..276dc1c406 100644
--- a/src/nm-core-utils.c
+++ b/src/nm-core-utils.c
@@ -2866,20 +2866,92 @@ nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
}
return FALSE;
}
+
+/*****************************************************************************/
+
+/**
+ * nm_utils_ipv6_addr_set_interface_identifier:
+ * @addr: output token encoded as %in6_addr
+ * @iid: %NMUtilsIPv6IfaceId interface identifier
+ *
+ * Converts the %NMUtilsIPv6IfaceId to an %in6_addr (suitable for use
+ * with Linux platform). This only copies the lower 8 bytes, ignoring
+ * the /64 network prefix which is expected to be all-zero for a valid
+ * token.
+ */
void
-nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr,
+nm_utils_ipv6_addr_set_interface_identifier (struct in6_addr *addr,
const NMUtilsIPv6IfaceId iid)
{
memcpy (addr->s6_addr + 8, &iid.id_u8, 8);
}
+/**
+ * nm_utils_ipv6_interface_identifier_get_from_addr:
+ * @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token
+ * @addr: token encoded as %in6_addr
+ *
+ * Converts the %in6_addr encoded token (as used by Linux platform) to
+ * the interface identifier.
+ */
void
-nm_utils_ipv6_interface_identfier_get_from_addr (NMUtilsIPv6IfaceId *iid,
+nm_utils_ipv6_interface_identifier_get_from_addr (NMUtilsIPv6IfaceId *iid,
const struct in6_addr *addr)
{
memcpy (iid, addr->s6_addr + 8, 8);
}
+/**
+ * nm_utils_ipv6_interface_identifier_get_from_token:
+ * @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token
+ * @token: token encoded as string
+ *
+ * Converts the %in6_addr encoded token (as used in ip6 settings) to
+ * the interface identifier.
+ *
+ * Returns: %TRUE if the @token is a valid token, %FALSE otherwise
+ */
+gboolean
+nm_utils_ipv6_interface_identifier_get_from_token (NMUtilsIPv6IfaceId *iid,
+ const char *token)
+{
+ struct in6_addr i6_token;
+
+ g_return_val_if_fail (token, FALSE);
+
+ if (!inet_pton (AF_INET6, token, &i6_token))
+ return FALSE;
+
+ if (!_nm_utils_inet6_is_token (&i6_token))
+ return FALSE;
+
+ nm_utils_ipv6_interface_identifier_get_from_addr (iid, &i6_token);
+ return TRUE;
+}
+
+/**
+ * nm_utils_inet6_interface_identifier_to_token:
+ * @iid: %NMUtilsIPv6IfaceId interface identifier
+ * @buf: the destination buffer or %NULL
+ *
+ * Converts the interface identifier to a string token.
+ * If the destination buffer it set, set it is used to store the
+ * resulting token, otherwise an internal static buffer is used.
+ * The buffer needs to be %NM_UTILS_INET_ADDRSTRLEN characters long.
+ *
+ * Returns: a statically allocated array. Do not g_free().
+ */
+const char *
+nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid, char *buf)
+{
+ struct in6_addr i6_token = { .s6_addr = { 0, } };
+
+ nm_utils_ipv6_addr_set_interface_identifier (&i6_token, iid);
+ return nm_utils_inet6_ntop (&i6_token, buf);
+}
+
+/*****************************************************************************/
+
static gboolean
_set_stable_privacy (struct in6_addr *addr,
const char *ifname,
diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h
index 7a0f909bc4..a203a8ef71 100644
--- a/src/nm-core-utils.h
+++ b/src/nm-core-utils.h
@@ -335,24 +335,30 @@ struct _NMUtilsIPv6IfaceId {
#define NM_UTILS_IPV6_IFACE_ID_INIT { { .id = 0 } }
+void nm_utils_ipv6_addr_set_interface_identifier (struct in6_addr *addr,
+ const NMUtilsIPv6IfaceId iid);
+
+void nm_utils_ipv6_interface_identifier_get_from_addr (NMUtilsIPv6IfaceId *iid,
+ const struct in6_addr *addr);
+
+gboolean nm_utils_ipv6_interface_identifier_get_from_token (NMUtilsIPv6IfaceId *iid,
+ const char *token);
+
+const char *nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid,
+ char *buf);
+
gboolean nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
const guint8 *hwaddr,
guint len,
guint dev_id,
NMUtilsIPv6IfaceId *out_iid);
-void nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr,
- const NMUtilsIPv6IfaceId iid);
-
gboolean nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr,
const char *ifname,
const char *uuid,
guint dad_counter,
GError **error);
-void nm_utils_ipv6_interface_identfier_get_from_addr (NMUtilsIPv6IfaceId *iid,
- const struct in6_addr *addr);
-
void nm_utils_array_remove_at_indexes (GArray *array, const guint *indexes_to_delete, gsize len);
void nm_utils_setpgid (gpointer unused);
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 2c20d77c57..4e41bc9b27 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -798,9 +798,10 @@ _nl_nlmsg_type_to_str (guint16 type, char *buf, gsize len)
static gboolean
_parse_af_inet6 (NMPlatform *platform,
struct nlattr *attr,
- NMUtilsIPv6IfaceId *out_iid,
- guint8 *out_iid_is_valid,
- guint8 *out_addr_gen_mode_inv)
+ NMUtilsIPv6IfaceId *out_token,
+ gboolean *out_token_valid,
+ guint8 *out_addr_gen_mode_inv,
+ gboolean *out_addr_gen_mode_valid)
{
static struct nla_policy policy[IFLA_INET6_MAX+1] = {
[IFLA_INET6_FLAGS] = { .type = NLA_U32 },
@@ -814,7 +815,8 @@ _parse_af_inet6 (NMPlatform *platform,
struct nlattr *tb[IFLA_INET6_MAX+1];
int err;
struct in6_addr i6_token;
- gboolean iid_is_valid = FALSE;
+ gboolean token_valid = FALSE;
+ gboolean addr_gen_mode_valid = FALSE;
guint8 i6_addr_gen_mode_inv = 0;
gboolean success = FALSE;
@@ -831,8 +833,7 @@ _parse_af_inet6 (NMPlatform *platform,
if (_check_addr_or_errout (tb, IFLA_INET6_TOKEN, sizeof (struct in6_addr))) {
nla_memcpy (&i6_token, tb[IFLA_INET6_TOKEN], sizeof (struct in6_addr));
- if (!IN6_IS_ADDR_UNSPECIFIED (&i6_token))
- iid_is_valid = TRUE;
+ token_valid = TRUE;
}
/* Hack to detect support addrgenmode of the kernel. We only parse
@@ -847,21 +848,18 @@ _parse_af_inet6 (NMPlatform *platform,
* to signal "unset". */
goto errout;
}
+ addr_gen_mode_valid = TRUE;
}
success = TRUE;
- if (iid_is_valid) {
- out_iid->id_u8[7] = i6_token.s6_addr[15];
- out_iid->id_u8[6] = i6_token.s6_addr[14];
- out_iid->id_u8[5] = i6_token.s6_addr[13];
- out_iid->id_u8[4] = i6_token.s6_addr[12];
- out_iid->id_u8[3] = i6_token.s6_addr[11];
- out_iid->id_u8[2] = i6_token.s6_addr[10];
- out_iid->id_u8[1] = i6_token.s6_addr[9];
- out_iid->id_u8[0] = i6_token.s6_addr[8];
- *out_iid_is_valid = TRUE;
+ if (token_valid) {
+ *out_token_valid = token_valid;
+ nm_utils_ipv6_interface_identifier_get_from_addr (out_token, &i6_token);
+ }
+ if (addr_gen_mode_valid) {
+ *out_addr_gen_mode_valid = addr_gen_mode_valid;
+ *out_addr_gen_mode_inv = i6_addr_gen_mode_inv;
}
- *out_addr_gen_mode_inv = i6_addr_gen_mode_inv;
errout:
return success;
}
@@ -1436,6 +1434,8 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
NMPObject *lnk_data = NULL;
gboolean address_complete_from_cache = TRUE;
gboolean lnk_data_complete_from_cache = TRUE;
+ gboolean af_inet6_token_valid = FALSE;
+ gboolean af_inet6_addr_gen_mode_valid = FALSE;
if (!nlmsg_valid_hdr (nlh, sizeof (*ifi)))
return NULL;
@@ -1512,9 +1512,10 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
case AF_INET6:
_parse_af_inet6 (platform,
af_attr,
- &obj->link.inet6_token.iid,
- &obj->link.inet6_token.is_valid,
- &obj->link.inet6_addr_gen_mode_inv);
+ &obj->link.inet6_token,
+ &af_inet6_token_valid,
+ &obj->link.inet6_addr_gen_mode_inv,
+ &af_inet6_addr_gen_mode_valid);
break;
}
}
@@ -1556,7 +1557,9 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
if ( completed_from_cache
&& ( lnk_data_complete_from_cache
- || address_complete_from_cache)) {
+ || address_complete_from_cache
+ || !af_inet6_token_valid
+ || !af_inet6_addr_gen_mode_valid)) {
_lookup_cached_link (cache, obj->link.ifindex, completed_from_cache, &link_cached);
if (link_cached) {
if ( lnk_data_complete_from_cache
@@ -1575,6 +1578,10 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
}
if (address_complete_from_cache)
obj->link.addr = link_cached->link.addr;
+ if (!af_inet6_token_valid)
+ obj->link.inet6_token = link_cached->link.inet6_token;
+ if (!af_inet6_addr_gen_mode_valid)
+ obj->link.inet6_addr_gen_mode_inv = link_cached->link.inet6_addr_gen_mode_inv;
}
}
@@ -1947,7 +1954,8 @@ nmp_object_new_from_nl (NMPlatform *platform, const NMPCache *cache, struct nl_m
static gboolean
_nl_msg_new_link_set_afspec (struct nl_msg *msg,
- int addr_gen_mode)
+ int addr_gen_mode,
+ NMUtilsIPv6IfaceId *iid)
{
struct nlattr *af_spec;
struct nlattr *af_attr;
@@ -1957,11 +1965,19 @@ _nl_msg_new_link_set_afspec (struct nl_msg *msg,
if (!(af_spec = nla_nest_start (msg, IFLA_AF_SPEC)))
goto nla_put_failure;
- if (addr_gen_mode >= 0) {
+ if (addr_gen_mode >= 0 || iid) {
if (!(af_attr = nla_nest_start (msg, AF_INET6)))
goto nla_put_failure;
- NLA_PUT_U8 (msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode);
+ if (addr_gen_mode >= 0)
+ NLA_PUT_U8 (msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode);
+
+ if (iid) {
+ struct in6_addr i6_token = { .s6_addr = { 0, } };
+
+ nm_utils_ipv6_addr_set_interface_identifier (&i6_token, *iid);
+ NLA_PUT (msg, IFLA_INET6_TOKEN, sizeof (struct in6_addr), &i6_token);
+ }
nla_nest_end (msg, af_attr);
}
@@ -4322,8 +4338,22 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable
0,
0);
if ( !nlmsg
- || !_nl_msg_new_link_set_afspec (nlmsg,
- mode))
+ || !_nl_msg_new_link_set_afspec (nlmsg, mode, NULL))
+ g_return_val_if_reached (FALSE);
+
+ return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS;
+}
+
+static gboolean
+link_set_token (NMPlatform *platform, int ifindex, NMUtilsIPv6IfaceId iid)
+{
+ nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
+
+ _LOGD ("link: change %d: token: set IPv6 address generation token to %s",
+ ifindex, nm_utils_inet6_interface_identifier_to_token (iid, NULL));
+
+ nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, NULL, 0, 0);
+ if (!nlmsg || !_nl_msg_new_link_set_afspec (nlmsg, -1, &iid))
g_return_val_if_reached (FALSE);
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS;
@@ -6435,6 +6465,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->link_get_udev_device = link_get_udev_device;
platform_class->link_set_user_ipv6ll_enabled = link_set_user_ipv6ll_enabled;
+ platform_class->link_set_token = link_set_token;
platform_class->link_set_address = link_set_address;
platform_class->link_get_permanent_address = link_get_permanent_address;
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 500db9b621..a6afcf33a9 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -900,33 +900,25 @@ nm_platform_link_uses_arp (NMPlatform *self, int ifindex)
}
/**
- * nm_platform_link_get_ipv6_token:
+ * nm_platform_link_set_ipv6_token:
* @self: platform instance
* @ifindex: Interface index
* @iid: Tokenized interface identifier
*
- * Returns IPv6 tokenized interface identifier. If the platform or OS doesn't
- * support IPv6 tokenized interface identifiers, or the token is not set
- * this call will fail and return %FALSE.
+ * Sets then IPv6 tokenized interface identifier.
*
* Returns: %TRUE a tokenized identifier was available
*/
gboolean
-nm_platform_link_get_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId *iid)
+nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid)
{
- const NMPlatformLink *pllink;
-
_CHECK_SELF (self, klass, FALSE);
g_return_val_if_fail (ifindex >= 0, FALSE);
- g_return_val_if_fail (iid, FALSE);
-
+ g_return_val_if_fail (iid.id, FALSE);
- pllink = nm_platform_link_get (self, ifindex);
- if (pllink && pllink->inet6_token.is_valid) {
- *iid = pllink->inet6_token.iid;
- return TRUE;
- }
+ if (klass->link_set_token)
+ return klass->link_set_token (self, ifindex, iid);
return FALSE;
}
@@ -3067,7 +3059,7 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len)
GString *str_flags;
char str_addrmode[30];
gs_free char *str_addr = NULL;
- gs_free char *str_inet6_token = NULL;
+ char str_inet6_token[NM_UTILS_INET_ADDRSTRLEN];
const char *str_link_type;
if (!nm_utils_to_string_buffer_init_null (link, &buf, &len))
@@ -3104,8 +3096,6 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len)
if (link->addr.len)
str_addr = nm_utils_hwaddr_ntoa (link->addr.data, MIN (link->addr.len, sizeof (link->addr.data)));
- if (link->inet6_token.is_valid)
- str_inet6_token = nm_utils_hwaddr_ntoa (&link->inet6_token.iid, sizeof (link->inet6_token.iid));
str_link_type = nm_link_type_to_string (link->type);
@@ -3139,8 +3129,8 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len)
link->inet6_addr_gen_mode_inv ? nm_platform_link_inet6_addrgenmode2str (_nm_platform_uint8_inv (link->inet6_addr_gen_mode_inv), str_addrmode, sizeof (str_addrmode)) : "",
str_addr ? " addr " : "",
str_addr ? str_addr : "",
- str_inet6_token ? " inet6token " : "",
- str_inet6_token ? str_inet6_token : "",
+ link->inet6_token.id ? " inet6token " : "",
+ link->inet6_token.id ? nm_utils_inet6_interface_identifier_to_token (link->inet6_token, str_inet6_token) : "",
link->driver ? " driver " : "",
link->driver ? link->driver : "");
g_string_free (str_flags, TRUE);
@@ -3798,13 +3788,11 @@ nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b)
_CMP_FIELD (a, b, arptype);
_CMP_FIELD (a, b, addr.len);
_CMP_FIELD (a, b, inet6_addr_gen_mode_inv);
- _CMP_FIELD (a, b, inet6_token.is_valid);
_CMP_FIELD_STR_INTERNED (a, b, kind);
_CMP_FIELD_STR_INTERNED (a, b, driver);
if (a->addr.len)
_CMP_FIELD_MEMCMP_LEN (a, b, addr.data, a->addr.len);
- if (a->inet6_token.is_valid)
- _CMP_FIELD_MEMCMP (a, b, inet6_token.iid);
+ _CMP_FIELD_MEMCMP (a, b, inet6_token);
return 0;
}
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index ed21632836..72f4f6720a 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -147,11 +147,8 @@ struct _NMPlatformLink {
guint8 len;
} addr;
- /* rtnl_link_inet6_get_token() */
- struct {
- NMUtilsIPv6IfaceId iid;
- guint8 is_valid;
- } inet6_token;
+ /* rtnl_link_inet6_get_token(), IFLA_INET6_TOKEN */
+ NMUtilsIPv6IfaceId inet6_token;
/* The bitwise inverse of rtnl_link_inet6_get_addr_gen_mode(). It is inverse
* to have a default of 0 -- meaning: unspecified. That way, a struct
@@ -523,6 +520,7 @@ typedef struct {
GObject *(*link_get_udev_device) (NMPlatform *self, int ifindex);
gboolean (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled);
+ gboolean (*link_set_token) (NMPlatform *, int ifindex, NMUtilsIPv6IfaceId iid);
gboolean (*link_get_permanent_address) (NMPlatform *,
int ifindex,
@@ -733,7 +731,6 @@ gboolean nm_platform_link_is_up (NMPlatform *self, int ifindex);
gboolean nm_platform_link_is_connected (NMPlatform *self, int ifindex);
gboolean nm_platform_link_uses_arp (NMPlatform *self, int ifindex);
guint32 nm_platform_link_get_mtu (NMPlatform *self, int ifindex);
-gboolean nm_platform_link_get_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId *iid);
gboolean nm_platform_link_get_user_ipv6ll_enabled (NMPlatform *self, int ifindex);
gconstpointer nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length);
int nm_platform_link_get_master (NMPlatform *self, int slave);
@@ -757,6 +754,7 @@ const char *nm_platform_link_get_udi (NMPlatform *self, int ifindex);
GObject *nm_platform_link_get_udev_device (NMPlatform *self, int ifindex);
gboolean nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled);
+gboolean nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid);
gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length);
gboolean nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length);
diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c
index b8860b9eb0..a51f7cfa6c 100644
--- a/src/ppp-manager/nm-ppp-manager.c
+++ b/src/ppp-manager/nm-ppp-manager.c
@@ -540,7 +540,7 @@ iid_value_to_ll6_addr (GVariant *dict,
out_addr->s6_addr16[0] = htons (0xfe80);
memcpy (out_addr->s6_addr + 8, &iid, sizeof (iid));
if (out_iid)
- nm_utils_ipv6_interface_identfier_get_from_addr (out_iid, out_addr);
+ nm_utils_ipv6_interface_identifier_get_from_addr (out_iid, out_addr);
return TRUE;
}
diff --git a/src/rdisc/nm-rdisc.c b/src/rdisc/nm-rdisc.c
index 12e3962b0d..85c803dc79 100644
--- a/src/rdisc/nm-rdisc.c
+++ b/src/rdisc/nm-rdisc.c
@@ -161,7 +161,7 @@ complete_address (NMRDisc *rdisc, NMRDiscAddress *addr)
if (addr->address.s6_addr32[2] == 0x0 && addr->address.s6_addr32[3] == 0x0) {
_LOGD ("complete-address: adding an EUI-64 address");
- nm_utils_ipv6_addr_set_interface_identfier (&addr->address, rdisc->iid);
+ nm_utils_ipv6_addr_set_interface_identifier (&addr->address, rdisc->iid);
return TRUE;
}
diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
index 240149b3e3..b933e1a5fa 100644
--- a/src/settings/plugins/ifcfg-rh/reader.c
+++ b/src/settings/plugins/ifcfg-rh/reader.c
@@ -1527,6 +1527,13 @@ make_ip6_setting (shvarFile *ifcfg,
NULL);
}
+ /* IPv6 tokenized interface identifier */
+ tmp = svGetValue (ifcfg, "IPV6_TOKEN", FALSE);
+ if (tmp) {
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, tmp, NULL);
+ g_free (tmp);
+ }
+
/* DNS servers
* Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting())
*/
diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c
index 55ef2cc766..2864078a48 100644
--- a/src/settings/plugins/ifcfg-rh/writer.c
+++ b/src/settings/plugins/ifcfg-rh/writer.c
@@ -2623,8 +2623,14 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
addr_gen_mode);
svSetValue (ifcfg, "IPV6_ADDR_GEN_MODE", tmp, FALSE);
g_free (tmp);
+ } else {
+ svSetValue (ifcfg, "IPV6_ADDR_GEN_MODE", NULL, FALSE);
}
+ /* IPv6 tokenized interface identifier */
+ value = nm_setting_ip6_config_get_token (NM_SETTING_IP6_CONFIG (s_ip6));
+ svSetValue (ifcfg, "IPV6_TOKEN", value, FALSE);
+
priority = nm_setting_ip_config_get_dns_priority (s_ip6);
if (priority)
svSetValueInt64 (ifcfg, "IPV6_DNS_PRIORITY", priority);