ip6: fail if the RA-provided address disappears or RDNSS expires

This commit is contained in:
Dan Williams 2010-05-03 03:02:57 -07:00
parent c21416e956
commit 10d6bc8d2e
3 changed files with 32 additions and 6 deletions

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}