From f9bd97020d429264cbe2b0aadd85566acf6e02f0 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 14 Jan 2010 22:57:51 -0800 Subject: [PATCH] ipv6: push router advertisement flags to listeners --- marshallers/nm-marshal.list | 1 + src/ip6-manager/nm-ip6-manager.c | 78 ++++++++++++++++++++++---------- src/ip6-manager/nm-ip6-manager.h | 15 +++++- src/nm-device.c | 12 +++-- 4 files changed, 76 insertions(+), 30 deletions(-) diff --git a/marshallers/nm-marshal.list b/marshallers/nm-marshal.list index 38669dd32..36e0fbe6d 100644 --- a/marshallers/nm-marshal.list +++ b/marshallers/nm-marshal.list @@ -16,6 +16,7 @@ VOID:STRING,STRING,STRING,UINT VOID:OBJECT,UINT,UINT VOID:STRING,INT VOID:STRING,UINT +VOID:STRING,UINT,BOOLEAN VOID:OBJECT,OBJECT,ENUM VOID:POINTER,STRING VOID:STRING,BOXED diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c index f41169cb1..20e1a7f93 100644 --- a/src/ip6-manager/nm-ip6-manager.c +++ b/src/ip6-manager/nm-ip6-manager.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 Red Hat, Inc. + * Copyright (C) 2009 - 2010 Red Hat, Inc. */ #include @@ -165,10 +165,8 @@ nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMIP6ManagerClass, addrconf_complete), NULL, NULL, - _nm_marshal_VOID__STRING_BOOLEAN, - G_TYPE_NONE, 2, - G_TYPE_STRING, - G_TYPE_BOOLEAN); + _nm_marshal_VOID__STRING_UINT_BOOLEAN, + G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_BOOLEAN); signals[CONFIG_CHANGED] = g_signal_new ("config-changed", @@ -176,9 +174,8 @@ nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMIP6ManagerClass, config_changed), NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); + _nm_marshal_VOID__STRING_UINT, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT); } static void @@ -233,10 +230,16 @@ nm_ip6_manager_get_device (NMIP6Manager *manager, int ifindex) GINT_TO_POINTER (ifindex)); } +typedef struct { + NMIP6Device *device; + guint dhcp_opts; +} CallbackInfo; + static gboolean finish_addrconf (gpointer user_data) { - NMIP6Device *device = user_data; + CallbackInfo *info = user_data; + NMIP6Device *device = info->device; NMIP6Manager *manager = device->manager; char *iface_copy; @@ -245,7 +248,7 @@ finish_addrconf (gpointer user_data) if (device->state >= device->target_state) { g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0, - device->iface, TRUE); + device->iface, info->dhcp_opts, TRUE); } else { nm_info ("Device '%s' IP6 addrconf timed out or failed.", device->iface); @@ -254,7 +257,7 @@ finish_addrconf (gpointer user_data) nm_ip6_manager_cancel_addrconf (manager, device->iface); g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0, - iface_copy, FALSE); + iface_copy, info->dhcp_opts, FALSE); g_free (iface_copy); } @@ -265,11 +268,12 @@ finish_addrconf (gpointer user_data) static gboolean emit_config_changed (gpointer user_data) { - NMIP6Device *device = user_data; + CallbackInfo *info = user_data; + NMIP6Device *device = info->device; NMIP6Manager *manager = device->manager; device->config_changed_id = 0; - g_signal_emit (manager, signals[CONFIG_CHANGED], 0, device->iface); + g_signal_emit (manager, signals[CONFIG_CHANGED], 0, device->iface, info->dhcp_opts); return FALSE; } @@ -279,9 +283,10 @@ static gboolean rdnss_expired (gpointer user_data) { NMIP6Device *device = user_data; + CallbackInfo info = { device, IP6_DHCP_OPT_NONE }; set_rdnss_timeout (device); - emit_config_changed (device); + emit_config_changed (&info); return FALSE; } @@ -323,6 +328,18 @@ set_rdnss_timeout (NMIP6Device *device) } } +static CallbackInfo * +callback_info_new (NMIP6Device *device, guint dhcp_opts) +{ + CallbackInfo *info; + + info = g_malloc0 (sizeof (CallbackInfo)); + info->device = device; + info->dhcp_opts = dhcp_opts; + + return info; +} + static void nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed) { @@ -333,6 +350,8 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed) struct in6_addr *addr; struct rtnl_link *link; guint flags; + CallbackInfo *info; + guint dhcp_opts = IP6_DHCP_OPT_NONE; for (rtnladdr = (struct rtnl_addr *)nl_cache_get_first (priv->addr_cache); rtnladdr; @@ -365,8 +384,10 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed) if ((flags & IF_RA_RCVD) && device->state < NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT) device->state = NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT; -// if (flags & (IF_RA_MANAGED | IF_RA_OTHERCONF)) -// device->need_dhcp = TRUE; + if (flags & IF_RA_MANAGED) + dhcp_opts = IP6_DHCP_OPT_MANAGED; + else if (flags & IF_RA_OTHERCONF) + dhcp_opts = IP6_DHCP_OPT_OTHERCONF; if (!device->addrconf_complete) { if (device->state >= device->target_state || @@ -376,13 +397,20 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed) */ if (device->finish_addrconf_id) g_source_remove (device->finish_addrconf_id); - device->finish_addrconf_id = g_idle_add (finish_addrconf, - device); + + info = callback_info_new (device, dhcp_opts); + device->finish_addrconf_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, + finish_addrconf, + info, + (GDestroyNotify) g_free); } } else if (config_changed) { if (!device->config_changed_id) { - device->config_changed_id = g_idle_add (emit_config_changed, - device); + info = callback_info_new (device, dhcp_opts); + device->config_changed_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, + emit_config_changed, + info, + (GDestroyNotify) g_free); } } } @@ -717,6 +745,7 @@ nm_ip6_manager_begin_addrconf (NMIP6Manager *manager, { NMIP6ManagerPrivate *priv; NMIP6Device *device; + CallbackInfo *info; g_return_if_fail (NM_IS_IP6_MANAGER (manager)); g_return_if_fail (iface != NULL); @@ -731,9 +760,12 @@ nm_ip6_manager_begin_addrconf (NMIP6Manager *manager, device->addrconf_complete = FALSE; /* Set up a timeout on the transaction to kill it after the timeout */ - device->finish_addrconf_id = g_timeout_add_seconds (NM_IP6_TIMEOUT, - finish_addrconf, - device); + info = callback_info_new (device, 0); + device->finish_addrconf_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, + NM_IP6_TIMEOUT, + finish_addrconf, + info, + (GDestroyNotify) g_free); /* Sync flags, etc, from netlink; this will also notice if the * device is already fully configured and schedule the diff --git a/src/ip6-manager/nm-ip6-manager.h b/src/ip6-manager/nm-ip6-manager.h index 33b2b9893..d0cf4b08a 100644 --- a/src/ip6-manager/nm-ip6-manager.h +++ b/src/ip6-manager/nm-ip6-manager.h @@ -35,6 +35,12 @@ #define NM_IS_IP6_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IP6_MANAGER)) #define NM_IP6_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IP6_MANAGER, NMIP6ManagerClass)) +enum { + IP6_DHCP_OPT_NONE = 0, + IP6_DHCP_OPT_OTHERCONF, + IP6_DHCP_OPT_MANAGED +}; + typedef struct { GObject parent; } NMIP6Manager; @@ -47,13 +53,18 @@ typedef struct { /* addrconf_complete is emitted only during initial configuration to indicate * that the initial configuration is complete. */ - void (*addrconf_complete) (NMIP6Manager *manager, char *iface, gboolean success); + void (*addrconf_complete) (NMIP6Manager *manager, + char *iface, + guint dhcp_opts, + gboolean success); /* config_changed gets emitted only *after* initial configuration is * complete; it's like DHCP renew and indicates that the existing config * of the interface has changed. */ - void (*config_changed) (NMIP6Manager *manager, char *iface); + void (*config_changed) (NMIP6Manager *manager, + char *iface, + guint dhcp_opts); } NMIP6ManagerClass; GType nm_ip6_manager_get_type (void); diff --git a/src/nm-device.c b/src/nm-device.c index daf3d111c..7700c7a10 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -535,9 +535,10 @@ activation_source_schedule (NMDevice *self, GSourceFunc func, int family) static void ip6_addrconf_complete (NMIP6Manager *ip6_manager, - const char *iface, - gboolean success, - gpointer user_data) + const char *iface, + guint dhcp_opts, + gboolean success, + gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -558,8 +559,9 @@ ip6_addrconf_complete (NMIP6Manager *ip6_manager, static void ip6_config_changed (NMIP6Manager *ip6_manager, - const char *iface, - gpointer user_data) + const char *iface, + guint dhcp_opts, + gpointer user_data) { NMDevice *self = NM_DEVICE (user_data);