From 10d6bc8d2ecbe996091b0c224ba14b7fdfe9123f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 3 May 2010 03:02:57 -0700 Subject: [PATCH] ip6: fail if the RA-provided address disappears or RDNSS expires --- src/ip6-manager/nm-ip6-manager.c | 27 ++++++++++++++++++++++----- src/ip6-manager/nm-ip6-manager.h | 3 ++- src/nm-device.c | 8 ++++++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c index 1b544a2449..5101faf2a8 100644 --- a/src/ip6-manager/nm-ip6-manager.c +++ b/src/ip6-manager/nm-ip6-manager.c @@ -282,7 +282,10 @@ emit_config_changed (gpointer user_data) NMIP6Manager *manager = device->manager; device->config_changed_id = 0; - g_signal_emit (manager, signals[CONFIG_CHANGED], 0, device->ifindex, info->dhcp_opts); + g_signal_emit (manager, signals[CONFIG_CHANGED], 0, + device->ifindex, + info->dhcp_opts, + info->success); return FALSE; } @@ -386,7 +389,7 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed) struct in6_addr *addr; CallbackInfo *info; guint dhcp_opts = IP6_DHCP_OPT_NONE; - gboolean found_linklocal = FALSE; + gboolean found_linklocal = FALSE, found_other = FALSE; nm_log_dbg (LOGD_IP6, "(%s): syncing with netlink (ra_flags 0x%X) (state/target '%s'/'%s')", device->iface, device->ra_flags, @@ -420,6 +423,7 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed) } else { if (device->state < NM_IP6_DEVICE_GOT_ADDRESS) device->state = NM_IP6_DEVICE_GOT_ADDRESS; + found_other = TRUE; } } @@ -473,7 +477,20 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed) } } else if (config_changed) { if (!device->config_changed_id) { - info = callback_info_new (device, dhcp_opts, TRUE); + gboolean success = TRUE; + + /* If for some reason an RA-provided address disappeared, we need + * to make sure we fail the connection as it's no longer valid. + */ + if ( (device->state == NM_IP6_DEVICE_GOT_ADDRESS) + && (device->target_state == NM_IP6_DEVICE_GOT_ADDRESS) + && !found_other) { + nm_log_dbg (LOGD_IP6, "(%s): RA-provided address no longer valid", + device->iface); + success = FALSE; + } + + info = callback_info_new (device, dhcp_opts, success); device->config_changed_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, emit_config_changed, info, @@ -1141,7 +1158,7 @@ nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMIP6ManagerClass, config_changed), NULL, NULL, - _nm_marshal_VOID__INT_UINT, - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT); + _nm_marshal_VOID__INT_UINT_BOOLEAN, + G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_UINT, G_TYPE_BOOLEAN); } diff --git a/src/ip6-manager/nm-ip6-manager.h b/src/ip6-manager/nm-ip6-manager.h index db920662b9..7cd0ef70e6 100644 --- a/src/ip6-manager/nm-ip6-manager.h +++ b/src/ip6-manager/nm-ip6-manager.h @@ -64,7 +64,8 @@ typedef struct { */ void (*config_changed) (NMIP6Manager *manager, guint32 ifindex, - guint dhcp_opts); + guint dhcp_opts, + gboolean success); } NMIP6ManagerClass; GType nm_ip6_manager_get_type (void); diff --git a/src/nm-device.c b/src/nm-device.c index a09a69218f..d8f7b64f02 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -681,6 +681,7 @@ static void ip6_config_changed (NMIP6Manager *ip6_manager, int ifindex, guint dhcp_opts, + gboolean success, gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); @@ -692,6 +693,13 @@ ip6_config_changed (NMIP6Manager *ip6_manager, /* FIXME: re-run DHCPv6 here to get any new nameservers or whatever */ + if (!success && (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED)) { + nm_device_state_changed (self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return; + } + nm_device_activate_schedule_stage4_ip6_config_get (self); }