core: support renaming of NMDevice (changes of ifname)
https://bugzilla.gnome.org/show_bug.cgi?id=726177 https://bugzilla.redhat.com/show_bug.cgi?id=907836 Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
@@ -79,6 +79,7 @@ void nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout);
|
||||
void nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr);
|
||||
|
||||
gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release);
|
||||
gboolean nm_device_dhcp6_renew (NMDevice *device, gboolean release);
|
||||
|
||||
void nm_device_recheck_available_connections (NMDevice *device);
|
||||
|
||||
|
@@ -339,6 +339,7 @@ static gboolean spec_match_list (NMDevice *device, const GSList *specs);
|
||||
static void _clear_available_connections (NMDevice *device, gboolean do_signal);
|
||||
|
||||
static void dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release);
|
||||
static void dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release);
|
||||
|
||||
static const char *reason_to_string (NMDeviceStateReason reason);
|
||||
|
||||
@@ -1121,32 +1122,96 @@ link_changed_cb (NMPlatform *platform, int ifindex, NMPlatformLink *info, NMPlat
|
||||
{
|
||||
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (device);
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
|
||||
int my_ifindex = nm_device_get_ifindex (device);
|
||||
gboolean change_ip_ifname = FALSE;
|
||||
|
||||
/* Ignore other devices. */
|
||||
if (ifindex != nm_device_get_ifindex (device))
|
||||
return;
|
||||
if (ifindex == my_ifindex) {
|
||||
|
||||
/* We don't filter by 'reason' because we are interested in *all* link
|
||||
* changes. For example a call to nm_platform_link_set_up() may result
|
||||
* in an internal carrier change (i.e. we ask the kernel to set IFF_UP
|
||||
* and it results in also setting IFF_LOWER_UP.
|
||||
*/
|
||||
/* We don't filter by 'reason' because we are interested in *all* link
|
||||
* changes. For example a call to nm_platform_link_set_up() may result
|
||||
* in an internal carrier change (i.e. we ask the kernel to set IFF_UP
|
||||
* and it results in also setting IFF_LOWER_UP.
|
||||
*/
|
||||
|
||||
if (info->udi && g_strcmp0 (info->udi, priv->udi)) {
|
||||
/* Update UDI to what udev gives us */
|
||||
g_free (priv->udi);
|
||||
priv->udi = g_strdup (info->udi);
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_UDI);
|
||||
if (info->udi && g_strcmp0 (info->udi, priv->udi)) {
|
||||
/* Update UDI to what udev gives us */
|
||||
g_free (priv->udi);
|
||||
priv->udi = g_strdup (info->udi);
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_UDI);
|
||||
}
|
||||
|
||||
/* Update MTU if it has changed. */
|
||||
if (priv->mtu != info->mtu) {
|
||||
priv->mtu = info->mtu;
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_MTU);
|
||||
}
|
||||
|
||||
if (info->name[0] && strcmp (priv->iface, info->name) != 0) {
|
||||
nm_log_info (LOGD_DEVICE, "(%s): interface index %d renamed iface from '%s' to '%s'",
|
||||
priv->iface, my_ifindex, priv->iface, info->name);
|
||||
g_free (priv->iface);
|
||||
priv->iface = g_strdup (info->name);
|
||||
|
||||
change_ip_ifname = !priv->ip_iface;
|
||||
if (change_ip_ifname)
|
||||
g_hash_table_remove_all (priv->ip6_saved_properties);
|
||||
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_IFACE);
|
||||
if (change_ip_ifname)
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_IP_IFACE);
|
||||
|
||||
/* Re-match available connections against the new interface name */
|
||||
nm_device_recheck_available_connections (device);
|
||||
|
||||
/* Let any connections that use the new interface name have a chance
|
||||
* to auto-activate on the device.
|
||||
*/
|
||||
nm_device_emit_recheck_auto_activate (device);
|
||||
}
|
||||
|
||||
if (klass->link_changed)
|
||||
klass->link_changed (device, info);
|
||||
|
||||
} else if (priv->ip_iface && ifindex == nm_device_get_ip_ifindex (device)) {
|
||||
if (info->name[0] && strcmp (priv->ip_iface, info->name)) {
|
||||
nm_log_info (LOGD_DEVICE, "(%s): interface index %d renamed ip_iface (%d) from '%s' to '%s'",
|
||||
priv->iface, my_ifindex, nm_device_get_ip_ifindex (device),
|
||||
priv->ip_iface, info->name);
|
||||
g_free (priv->ip_iface);
|
||||
priv->ip_iface = g_strdup (info->name);
|
||||
|
||||
g_hash_table_remove_all (priv->ip6_saved_properties);
|
||||
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_IP_IFACE);
|
||||
change_ip_ifname = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update MTU if it has changed. */
|
||||
if (priv->mtu != info->mtu) {
|
||||
priv->mtu = info->mtu;
|
||||
g_object_notify (G_OBJECT (device), NM_DEVICE_MTU);
|
||||
if (change_ip_ifname) {
|
||||
if (priv->dhcp4_client) {
|
||||
if (!nm_device_dhcp4_renew (device, FALSE)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_DHCP_FAILED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (priv->dhcp6_client) {
|
||||
if (!nm_device_dhcp6_renew (device, FALSE)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_DHCP_FAILED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (priv->rdisc) {
|
||||
/* FIXME: todo */
|
||||
}
|
||||
if (priv->dnsmasq_manager) {
|
||||
/* FIXME: todo */
|
||||
}
|
||||
}
|
||||
|
||||
if (klass->link_changed)
|
||||
klass->link_changed (device, info);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3167,6 +3232,31 @@ dhcp6_start (NMDevice *self,
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_device_dhcp6_renew (NMDevice *self, gboolean release)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMActStageReturn ret;
|
||||
NMDeviceStateReason reason;
|
||||
NMConnection *connection;
|
||||
|
||||
g_return_val_if_fail (priv->dhcp6_client != NULL, FALSE);
|
||||
|
||||
nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 lease renewal requested",
|
||||
nm_device_get_iface (self));
|
||||
|
||||
/* Terminate old DHCP instance and release the old lease */
|
||||
dhcp6_cleanup (self, TRUE, release);
|
||||
|
||||
connection = nm_device_get_connection (self);
|
||||
g_assert (connection);
|
||||
|
||||
/* Start DHCP again on the interface */
|
||||
ret = dhcp6_start (self, connection, priv->dhcp6_mode, &reason);
|
||||
|
||||
return (ret != NM_ACT_STAGE_RETURN_FAILURE);
|
||||
}
|
||||
|
||||
/******************************************/
|
||||
|
||||
static gboolean
|
||||
|
Reference in New Issue
Block a user