summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2014-09-27 09:04:46 +0200
committerLubomir Rintel <lkundrak@v3.sk>2015-01-26 13:05:06 +0100
commit24e7ea786058597fdb45842377045e73ba8f923d (patch)
tree8b69ea09176d54a405768aa937278678a4b58a1c
parentdb5603e615f502e2fc96040e7f6b83a13fcb0f98 (diff)
downloadNetworkManager-24e7ea786058597fdb45842377045e73ba8f923d.tar.gz
core: Use tokenized identifiers when constructing an address
We trigger a new solicitation upon seeing the new token. Kernel triggers one too, but that one is of no use to us, since the advertisement might arrive sooner than we learn about the token change.
-rw-r--r--src/devices/nm-device.c14
-rw-r--r--src/rdisc/nm-rdisc.c32
-rw-r--r--src/rdisc/nm-rdisc.h2
3 files changed, 42 insertions, 6 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index caed116f51..9f5ca4b2bb 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1208,6 +1208,7 @@ device_link_changed (NMDevice *self, NMPlatformLink *info)
{
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ NMUtilsIPv6IfaceId token_iid;
gboolean ip_ifname_changed = FALSE;
if (info->udi && g_strcmp0 (info->udi, priv->udi)) {
@@ -1254,6 +1255,12 @@ device_link_changed (NMDevice *self, NMPlatformLink *info)
nm_device_enslave_slave (priv->master, self, NULL);
}
+ if (priv->rdisc && nm_platform_link_get_ipv6_token (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))
+ nm_rdisc_start (priv->rdisc);
+ }
+
if (klass->link_changed)
klass->link_changed (self, info);
@@ -4244,11 +4251,12 @@ addrconf6_start_with_link_ready (NMDevice *self)
g_assert (priv->rdisc);
- if (!nm_device_get_ip_iface_identifier (self, &iid)) {
+ if (nm_platform_link_get_ipv6_token (priv->ifindex, &iid)) {
+ _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
+ } else if (!nm_device_get_ip_iface_identifier (self, &iid)) {
_LOGW (LOGD_IP6, "failed to get interface identifier; IPv6 cannot continue");
return FALSE;
}
- nm_rdisc_set_iid (priv->rdisc, iid);
/* Apply any manual configuration before starting RA */
if (!ip6_config_merge_and_apply (self, TRUE, NULL))
@@ -4267,6 +4275,8 @@ addrconf6_start_with_link_ready (NMDevice *self)
NM_RDISC_RA_TIMEOUT,
G_CALLBACK (rdisc_ra_timeout),
self);
+
+ nm_rdisc_set_iid (priv->rdisc, iid);
nm_rdisc_start (priv->rdisc);
return TRUE;
}
diff --git a/src/rdisc/nm-rdisc.c b/src/rdisc/nm-rdisc.c
index 8729fa63df..58040c9d43 100644
--- a/src/rdisc/nm-rdisc.c
+++ b/src/rdisc/nm-rdisc.c
@@ -42,12 +42,38 @@ static guint signals[LAST_SIGNAL] = { 0 };
/******************************************************************/
-void
+/**
+ * nm_rdisc_set_iid:
+ * @rdisc: the #NMRDisc
+ * @iid: the new interface ID
+ *
+ * Sets the "Modified EUI-64" interface ID to be used when generating
+ * IPv6 addresses using received prefixes. Identifiers are either generated
+ * from the hardware addresses or manually set by the operator with
+ * "ip token" command.
+ *
+ * Upon token change (or initial setting) all addresses generated using
+ * the old identifier are removed. The caller should ensure the addresses
+ * will be reset by soliciting router advertisements.
+ *
+ * Returns: %TRUE if the token was changed, %FALSE otherwise.
+ **/
+gboolean
nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid)
{
- g_return_if_fail (NM_IS_RDISC (rdisc));
+ g_return_val_if_fail (NM_IS_RDISC (rdisc), FALSE);
+
+ if (rdisc->iid.id != iid.id) {
+ rdisc->iid = iid;
+ if (rdisc->addresses->len) {
+ debug ("(%s) IPv6 interface identifier changed, flushing addresses", rdisc->ifname);
+ g_array_remove_range (rdisc->addresses, 0, rdisc->addresses->len);
+ g_signal_emit_by_name (rdisc, NM_RDISC_CONFIG_CHANGED, NM_RDISC_CONFIG_ADDRESSES);
+ }
+ return TRUE;
+ }
- rdisc->iid = iid;
+ return FALSE;
}
void
diff --git a/src/rdisc/nm-rdisc.h b/src/rdisc/nm-rdisc.h
index 2d83f0f020..8864c22f72 100644
--- a/src/rdisc/nm-rdisc.h
+++ b/src/rdisc/nm-rdisc.h
@@ -139,7 +139,7 @@ typedef struct {
GType nm_rdisc_get_type (void);
-void nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid);
+gboolean nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid);
void nm_rdisc_start (NMRDisc *rdisc);
#endif /* __NETWORKMANAGER_RDISC_H__ */