summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2013-08-28 09:08:43 -0500
committerDan Williams <dcbw@redhat.com>2013-10-31 14:15:08 -0500
commit8252357dd1796dd6123a56a10356d0c5496e885b (patch)
tree76f309759e4f5bf4c879690df8c4e0caa4f40fbc
parent3bb2b158cdda573b79a8c209cf25f956e94e9e0d (diff)
downloadNetworkManager-8252357dd1796dd6123a56a10356d0c5496e885b.tar.gz
core: watch master ActiveConnections and follow master deactivation
-rw-r--r--src/nm-activation-request.c24
-rw-r--r--src/nm-active-connection.c30
-rw-r--r--src/nm-active-connection.h2
-rw-r--r--src/vpn-manager/nm-vpn-connection.c13
4 files changed, 69 insertions, 0 deletions
diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c
index ce9ee7da82..61d7782d44 100644
--- a/src/nm-activation-request.c
+++ b/src/nm-activation-request.c
@@ -334,6 +334,28 @@ device_state_changed (NMDevice *device, GParamSpec *pspec, NMActRequest *self)
nm_active_connection_set_state (NM_ACTIVE_CONNECTION (self), ac_state);
}
+static void
+master_failed (NMActiveConnection *self)
+{
+ NMDevice *device;
+ NMDeviceState device_state;
+
+ /* If the connection has an active device, fail it */
+ device = nm_active_connection_get_device (self);
+ if (device) {
+ device_state = nm_device_get_state (device);
+ if (nm_device_is_activating (device) || (device_state == NM_DEVICE_STATE_ACTIVATED)) {
+ nm_device_state_changed (device,
+ NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED);
+ return;
+ }
+ }
+
+ /* If no device, or the device wasn't active, just move to deactivated state */
+ nm_active_connection_set_state (self, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
+}
+
/********************************************************************/
/**
@@ -426,11 +448,13 @@ static void
nm_act_request_class_init (NMActRequestClass *req_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (req_class);
+ NMActiveConnectionClass *active_class = NM_ACTIVE_CONNECTION_CLASS (req_class);
g_type_class_add_private (req_class, sizeof (NMActRequestPrivate));
/* virtual methods */
object_class->constructed = constructed;
object_class->dispose = dispose;
+ active_class->master_failed = master_failed;
}
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c
index d24c621272..f811dee82f 100644
--- a/src/nm-active-connection.c
+++ b/src/nm-active-connection.c
@@ -265,6 +265,26 @@ nm_active_connection_get_master (NMActiveConnection *self)
return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->master;
}
+static void
+master_state_cb (NMActiveConnection *master,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
+ NMActiveConnectionState self_state = nm_active_connection_get_state (self);
+ NMActiveConnectionState master_state = nm_active_connection_get_state (master);
+
+ /* Master is deactivating, so this active connection must also deactivate */
+ if (self_state < NM_ACTIVE_CONNECTION_STATE_DEACTIVATING &&
+ master_state >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
+ g_signal_handlers_disconnect_by_func (master,
+ (GCallback) master_state_cb,
+ self);
+ if (NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed)
+ NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed (self);
+ }
+}
+
/**
* nm_active_connection_set_master:
* @self: the #NMActiveConnection
@@ -294,6 +314,10 @@ nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *m
g_return_if_fail (master_device != priv->device);
priv->master = g_object_ref (master);
+ g_signal_connect (priv->master,
+ "notify::" NM_ACTIVE_CONNECTION_STATE,
+ (GCallback) master_state_cb,
+ self);
}
/****************************************************************/
@@ -530,6 +554,12 @@ dispose (GObject *object)
g_clear_object (&priv->connection);
g_clear_object (&priv->device);
+
+ if (priv->master) {
+ g_signal_handlers_disconnect_by_func (priv->master,
+ (GCallback) master_state_cb,
+ NM_ACTIVE_CONNECTION (object));
+ }
g_clear_object (&priv->master);
g_clear_object (&priv->subject);
diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h
index 93723c904e..1605c3963a 100644
--- a/src/nm-active-connection.h
+++ b/src/nm-active-connection.h
@@ -56,6 +56,8 @@ typedef struct {
typedef struct {
GObjectClass parent;
+
+ void (*master_failed) (NMActiveConnection *connection);
} NMActiveConnectionClass;
GType nm_active_connection_get_type (void);
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index 129123acdb..ec66732d2f 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.c
@@ -296,6 +296,17 @@ device_state_changed (NMDevice *device,
}
static void
+master_failed (NMActiveConnection *self)
+{
+ NMVPNConnection *connection = NM_VPN_CONNECTION (self);
+
+ /* Master failure fails the VPN */
+ nm_vpn_connection_set_vpn_state (connection,
+ NM_VPN_CONNECTION_STATE_FAILED,
+ NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED);
+}
+
+static void
add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
{
NMIP4Config *parent_config;
@@ -1768,6 +1779,7 @@ static void
nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
+ NMActiveConnectionClass *active_class = NM_ACTIVE_CONNECTION_CLASS (connection_class);
g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
@@ -1776,6 +1788,7 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
object_class->constructed = constructed;
object_class->dispose = dispose;
object_class->finalize = finalize;
+ active_class->master_failed = master_failed;
g_object_class_override_property (object_class, PROP_MASTER, NM_ACTIVE_CONNECTION_MASTER);