ipv6: push router advertisement flags to listeners
authorDan Williams <dcbw@redhat.com>
Fri, 15 Jan 2010 06:57:51 +0000 (22:57 -0800)
committerDan Williams <dcbw@redhat.com>
Fri, 15 Jan 2010 06:57:51 +0000 (22:57 -0800)
marshallers/nm-marshal.list
src/ip6-manager/nm-ip6-manager.c
src/ip6-manager/nm-ip6-manager.h
src/nm-device.c

index 38669dd..36e0fbe 100644 (file)
@@ -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
index f41169c..20e1a7f 100644 (file)
@@ -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 <errno.h>
@@ -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
index 33b2b98..d0cf4b0 100644 (file)
 #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);
index daf3d11..7700c7a 100644 (file)
@@ -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);