ipv6: push router advertisement flags to listeners

This commit is contained in:
Dan Williams
2010-01-14 22:57:51 -08:00
parent a9e32f3c3b
commit f9bd97020d
4 changed files with 76 additions and 30 deletions

View File

@@ -16,6 +16,7 @@ VOID:STRING,STRING,STRING,UINT
VOID:OBJECT,UINT,UINT VOID:OBJECT,UINT,UINT
VOID:STRING,INT VOID:STRING,INT
VOID:STRING,UINT VOID:STRING,UINT
VOID:STRING,UINT,BOOLEAN
VOID:OBJECT,OBJECT,ENUM VOID:OBJECT,OBJECT,ENUM
VOID:POINTER,STRING VOID:POINTER,STRING
VOID:STRING,BOXED VOID:STRING,BOXED

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 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> #include <errno.h>
@@ -165,10 +165,8 @@ nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class)
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMIP6ManagerClass, addrconf_complete), G_STRUCT_OFFSET (NMIP6ManagerClass, addrconf_complete),
NULL, NULL, NULL, NULL,
_nm_marshal_VOID__STRING_BOOLEAN, _nm_marshal_VOID__STRING_UINT_BOOLEAN,
G_TYPE_NONE, 2, G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_BOOLEAN);
G_TYPE_STRING,
G_TYPE_BOOLEAN);
signals[CONFIG_CHANGED] = signals[CONFIG_CHANGED] =
g_signal_new ("config-changed", g_signal_new ("config-changed",
@@ -176,9 +174,8 @@ nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class)
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMIP6ManagerClass, config_changed), G_STRUCT_OFFSET (NMIP6ManagerClass, config_changed),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__STRING, _nm_marshal_VOID__STRING_UINT,
G_TYPE_NONE, 1, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT);
G_TYPE_STRING);
} }
static void static void
@@ -233,10 +230,16 @@ nm_ip6_manager_get_device (NMIP6Manager *manager, int ifindex)
GINT_TO_POINTER (ifindex)); GINT_TO_POINTER (ifindex));
} }
typedef struct {
NMIP6Device *device;
guint dhcp_opts;
} CallbackInfo;
static gboolean static gboolean
finish_addrconf (gpointer user_data) finish_addrconf (gpointer user_data)
{ {
NMIP6Device *device = user_data; CallbackInfo *info = user_data;
NMIP6Device *device = info->device;
NMIP6Manager *manager = device->manager; NMIP6Manager *manager = device->manager;
char *iface_copy; char *iface_copy;
@@ -245,7 +248,7 @@ finish_addrconf (gpointer user_data)
if (device->state >= device->target_state) { if (device->state >= device->target_state) {
g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0, g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0,
device->iface, TRUE); device->iface, info->dhcp_opts, TRUE);
} else { } else {
nm_info ("Device '%s' IP6 addrconf timed out or failed.", nm_info ("Device '%s' IP6 addrconf timed out or failed.",
device->iface); device->iface);
@@ -254,7 +257,7 @@ finish_addrconf (gpointer user_data)
nm_ip6_manager_cancel_addrconf (manager, device->iface); nm_ip6_manager_cancel_addrconf (manager, device->iface);
g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0, g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0,
iface_copy, FALSE); iface_copy, info->dhcp_opts, FALSE);
g_free (iface_copy); g_free (iface_copy);
} }
@@ -265,11 +268,12 @@ finish_addrconf (gpointer user_data)
static gboolean static gboolean
emit_config_changed (gpointer user_data) emit_config_changed (gpointer user_data)
{ {
NMIP6Device *device = user_data; CallbackInfo *info = user_data;
NMIP6Device *device = info->device;
NMIP6Manager *manager = device->manager; NMIP6Manager *manager = device->manager;
device->config_changed_id = 0; 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; return FALSE;
} }
@@ -279,9 +283,10 @@ static gboolean
rdnss_expired (gpointer user_data) rdnss_expired (gpointer user_data)
{ {
NMIP6Device *device = user_data; NMIP6Device *device = user_data;
CallbackInfo info = { device, IP6_DHCP_OPT_NONE };
set_rdnss_timeout (device); set_rdnss_timeout (device);
emit_config_changed (device); emit_config_changed (&info);
return FALSE; 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 static void
nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed) 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 in6_addr *addr;
struct rtnl_link *link; struct rtnl_link *link;
guint flags; guint flags;
CallbackInfo *info;
guint dhcp_opts = IP6_DHCP_OPT_NONE;
for (rtnladdr = (struct rtnl_addr *)nl_cache_get_first (priv->addr_cache); for (rtnladdr = (struct rtnl_addr *)nl_cache_get_first (priv->addr_cache);
rtnladdr; 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) if ((flags & IF_RA_RCVD) && device->state < NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT)
device->state = NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT; device->state = NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT;
// if (flags & (IF_RA_MANAGED | IF_RA_OTHERCONF)) if (flags & IF_RA_MANAGED)
// device->need_dhcp = TRUE; dhcp_opts = IP6_DHCP_OPT_MANAGED;
else if (flags & IF_RA_OTHERCONF)
dhcp_opts = IP6_DHCP_OPT_OTHERCONF;
if (!device->addrconf_complete) { if (!device->addrconf_complete) {
if (device->state >= device->target_state || 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) if (device->finish_addrconf_id)
g_source_remove (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) { } else if (config_changed) {
if (!device->config_changed_id) { if (!device->config_changed_id) {
device->config_changed_id = g_idle_add (emit_config_changed, info = callback_info_new (device, dhcp_opts);
device); 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; NMIP6ManagerPrivate *priv;
NMIP6Device *device; NMIP6Device *device;
CallbackInfo *info;
g_return_if_fail (NM_IS_IP6_MANAGER (manager)); g_return_if_fail (NM_IS_IP6_MANAGER (manager));
g_return_if_fail (iface != NULL); g_return_if_fail (iface != NULL);
@@ -731,9 +760,12 @@ nm_ip6_manager_begin_addrconf (NMIP6Manager *manager,
device->addrconf_complete = FALSE; device->addrconf_complete = FALSE;
/* Set up a timeout on the transaction to kill it after the timeout */ /* Set up a timeout on the transaction to kill it after the timeout */
device->finish_addrconf_id = g_timeout_add_seconds (NM_IP6_TIMEOUT, info = callback_info_new (device, 0);
finish_addrconf, device->finish_addrconf_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
device); NM_IP6_TIMEOUT,
finish_addrconf,
info,
(GDestroyNotify) g_free);
/* Sync flags, etc, from netlink; this will also notice if the /* Sync flags, etc, from netlink; this will also notice if the
* device is already fully configured and schedule the * device is already fully configured and schedule the

View File

@@ -35,6 +35,12 @@
#define NM_IS_IP6_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IP6_MANAGER)) #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)) #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 { typedef struct {
GObject parent; GObject parent;
} NMIP6Manager; } NMIP6Manager;
@@ -47,13 +53,18 @@ typedef struct {
/* addrconf_complete is emitted only during initial configuration to indicate /* addrconf_complete is emitted only during initial configuration to indicate
* that the initial configuration is complete. * 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 /* config_changed gets emitted only *after* initial configuration is
* complete; it's like DHCP renew and indicates that the existing config * complete; it's like DHCP renew and indicates that the existing config
* of the interface has changed. * of the interface has changed.
*/ */
void (*config_changed) (NMIP6Manager *manager, char *iface); void (*config_changed) (NMIP6Manager *manager,
char *iface,
guint dhcp_opts);
} NMIP6ManagerClass; } NMIP6ManagerClass;
GType nm_ip6_manager_get_type (void); GType nm_ip6_manager_get_type (void);

View File

@@ -535,9 +535,10 @@ activation_source_schedule (NMDevice *self, GSourceFunc func, int family)
static void static void
ip6_addrconf_complete (NMIP6Manager *ip6_manager, ip6_addrconf_complete (NMIP6Manager *ip6_manager,
const char *iface, const char *iface,
gboolean success, guint dhcp_opts,
gpointer user_data) gboolean success,
gpointer user_data)
{ {
NMDevice *self = NM_DEVICE (user_data); NMDevice *self = NM_DEVICE (user_data);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
@@ -558,8 +559,9 @@ ip6_addrconf_complete (NMIP6Manager *ip6_manager,
static void static void
ip6_config_changed (NMIP6Manager *ip6_manager, ip6_config_changed (NMIP6Manager *ip6_manager,
const char *iface, const char *iface,
gpointer user_data) guint dhcp_opts,
gpointer user_data)
{ {
NMDevice *self = NM_DEVICE (user_data); NMDevice *self = NM_DEVICE (user_data);