mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-08 21:10:25 +01:00
core: merge branch 'th/keep-alive-fixes'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/50
This commit is contained in:
commit
e9d1cbb2f3
15 changed files with 547 additions and 187 deletions
|
|
@ -960,20 +960,25 @@ typedef enum { /*< flags >*/
|
|||
* @NM_ACTIVATION_STATE_FLAG_IP6_READY: IPv6 setting is completed.
|
||||
* @NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES: The master has any slave devices attached.
|
||||
* This only makes sense if the device is a master.
|
||||
* @NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY: the lifetime
|
||||
* of the activation is bound to the visilibity of the connection profile,
|
||||
* which in turn depends on "connection.permissions" and whether a session
|
||||
* for the user exists. Since: 1.16
|
||||
*
|
||||
* Flags describing the current activation state.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
typedef enum { /*< flags >*/
|
||||
NM_ACTIVATION_STATE_FLAG_NONE = 0,
|
||||
NM_ACTIVATION_STATE_FLAG_NONE = 0,
|
||||
|
||||
NM_ACTIVATION_STATE_FLAG_IS_MASTER = (1LL << 0),
|
||||
NM_ACTIVATION_STATE_FLAG_IS_SLAVE = (1LL << 1),
|
||||
NM_ACTIVATION_STATE_FLAG_LAYER2_READY = (1LL << 2),
|
||||
NM_ACTIVATION_STATE_FLAG_IP4_READY = (1LL << 3),
|
||||
NM_ACTIVATION_STATE_FLAG_IP6_READY = (1LL << 4),
|
||||
NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES = (1LL << 5),
|
||||
NM_ACTIVATION_STATE_FLAG_IS_MASTER = (1LL << 0),
|
||||
NM_ACTIVATION_STATE_FLAG_IS_SLAVE = (1LL << 1),
|
||||
NM_ACTIVATION_STATE_FLAG_LAYER2_READY = (1LL << 2),
|
||||
NM_ACTIVATION_STATE_FLAG_IP4_READY = (1LL << 3),
|
||||
NM_ACTIVATION_STATE_FLAG_IP6_READY = (1LL << 4),
|
||||
NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES = (1LL << 5),
|
||||
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY = (1LL << 6),
|
||||
} NMActivationStateFlags;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@
|
|||
#include "settings/nm-settings.h"
|
||||
#include "nm-setting-ethtool.h"
|
||||
#include "nm-auth-utils.h"
|
||||
#include "nm-keep-alive.h"
|
||||
#include "nm-netns.h"
|
||||
#include "nm-dispatcher.h"
|
||||
#include "nm-config.h"
|
||||
|
|
@ -2383,10 +2384,27 @@ nm_device_get_act_request (NMDevice *self)
|
|||
return NM_DEVICE_GET_PRIVATE (self)->act_request.obj;
|
||||
}
|
||||
|
||||
NMActivationStateFlags
|
||||
nm_device_get_activation_state_flags (NMDevice *self)
|
||||
{
|
||||
NMActRequest *ac;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), NM_ACTIVATION_STATE_FLAG_NONE);
|
||||
|
||||
ac = NM_DEVICE_GET_PRIVATE (self)->act_request.obj;
|
||||
if (!ac)
|
||||
return NM_ACTIVATION_STATE_FLAG_NONE;
|
||||
return nm_active_connection_get_state_flags (NM_ACTIVE_CONNECTION (ac));
|
||||
}
|
||||
|
||||
NMSettingsConnection *
|
||||
nm_device_get_settings_connection (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
return priv->act_request.obj ? nm_act_request_get_settings_connection (priv->act_request.obj) : NULL;
|
||||
}
|
||||
|
|
@ -11619,14 +11637,15 @@ disconnect_cb (NMDevice *self,
|
|||
}
|
||||
|
||||
static void
|
||||
_clear_queued_act_request (NMDevicePrivate *priv)
|
||||
_clear_queued_act_request (NMDevicePrivate *priv,
|
||||
NMActiveConnectionStateReason active_reason)
|
||||
{
|
||||
if (priv->queued_act_request) {
|
||||
gs_unref_object NMActRequest *ac = NULL;
|
||||
|
||||
ac = g_steal_pointer (&priv->queued_act_request);
|
||||
nm_active_connection_set_state_fail ((NMActiveConnection *) ac,
|
||||
NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED,
|
||||
active_reason,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -11768,7 +11787,8 @@ _carrier_wait_check_queued_act_request (NMDevice *self)
|
|||
priv->queued_act_request_is_waiting_for_carrier = FALSE;
|
||||
if (!priv->carrier) {
|
||||
_LOGD (LOGD_DEVICE, "Cancel queued activation request as we have no carrier after timeout");
|
||||
_clear_queued_act_request (priv);
|
||||
_clear_queued_act_request (priv,
|
||||
NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED);
|
||||
} else {
|
||||
gs_unref_object NMActRequest *queued_req = NULL;
|
||||
|
||||
|
|
@ -11823,7 +11843,9 @@ _carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req)
|
|||
}
|
||||
|
||||
void
|
||||
nm_device_disconnect_active_connection (NMActiveConnection *active)
|
||||
nm_device_disconnect_active_connection (NMActiveConnection *active,
|
||||
NMDeviceStateReason device_reason,
|
||||
NMActiveConnectionStateReason active_reason)
|
||||
{
|
||||
NMDevice *self;
|
||||
NMDevicePrivate *priv;
|
||||
|
|
@ -11831,38 +11853,59 @@ nm_device_disconnect_active_connection (NMActiveConnection *active)
|
|||
g_return_if_fail (NM_IS_ACTIVE_CONNECTION (active));
|
||||
|
||||
self = nm_active_connection_get_device (active);
|
||||
|
||||
if (!self) {
|
||||
/* hm, no device? Just fail the active connection. */
|
||||
nm_active_connection_set_state_fail (active,
|
||||
NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN,
|
||||
NULL);
|
||||
return;
|
||||
goto do_fail;
|
||||
}
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
if (NM_ACTIVE_CONNECTION (priv->queued_act_request) == active) {
|
||||
_clear_queued_act_request (priv);
|
||||
_clear_queued_act_request (priv, active_reason);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NM_ACTIVE_CONNECTION (priv->act_request.obj) == active) {
|
||||
if (priv->state < NM_DEVICE_STATE_DEACTIVATING) {
|
||||
nm_device_state_changed (self,
|
||||
NM_DEVICE_STATE_DEACTIVATING,
|
||||
NM_DEVICE_STATE_REASON_NEW_ACTIVATION);
|
||||
device_reason);
|
||||
} else {
|
||||
/* it's going down already... */
|
||||
/* @active is the current ac of @self, but it's going down already.
|
||||
* Nothing to do. */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* the active connection references this device, but it's neither the
|
||||
* queued_act_request nor the current act_request. Just set it to fail... */
|
||||
do_fail:
|
||||
nm_active_connection_set_state_fail (active,
|
||||
active_reason,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_queue_activation (NMDevice *self, NMActRequest *req)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMDevicePrivate *priv;
|
||||
gboolean must_queue;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (self));
|
||||
g_return_if_fail (NM_IS_ACT_REQUEST (req));
|
||||
|
||||
nm_keep_alive_arm (nm_active_connection_get_keep_alive (NM_ACTIVE_CONNECTION (req)));
|
||||
|
||||
if (nm_active_connection_get_state (NM_ACTIVE_CONNECTION (req)) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
|
||||
/* it's already deactivating. Nothing to do. */
|
||||
nm_assert (NM_IN_SET (nm_active_connection_get_device (NM_ACTIVE_CONNECTION (req)), NULL, self));
|
||||
return;
|
||||
}
|
||||
|
||||
nm_assert (self == nm_active_connection_get_device (NM_ACTIVE_CONNECTION (req)));
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
must_queue = _carrier_wait_check_act_request_must_queue (self, req);
|
||||
|
||||
if ( !priv->act_request.obj
|
||||
|
|
@ -11873,7 +11916,8 @@ nm_device_queue_activation (NMDevice *self, NMActRequest *req)
|
|||
}
|
||||
|
||||
/* supersede any already-queued request */
|
||||
_clear_queued_act_request (priv);
|
||||
_clear_queued_act_request (priv,
|
||||
NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED);
|
||||
priv->queued_act_request = g_object_ref (req);
|
||||
priv->queued_act_request_is_waiting_for_carrier = must_queue;
|
||||
|
||||
|
|
@ -14742,8 +14786,10 @@ _set_state_full (NMDevice *self,
|
|||
if (state <= NM_DEVICE_STATE_UNAVAILABLE) {
|
||||
if (available_connections_del_all (self))
|
||||
_notify (self, PROP_AVAILABLE_CONNECTIONS);
|
||||
if (old_state > NM_DEVICE_STATE_UNAVAILABLE)
|
||||
_clear_queued_act_request (priv);
|
||||
if (old_state > NM_DEVICE_STATE_UNAVAILABLE) {
|
||||
_clear_queued_act_request (priv,
|
||||
NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the available connections list when a device first becomes available */
|
||||
|
|
@ -16188,7 +16234,8 @@ dispose (GObject *object)
|
|||
if (nm_clear_g_source (&priv->carrier_wait_id))
|
||||
nm_device_remove_pending_action (self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE);
|
||||
|
||||
_clear_queued_act_request (priv);
|
||||
_clear_queued_act_request (priv,
|
||||
NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED);
|
||||
|
||||
nm_clear_g_source (&priv->device_link_changed_id);
|
||||
nm_clear_g_source (&priv->device_ip_link_changed_id);
|
||||
|
|
|
|||
|
|
@ -543,6 +543,7 @@ NMConnection * nm_device_get_settings_connection_get_connection (NMDevice *self
|
|||
NMConnection * nm_device_get_applied_connection (NMDevice *dev);
|
||||
gboolean nm_device_has_unmodified_applied_connection (NMDevice *self,
|
||||
NMSettingCompareFlags compare_flags);
|
||||
NMActivationStateFlags nm_device_get_activation_state_flags (NMDevice *self);
|
||||
|
||||
gpointer /* (NMSetting *) */ nm_device_get_applied_setting (NMDevice *dev,
|
||||
GType setting_type);
|
||||
|
|
@ -769,7 +770,9 @@ void nm_device_queue_state (NMDevice *self,
|
|||
|
||||
gboolean nm_device_get_firmware_missing (NMDevice *self);
|
||||
|
||||
void nm_device_disconnect_active_connection (NMActiveConnection *active);
|
||||
void nm_device_disconnect_active_connection (NMActiveConnection *active,
|
||||
NMDeviceStateReason device_reason,
|
||||
NMActiveConnectionStateReason active_reason);
|
||||
|
||||
void nm_device_queue_activation (NMDevice *device, NMActRequest *req);
|
||||
|
||||
|
|
|
|||
|
|
@ -539,6 +539,7 @@ nm_act_request_init (NMActRequest *req)
|
|||
* @subject: the #NMAuthSubject representing the requestor of the activation
|
||||
* @activation_type: the #NMActivationType
|
||||
* @activation_reason: the reason for activation
|
||||
* @initial_state_flags: the initial state flags.
|
||||
* @device: the device/interface to configure according to @connection
|
||||
*
|
||||
* Creates a new device-based activation request. If an applied connection is
|
||||
|
|
@ -553,6 +554,7 @@ nm_act_request_new (NMSettingsConnection *settings_connection,
|
|||
NMAuthSubject *subject,
|
||||
NMActivationType activation_type,
|
||||
NMActivationReason activation_reason,
|
||||
NMActivationStateFlags initial_state_flags,
|
||||
NMDevice *device)
|
||||
{
|
||||
g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
|
||||
|
|
@ -567,6 +569,7 @@ nm_act_request_new (NMSettingsConnection *settings_connection,
|
|||
NM_ACTIVE_CONNECTION_INT_SUBJECT, subject,
|
||||
NM_ACTIVE_CONNECTION_INT_ACTIVATION_TYPE, (int) activation_type,
|
||||
NM_ACTIVE_CONNECTION_INT_ACTIVATION_REASON, (int) activation_reason,
|
||||
NM_ACTIVE_CONNECTION_STATE_FLAGS, (guint) initial_state_flags,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ NMActRequest *nm_act_request_new (NMSettingsConnection *settings_connec
|
|||
NMAuthSubject *subject,
|
||||
NMActivationType activation_type,
|
||||
NMActivationReason activation_reason,
|
||||
NMActivationStateFlags initial_state_flags,
|
||||
NMDevice *device);
|
||||
|
||||
NMSettingsConnection *nm_act_request_get_settings_connection (NMActRequest *req);
|
||||
|
|
|
|||
|
|
@ -105,7 +105,6 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMActiveConnection,
|
|||
PROP_INT_MASTER_READY,
|
||||
PROP_INT_ACTIVATION_TYPE,
|
||||
PROP_INT_ACTIVATION_REASON,
|
||||
PROP_INT_KEEP_ALIVE,
|
||||
);
|
||||
|
||||
enum {
|
||||
|
|
@ -164,26 +163,22 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_state_to_string, NMActiveConnectionState,
|
|||
);
|
||||
#define state_to_string(state) NM_UTILS_LOOKUP_STR (_state_to_string, state)
|
||||
|
||||
/* the maximum required buffer size for _state_flags_to_string(). */
|
||||
#define _NM_ACTIVATION_STATE_FLAG_TO_STRING_BUFSIZE (255)
|
||||
|
||||
NM_UTILS_FLAGS2STR_DEFINE_STATIC (_state_flags_to_string, NMActivationStateFlags,
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_NONE, "none"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IS_MASTER, "is-master"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IS_SLAVE, "is-slave"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_LAYER2_READY, "layer2-ready"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IP4_READY, "ip4-ready"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IP6_READY, "ip6-ready"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES, "master-has-slaves"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_NONE, "none"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IS_MASTER, "is-master"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IS_SLAVE, "is-slave"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_LAYER2_READY, "layer2-ready"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IP4_READY, "ip4-ready"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IP6_READY, "ip6-ready"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES, "master-has-slaves"),
|
||||
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY, "lifetime-bound-to-profile-visibility"),
|
||||
);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
keep_alive_alive_changed (NMActiveConnection *ac,
|
||||
GParamSpec *pspec,
|
||||
NMKeepAlive *keep_alive)
|
||||
{
|
||||
_notify (ac, PROP_INT_KEEP_ALIVE);
|
||||
}
|
||||
|
||||
static void
|
||||
_settings_connection_updated (NMSettingsConnection *sett_conn,
|
||||
gboolean by_user,
|
||||
|
|
@ -264,6 +259,12 @@ nm_active_connection_set_state (NMActiveConnection *self,
|
|||
state_to_string (new_state),
|
||||
state_to_string (priv->state));
|
||||
|
||||
if (new_state > NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
|
||||
/* once we are about to deactivate, we don't need the keep-alive instance
|
||||
* anymore. Freeze/disarm it. */
|
||||
nm_keep_alive_disarm (priv->keep_alive);
|
||||
}
|
||||
|
||||
if ( new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
|
||||
&& priv->activation_type == NM_ACTIVATION_TYPE_ASSUME) {
|
||||
/* assuming connections mean to gracefully take over an externally
|
||||
|
|
@ -364,14 +365,20 @@ nm_active_connection_set_state_flags_full (NMActiveConnection *self,
|
|||
|
||||
f = (priv->state_flags & ~mask) | (state_flags & mask);
|
||||
if (f != priv->state_flags) {
|
||||
char buf1[G_N_ELEMENTS (_nm_utils_to_string_buffer)];
|
||||
char buf2[G_N_ELEMENTS (_nm_utils_to_string_buffer)];
|
||||
char buf1[_NM_ACTIVATION_STATE_FLAG_TO_STRING_BUFSIZE];
|
||||
char buf2[_NM_ACTIVATION_STATE_FLAG_TO_STRING_BUFSIZE];
|
||||
|
||||
_LOGD ("set state-flags %s (was %s)",
|
||||
_state_flags_to_string (f, buf1, sizeof (buf1)),
|
||||
_state_flags_to_string (priv->state_flags, buf2, sizeof (buf2)));
|
||||
priv->state_flags = f;
|
||||
_notify (self, PROP_STATE_FLAGS);
|
||||
|
||||
nm_keep_alive_set_settings_connection_watch_visible (priv->keep_alive,
|
||||
NM_FLAGS_HAS (priv->state_flags,
|
||||
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY)
|
||||
? priv->settings_connection.obj
|
||||
: NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -915,12 +922,30 @@ nm_active_connection_get_activation_reason (NMActiveConnection *self)
|
|||
return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->activation_reason;
|
||||
}
|
||||
|
||||
gboolean
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_active_connection_get_keep_alive:
|
||||
* @self: the #NMActiveConnection instance
|
||||
*
|
||||
* Gives the #NMKeepAlive instance of the active connection. Note that
|
||||
* @self is guaranteed not to swap the keep-alive instance, so it is
|
||||
* in particular safe to assume that the keep-alive instance is alive
|
||||
* as long as @self, and that nm_active_connection_get_keep_alive()
|
||||
* will return always the same instance.
|
||||
*
|
||||
* In particular this means, that it is safe and encouraged, that you
|
||||
* register to the notify:alive property changed signal of the returned
|
||||
* instance.
|
||||
*
|
||||
* Returns: the #NMKeepAlive instance.
|
||||
*/
|
||||
NMKeepAlive *
|
||||
nm_active_connection_get_keep_alive (NMActiveConnection *self)
|
||||
{
|
||||
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
|
||||
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL);
|
||||
|
||||
return nm_keep_alive_is_alive (priv->keep_alive);
|
||||
return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->keep_alive;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -1014,23 +1039,6 @@ nm_active_connection_set_parent (NMActiveConnection *self, NMActiveConnection *p
|
|||
g_object_weak_ref ((GObject *) priv->parent, parent_destroyed, self);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_active_connection_bind_dbus_client:
|
||||
* @self: the #NMActiveConnection
|
||||
* @dbus_client: The dbus client to watch.
|
||||
*
|
||||
* Binds the lifetime of this active connection to the given dbus client. If
|
||||
* the dbus client disappears, then the connection will be disconnected.
|
||||
*/
|
||||
void
|
||||
nm_active_connection_bind_dbus_client (NMActiveConnection *self, GDBusConnection *dbus_con, const char *dbus_client)
|
||||
{
|
||||
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
nm_keep_alive_set_dbus_client_watch (priv->keep_alive, dbus_con, dbus_client);
|
||||
nm_keep_alive_sink (priv->keep_alive);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -1329,9 +1337,6 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_INT_MASTER_READY:
|
||||
g_value_set_boolean (value, priv->master_ready);
|
||||
break;
|
||||
case PROP_INT_KEEP_ALIVE:
|
||||
g_value_set_boolean (value, nm_keep_alive_is_alive (priv->keep_alive));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -1389,6 +1394,12 @@ set_property (GObject *object, guint prop_id,
|
|||
g_return_if_reached ();
|
||||
_set_activation_type (self, (NMActivationType) i);
|
||||
break;
|
||||
case PROP_STATE_FLAGS:
|
||||
/* construct-only */
|
||||
priv->state_flags = g_value_get_uint (value);
|
||||
nm_assert ((guint) priv->state_flags == g_value_get_uint (value));
|
||||
nm_assert (!NM_FLAGS_ANY (priv->state_flags, ~NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY));
|
||||
break;
|
||||
case PROP_INT_ACTIVATION_REASON:
|
||||
/* construct-only */
|
||||
i = g_value_get_int (value);
|
||||
|
|
@ -1440,11 +1451,9 @@ nm_active_connection_init (NMActiveConnection *self)
|
|||
priv->activation_type = NM_ACTIVATION_TYPE_MANAGED;
|
||||
priv->version_id = _version_id_new ();
|
||||
|
||||
priv->keep_alive = nm_keep_alive_new (TRUE);
|
||||
g_signal_connect_object (priv->keep_alive, "notify::" NM_KEEP_ALIVE_ALIVE,
|
||||
(GCallback) keep_alive_alive_changed,
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
/* the keep-alive instance must never change. Callers rely on that. */
|
||||
priv->keep_alive = nm_keep_alive_new ();
|
||||
_nm_keep_alive_set_owner (priv->keep_alive, G_OBJECT (self));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1474,15 +1483,12 @@ constructed (GObject *object)
|
|||
g_steal_pointer (&priv->applied_connection));
|
||||
}
|
||||
|
||||
if (NM_FLAGS_HAS (priv->state_flags,
|
||||
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY))
|
||||
nm_keep_alive_set_settings_connection_watch_visible (priv->keep_alive, priv->settings_connection.obj);
|
||||
|
||||
g_return_if_fail (priv->subject);
|
||||
g_return_if_fail (priv->activation_reason != NM_ACTIVATION_REASON_UNSET);
|
||||
|
||||
if (NM_IN_SET ((NMActivationReason) priv->activation_reason,
|
||||
NM_ACTIVATION_REASON_AUTOCONNECT,
|
||||
NM_ACTIVATION_REASON_AUTOCONNECT_SLAVES)) {
|
||||
nm_keep_alive_set_settings_connection_watch_visible (priv->keep_alive, priv->settings_connection.obj);
|
||||
nm_keep_alive_sink (priv->keep_alive);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1526,6 +1532,8 @@ finalize (GObject *object)
|
|||
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
nm_dbus_track_obj_path_set (&priv->settings_connection, NULL, FALSE);
|
||||
|
||||
_nm_keep_alive_set_owner (priv->keep_alive, NULL);
|
||||
g_clear_object (&priv->keep_alive);
|
||||
|
||||
G_OBJECT_CLASS (nm_active_connection_parent_class)->finalize (object);
|
||||
|
|
@ -1632,7 +1640,7 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class)
|
|||
obj_properties[PROP_STATE_FLAGS] =
|
||||
g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE_FLAGS, "", "",
|
||||
0, G_MAXUINT32, NM_ACTIVATION_STATE_FLAG_NONE,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_properties[PROP_DEFAULT] =
|
||||
|
|
@ -1737,11 +1745,6 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class)
|
|||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_properties[PROP_INT_KEEP_ALIVE] =
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_INT_KEEP_ALIVE, "", "",
|
||||
TRUE, G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
||||
|
||||
signals[DEVICE_CHANGED] =
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@
|
|||
#define NM_ACTIVE_CONNECTION_INT_MASTER_READY "int-master-ready"
|
||||
#define NM_ACTIVE_CONNECTION_INT_ACTIVATION_TYPE "int-activation-type"
|
||||
#define NM_ACTIVE_CONNECTION_INT_ACTIVATION_REASON "int-activation-reason"
|
||||
#define NM_ACTIVE_CONNECTION_INT_KEEP_ALIVE "int-keep-alive"
|
||||
|
||||
/* Signals */
|
||||
#define NM_ACTIVE_CONNECTION_STATE_CHANGED "state-changed"
|
||||
|
|
@ -164,6 +163,13 @@ nm_active_connection_set_state_flags (NMActiveConnection *self,
|
|||
nm_active_connection_set_state_flags_full (self, state_flags, state_flags);
|
||||
}
|
||||
|
||||
static inline void
|
||||
nm_active_connection_set_state_flags_clear (NMActiveConnection *self,
|
||||
NMActivationStateFlags state_flags)
|
||||
{
|
||||
nm_active_connection_set_state_flags_full (self, NM_ACTIVATION_STATE_FLAG_NONE, state_flags);
|
||||
}
|
||||
|
||||
NMDevice * nm_active_connection_get_device (NMActiveConnection *self);
|
||||
|
||||
gboolean nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device);
|
||||
|
|
@ -186,12 +192,8 @@ NMActivationType nm_active_connection_get_activation_type (NMActiveConnection *s
|
|||
|
||||
NMActivationReason nm_active_connection_get_activation_reason (NMActiveConnection *self);
|
||||
|
||||
gboolean nm_active_connection_get_keep_alive (NMActiveConnection *self);
|
||||
NMKeepAlive *nm_active_connection_get_keep_alive (NMActiveConnection *self);
|
||||
|
||||
void nm_active_connection_clear_secrets (NMActiveConnection *self);
|
||||
|
||||
void nm_active_connection_bind_dbus_client (NMActiveConnection *self,
|
||||
GDBusConnection *dbus_con,
|
||||
const char *dbus_name);
|
||||
|
||||
#endif /* __NETWORKMANAGER_ACTIVE_CONNECTION_H__ */
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ typedef struct {
|
|||
guint64 ac_version_id;
|
||||
NMDeviceState state;
|
||||
bool realized:1;
|
||||
bool activation_lifetime_bound_to_profile_visiblity:1;
|
||||
NMUnmanFlagOp unmanaged_explicit;
|
||||
NMActivationReason activation_reason;
|
||||
} DeviceCheckpoint;
|
||||
|
|
@ -335,6 +336,9 @@ activate:
|
|||
subject,
|
||||
NM_ACTIVATION_TYPE_MANAGED,
|
||||
dev_checkpoint->activation_reason,
|
||||
dev_checkpoint->activation_lifetime_bound_to_profile_visiblity
|
||||
? NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY
|
||||
: NM_ACTIVATION_STATE_FLAG_NONE,
|
||||
&local_error)) {
|
||||
_LOGW ("rollback: reactivation of connection %s/%s failed: %s",
|
||||
nm_settings_connection_get_id (connection),
|
||||
|
|
@ -439,6 +443,8 @@ device_checkpoint_create (NMDevice *device)
|
|||
dev_checkpoint->settings_connection = nm_simple_connection_new_clone (nm_settings_connection_get_connection (settings_connection));
|
||||
dev_checkpoint->ac_version_id = nm_active_connection_version_id_get (NM_ACTIVE_CONNECTION (act_request));
|
||||
dev_checkpoint->activation_reason = nm_active_connection_get_activation_reason (NM_ACTIVE_CONNECTION (act_request));
|
||||
dev_checkpoint->activation_lifetime_bound_to_profile_visiblity = NM_FLAGS_HAS (nm_active_connection_get_state_flags (NM_ACTIVE_CONNECTION (act_request)),
|
||||
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY);
|
||||
}
|
||||
|
||||
return dev_checkpoint;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMKeepAlive,
|
|||
);
|
||||
|
||||
typedef struct {
|
||||
GObject *owner;
|
||||
|
||||
NMSettingsConnection *connection;
|
||||
GDBusConnection *dbus_connection;
|
||||
char *dbus_client;
|
||||
|
|
@ -41,10 +43,13 @@ typedef struct {
|
|||
GCancellable *dbus_client_confirm_cancellable;
|
||||
guint subscription_id;
|
||||
|
||||
bool floating:1;
|
||||
bool forced:1;
|
||||
bool armed:1;
|
||||
bool disarmed:1;
|
||||
|
||||
bool alive:1;
|
||||
bool dbus_client_confirmed:1;
|
||||
bool dbus_client_watching:1;
|
||||
bool connection_was_visible:1;
|
||||
} NMKeepAlivePrivate;
|
||||
|
||||
struct _NMKeepAlive {
|
||||
|
|
@ -77,22 +82,42 @@ _is_alive (NMKeepAlive *self)
|
|||
{
|
||||
NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
|
||||
|
||||
if ( priv->floating
|
||||
|| priv->forced)
|
||||
nm_assert (!priv->disarmed);
|
||||
|
||||
if (!priv->armed) {
|
||||
/* before arming, the instance is always alive. */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (priv->dbus_client_watching) {
|
||||
if (_is_alive_dbus_client (self)) {
|
||||
/* no matter what, the keep-alive is alive, because there is a D-Bus client
|
||||
* still around keeping it alive. */
|
||||
return TRUE;
|
||||
}
|
||||
/* the D-Bus client is gone. The only other binding (below) for the connection's
|
||||
* visibility cannot keep the instance alive.
|
||||
*
|
||||
* As such, a D-Bus client watch is authorative and overrules other conditions (that
|
||||
* we have so far). */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( priv->connection
|
||||
&& NM_FLAGS_HAS (nm_settings_connection_get_flags (priv->connection),
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE))
|
||||
return TRUE;
|
||||
&& priv->connection_was_visible
|
||||
&& !NM_FLAGS_HAS (nm_settings_connection_get_flags (priv->connection),
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) {
|
||||
/* note that we only declare the keep-alive as dead due to invisible
|
||||
* connection, if
|
||||
* (1) we monitor a connection, obviously
|
||||
* (2) the connection was visible earlier and is no longer. It was
|
||||
* was invisible all the time, it does not suffice.
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Perform this check as last. We want to confirm whether the dbus-client
|
||||
* is alive lazyly, so if we already decided above that the keep-alive
|
||||
* is good, we don't rely on the outcome of this check. */
|
||||
if (_is_alive_dbus_client (self))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
/* by default, the instance is alive. */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -100,9 +125,15 @@ _notify_alive (NMKeepAlive *self)
|
|||
{
|
||||
NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
|
||||
|
||||
if (priv->disarmed) {
|
||||
/* once disarmed, the alive state is frozen. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->alive == _is_alive (self))
|
||||
return;
|
||||
priv->alive = !priv->alive;
|
||||
_LOGD ("instance is now %s", priv->alive ? "alive" : "dead");
|
||||
_notify (self, PROP_ALIVE);
|
||||
}
|
||||
|
||||
|
|
@ -114,34 +145,28 @@ nm_keep_alive_is_alive (NMKeepAlive *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_keep_alive_sink (NMKeepAlive *self)
|
||||
{
|
||||
NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
|
||||
|
||||
if (priv->floating) {
|
||||
priv->floating = FALSE;
|
||||
_notify_alive (self);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nm_keep_alive_set_forced (NMKeepAlive *self, gboolean forced)
|
||||
{
|
||||
NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
|
||||
|
||||
if (priv->forced != (!!forced)) {
|
||||
priv->forced = forced;
|
||||
_notify_alive (self);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
connection_flags_changed (NMSettingsConnection *connection,
|
||||
NMKeepAlive *self)
|
||||
{
|
||||
NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
|
||||
|
||||
if ( !priv->connection_was_visible
|
||||
&& NM_FLAGS_HAS (nm_settings_connection_get_flags (priv->connection),
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) {
|
||||
/* the profile was never visible but now it becomes visible.
|
||||
* Remember that.
|
||||
*
|
||||
* Before this happens (that is, if the device was invisible all along),
|
||||
* the keep alive instance is considered alive (w.r.t. watching the connection).
|
||||
*
|
||||
* The reason is to allow a user to manually activate an invisible profile and keep
|
||||
* it alive. At least, as long until the user logs out the first time (which is the
|
||||
* first time, the profiles changes from visible to invisible).
|
||||
*
|
||||
* Yes, that is odd. How to improve? */
|
||||
priv->connection_was_visible = TRUE;
|
||||
}
|
||||
_notify_alive (self);
|
||||
}
|
||||
|
||||
|
|
@ -163,8 +188,11 @@ _set_settings_connection_watch_visible (NMKeepAlive *self,
|
|||
old_connection = g_steal_pointer (&priv->connection);
|
||||
}
|
||||
|
||||
if (connection) {
|
||||
if ( connection
|
||||
&& !priv->disarmed) {
|
||||
priv->connection = g_object_ref (connection);
|
||||
priv->connection_was_visible = NM_FLAGS_HAS (nm_settings_connection_get_flags (priv->connection),
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE);
|
||||
g_signal_connect (priv->connection,
|
||||
NM_SETTINGS_CONNECTION_FLAGS_CHANGED,
|
||||
G_CALLBACK (connection_flags_changed),
|
||||
|
|
@ -298,12 +326,16 @@ nm_keep_alive_set_dbus_client_watch (NMKeepAlive *self,
|
|||
{
|
||||
NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
|
||||
|
||||
if (priv->disarmed)
|
||||
return;
|
||||
|
||||
cleanup_dbus_watch (self);
|
||||
|
||||
if (client_address) {
|
||||
_LOGD ("Registering dbus client watch for keep alive");
|
||||
|
||||
priv->dbus_client = g_strdup (client_address);
|
||||
priv->dbus_client_watching = TRUE;
|
||||
priv->dbus_client_confirmed = FALSE;
|
||||
priv->dbus_connection = g_object_ref (connection);
|
||||
priv->subscription_id = g_dbus_connection_signal_subscribe (connection,
|
||||
|
|
@ -316,13 +348,65 @@ nm_keep_alive_set_dbus_client_watch (NMKeepAlive *self,
|
|||
name_owner_changed_cb,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
} else
|
||||
priv->dbus_client_watching = FALSE;
|
||||
|
||||
_notify_alive (self);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_keep_alive_arm:
|
||||
* @self: the #NMKeepAlive
|
||||
*
|
||||
* A #NMKeepAlive instance is unarmed by default. That means, it's
|
||||
* alive and stays alive until being armed. Arming means, that the conditions
|
||||
* start to be actively evaluated, that the alive state may change, and
|
||||
* that property changed signals are emitted.
|
||||
*
|
||||
* The opposite is nm_keep_alive_disarm() which freezes the alive state
|
||||
* for good. Once disarmed, the instance cannot be armed again. Arming an
|
||||
* instance multiple times has no effect. Arming an already disarmed instance
|
||||
* also has no effect. */
|
||||
void
|
||||
nm_keep_alive_arm (NMKeepAlive *self)
|
||||
{
|
||||
NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
|
||||
|
||||
if (!priv->armed) {
|
||||
priv->armed = TRUE;
|
||||
_notify_alive (self);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_keep_alive_disarm:
|
||||
* @self: the #NMKeepAlive instance
|
||||
*
|
||||
* Once the instance is disarmed, it will not change its alive state
|
||||
* anymore and will not emit anymore property changed signals about
|
||||
* alive state changed.
|
||||
*
|
||||
* As such, it will also free internal resources (since they no longer
|
||||
* affect the externally visible state).
|
||||
*
|
||||
* Once disarmed, the instance is frozen and cannot change anymore.
|
||||
*/
|
||||
void
|
||||
nm_keep_alive_disarm (NMKeepAlive *self)
|
||||
{
|
||||
NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
|
||||
|
||||
priv->disarmed = TRUE;
|
||||
|
||||
/* release internal data. */
|
||||
_set_settings_connection_watch_visible (self, NULL, FALSE);
|
||||
cleanup_dbus_watch (self);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
get_property (GObject *object,
|
||||
guint prop_id,
|
||||
|
|
@ -343,22 +427,76 @@ get_property (GObject *object,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_keep_alive_get_owner:
|
||||
* @self: the #NMKeepAlive
|
||||
*
|
||||
* Returns: the owner instance associated with this @self. This commonly
|
||||
* is set to be the target instance, which @self guards for being alive.
|
||||
* Returns a gpointer, but of course it's some GObject instance. */
|
||||
gpointer /* GObject * */
|
||||
nm_keep_alive_get_owner (NMKeepAlive *self)
|
||||
{
|
||||
NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
|
||||
|
||||
nm_assert (!priv->owner || G_IS_OBJECT (priv->owner));
|
||||
|
||||
return priv->owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* _nm_keep_alive_set_owner:
|
||||
* @self: the #NMKeepAlive
|
||||
* @owner: the owner to set or unset.
|
||||
*
|
||||
* Sets or unsets the owner instance. Think of the owner the target
|
||||
* instance that is guarded by @self. It's the responsibility of the
|
||||
* owner to set and properly unset this pointer. As the owner also
|
||||
* controls the lifetime of the NMKeepAlive instance.
|
||||
*
|
||||
* This API is not to be called by everybody, but only the owner of
|
||||
* @self.
|
||||
*/
|
||||
void
|
||||
_nm_keep_alive_set_owner (NMKeepAlive *self,
|
||||
GObject *owner)
|
||||
{
|
||||
NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
|
||||
|
||||
nm_assert (!owner || G_IS_OBJECT (owner));
|
||||
|
||||
/* it's bad style to reset the owner object. You are supposed to
|
||||
* set it once, and clear it once. That's it. */
|
||||
nm_assert (!owner || !priv->owner);
|
||||
|
||||
/* optimally, we would take a reference to @owner. But the
|
||||
* owner already owns a refrence to the keep-alive, so we cannot
|
||||
* just own a reference back.
|
||||
*
|
||||
* We could register a weak-pointer here. But instead, declare that
|
||||
* owner is required to set itself as owner when creating the
|
||||
* keep-alive instance, and unset itself when it lets go of the
|
||||
* keep-alive instance (at latest, when the owner itself gets destroyed).
|
||||
*/
|
||||
priv->owner = owner;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nm_keep_alive_init (NMKeepAlive *self)
|
||||
{
|
||||
nm_assert (NM_KEEP_ALIVE_GET_PRIVATE (self)->alive == _is_alive (self));
|
||||
NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
|
||||
|
||||
priv->alive = TRUE;
|
||||
|
||||
nm_assert (priv->alive == _is_alive (self));
|
||||
}
|
||||
|
||||
NMKeepAlive *
|
||||
nm_keep_alive_new (gboolean floating)
|
||||
nm_keep_alive_new (void)
|
||||
{
|
||||
NMKeepAlive *self = g_object_new (NM_TYPE_KEEP_ALIVE, NULL);
|
||||
NMKeepAlivePrivate *priv = NM_KEEP_ALIVE_GET_PRIVATE (self);
|
||||
|
||||
priv->floating = floating;
|
||||
priv->alive = TRUE;
|
||||
nm_assert (priv->alive == _is_alive (self));
|
||||
return self;
|
||||
return g_object_new (NM_TYPE_KEEP_ALIVE, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -366,8 +504,10 @@ dispose (GObject *object)
|
|||
{
|
||||
NMKeepAlive *self = NM_KEEP_ALIVE (object);
|
||||
|
||||
_set_settings_connection_watch_visible (self, NULL, FALSE);
|
||||
cleanup_dbus_watch (self);
|
||||
nm_assert (!NM_KEEP_ALIVE_GET_PRIVATE (self)->owner);
|
||||
|
||||
/* disarm also happens to free all resources. */
|
||||
nm_keep_alive_disarm (self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -36,14 +36,12 @@ typedef struct _NMKeepAliveClass NMKeepAliveClass;
|
|||
|
||||
GType nm_keep_alive_get_type (void) G_GNUC_CONST;
|
||||
|
||||
NMKeepAlive* nm_keep_alive_new (gboolean floating);
|
||||
NMKeepAlive* nm_keep_alive_new (void);
|
||||
|
||||
gboolean nm_keep_alive_is_alive (NMKeepAlive *self);
|
||||
|
||||
void nm_keep_alive_sink (NMKeepAlive *self);
|
||||
|
||||
void nm_keep_alive_set_forced (NMKeepAlive *self,
|
||||
gboolean forced);
|
||||
void nm_keep_alive_arm (NMKeepAlive *self);
|
||||
void nm_keep_alive_disarm (NMKeepAlive *self);
|
||||
|
||||
void nm_keep_alive_set_settings_connection_watch_visible (NMKeepAlive *self,
|
||||
NMSettingsConnection *connection);
|
||||
|
|
@ -52,4 +50,10 @@ void nm_keep_alive_set_dbus_client_watch (NMKeepAlive *self,
|
|||
GDBusConnection *connection,
|
||||
const char *client_address);
|
||||
|
||||
gpointer /* GObject * */ nm_keep_alive_get_owner (NMKeepAlive *self);
|
||||
|
||||
/* _nm_keep_alive_set_owner() is reserved for the owner to set/unset itself. */
|
||||
void _nm_keep_alive_set_owner (NMKeepAlive *self,
|
||||
GObject *owner);
|
||||
|
||||
#endif /* __NETWORKMANAGER_KEEP_ALIVE_H__ */
|
||||
|
|
|
|||
130
src/nm-manager.c
130
src/nm-manager.c
|
|
@ -39,6 +39,7 @@
|
|||
#include "platform/nm-platform.h"
|
||||
#include "platform/nmp-object.h"
|
||||
#include "nm-hostname-manager.h"
|
||||
#include "nm-keep-alive.h"
|
||||
#include "nm-rfkill-manager.h"
|
||||
#include "dhcp/nm-dhcp-manager.h"
|
||||
#include "settings/nm-settings.h"
|
||||
|
|
@ -319,6 +320,7 @@ static NMActiveConnection *_new_active_connection (NMManager *self,
|
|||
NMAuthSubject *subject,
|
||||
NMActivationType activation_type,
|
||||
NMActivationReason activation_reason,
|
||||
NMActivationStateFlags initial_state_flags,
|
||||
GError **error);
|
||||
|
||||
static void policy_activating_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
|
||||
|
|
@ -2697,6 +2699,18 @@ recheck_assume_connection (NMManager *self,
|
|||
GError *error = NULL;
|
||||
|
||||
subject = nm_auth_subject_new_internal ();
|
||||
|
||||
/* Note: the lifetime of the activation connection is always bound to the profiles visiblity
|
||||
* via NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY.
|
||||
*
|
||||
* This only makes a difference, if the profile actually has "connection.permissions"
|
||||
* set to limit visibility (which is not the case for externally managed, generated profiles).
|
||||
*
|
||||
* If we assume a previously active connection whose lifetime was unbound, we now bind it
|
||||
* after restart. That is not correct, and can mean that the profile becomes subject to
|
||||
* deactivation after restart (if the user logs out).
|
||||
*
|
||||
* This should be improved, but it's unclear how. */
|
||||
active = _new_active_connection (self,
|
||||
FALSE,
|
||||
sett_conn,
|
||||
|
|
@ -2707,6 +2721,7 @@ recheck_assume_connection (NMManager *self,
|
|||
subject,
|
||||
generated ? NM_ACTIVATION_TYPE_EXTERNAL : NM_ACTIVATION_TYPE_ASSUME,
|
||||
generated ? NM_ACTIVATION_REASON_EXTERNAL : NM_ACTIVATION_REASON_ASSUME,
|
||||
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY,
|
||||
&error);
|
||||
|
||||
if (!active) {
|
||||
|
|
@ -3891,11 +3906,16 @@ ensure_master_active_connection (NMManager *self,
|
|||
GError **error)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
NMActiveConnection *ac;
|
||||
NMActiveConnection *master_ac = NULL;
|
||||
NMDeviceState master_state;
|
||||
gboolean bind_lifetime_to_profile_visibility;
|
||||
|
||||
g_assert (connection);
|
||||
g_assert (master_connection || master_device);
|
||||
g_return_val_if_fail (connection, NULL);
|
||||
g_return_val_if_fail (master_connection || master_device, FALSE);
|
||||
|
||||
bind_lifetime_to_profile_visibility = NM_FLAGS_HAS (nm_device_get_activation_state_flags (device),
|
||||
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY);
|
||||
|
||||
/* If the master device isn't activated then we need to activate it using
|
||||
* compatible connection. If it's already activating we can just proceed.
|
||||
|
|
@ -3920,8 +3940,16 @@ ensure_master_active_connection (NMManager *self,
|
|||
if ( (master_state == NM_DEVICE_STATE_ACTIVATED)
|
||||
|| nm_device_is_activating (master_device)) {
|
||||
/* Device already using master_connection */
|
||||
g_assert (device_connection);
|
||||
return NM_ACTIVE_CONNECTION (nm_device_get_act_request (master_device));
|
||||
ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (master_device));
|
||||
g_return_val_if_fail (device_connection, ac);
|
||||
|
||||
if (!bind_lifetime_to_profile_visibility) {
|
||||
/* unbind the lifetime. */
|
||||
nm_active_connection_set_state_flags_clear (ac,
|
||||
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY);
|
||||
}
|
||||
|
||||
return ac;
|
||||
}
|
||||
|
||||
/* If the device is disconnected, find a compatible connection and
|
||||
|
|
@ -3958,6 +3986,9 @@ ensure_master_active_connection (NMManager *self,
|
|||
subject,
|
||||
NM_ACTIVATION_TYPE_MANAGED,
|
||||
activation_reason,
|
||||
bind_lifetime_to_profile_visibility
|
||||
? NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY
|
||||
: NM_ACTIVATION_STATE_FLAG_NONE,
|
||||
error);
|
||||
return master_ac;
|
||||
}
|
||||
|
|
@ -4006,6 +4037,9 @@ ensure_master_active_connection (NMManager *self,
|
|||
subject,
|
||||
NM_ACTIVATION_TYPE_MANAGED,
|
||||
activation_reason,
|
||||
bind_lifetime_to_profile_visibility
|
||||
? NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY
|
||||
: NM_ACTIVATION_STATE_FLAG_NONE,
|
||||
error);
|
||||
return master_ac;
|
||||
}
|
||||
|
|
@ -4167,6 +4201,7 @@ autoconnect_slaves (NMManager *self,
|
|||
master_device)) {
|
||||
gs_free SlaveConnectionInfo *slaves = NULL;
|
||||
guint i, n_slaves = 0;
|
||||
gboolean bind_lifetime_to_profile_visibility;
|
||||
|
||||
slaves = find_slaves (self, master_connection, master_device, &n_slaves);
|
||||
if (n_slaves > 1) {
|
||||
|
|
@ -4181,6 +4216,10 @@ autoconnect_slaves (NMManager *self,
|
|||
GINT_TO_POINTER (!nm_streq0 (value, "index")));
|
||||
}
|
||||
|
||||
bind_lifetime_to_profile_visibility = n_slaves > 0
|
||||
&& NM_FLAGS_HAS (nm_device_get_activation_state_flags (master_device),
|
||||
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY);
|
||||
|
||||
for (i = 0; i < n_slaves; i++) {
|
||||
SlaveConnectionInfo *slave = &slaves[i];
|
||||
const char *uuid;
|
||||
|
|
@ -4235,6 +4274,9 @@ autoconnect_slaves (NMManager *self,
|
|||
subject,
|
||||
NM_ACTIVATION_TYPE_MANAGED,
|
||||
NM_ACTIVATION_REASON_AUTOCONNECT_SLAVES,
|
||||
bind_lifetime_to_profile_visibility
|
||||
? NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY
|
||||
: NM_ACTIVATION_STATE_FLAG_NONE,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
_LOGW (LOGD_CORE, "Slave connection activation failed: %s", local_err->message);
|
||||
|
|
@ -4295,6 +4337,40 @@ unmanaged_to_disconnected (NMDevice *device)
|
|||
}
|
||||
}
|
||||
|
||||
static NMActivationStateFlags
|
||||
_activation_bind_lifetime_to_profile_visibility (NMAuthSubject *subject)
|
||||
{
|
||||
if ( nm_auth_subject_is_internal (subject)
|
||||
|| nm_auth_subject_get_unix_process_uid (subject) == 0) {
|
||||
/* internal requests and requests from root are always unbound. */
|
||||
return NM_ACTIVATION_STATE_FLAG_NONE;
|
||||
}
|
||||
|
||||
/* if the activation was not done by internal decision nor root, there
|
||||
* are the following cases:
|
||||
*
|
||||
* - the connection has "connection.permissions" unset and the profile
|
||||
* is not restricted to a user and commonly always visible. It does
|
||||
* not hurt to bind the lifetime, because we expect the profile to be
|
||||
* visible at the moment. If the profile changes (while still being active),
|
||||
* we want to pick-up changes to the visibility and possibly disconnect.
|
||||
*
|
||||
* - the connection has "connection.permissions" set, and the current user
|
||||
* is the owner:
|
||||
*
|
||||
* - Usually, we would expect that the profile is visible at the moment,
|
||||
* and of course we want to bind the lifetime. The moment the user
|
||||
* logs out, the connection becomes invisible and disconnects.
|
||||
*
|
||||
* - the profile at this time could already be invisible (e.g. if the
|
||||
* user didn't ceate a proper session (sudo) and manually activates
|
||||
* an invisible profile. In this case, we still want to bind the
|
||||
* lifetime, and it will disconnect after the user logs in and logs
|
||||
* out again. NMKeepAlive takes care of that.
|
||||
*/
|
||||
return NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY;
|
||||
}
|
||||
|
||||
/* The parent connection is ready; we can proceed realizing the device and
|
||||
* progressing the device to disconencted state.
|
||||
*/
|
||||
|
|
@ -4424,6 +4500,8 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
|
|||
subject,
|
||||
NM_ACTIVATION_TYPE_MANAGED,
|
||||
nm_active_connection_get_activation_reason (active),
|
||||
nm_active_connection_get_state_flags (active)
|
||||
& NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY,
|
||||
error);
|
||||
if (!parent_ac) {
|
||||
g_prefix_error (error, "%s failed to activate parent: ", nm_device_get_iface (device));
|
||||
|
|
@ -4549,7 +4627,9 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
|
|||
for (i = 0; i < n_all; i++) {
|
||||
nm_device_disconnect_active_connection ( all_ac_arr
|
||||
? all_ac_arr->pdata[i]
|
||||
: ac);
|
||||
: ac,
|
||||
NM_DEVICE_STATE_REASON_NEW_ACTIVATION,
|
||||
NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4622,6 +4702,7 @@ _new_active_connection (NMManager *self,
|
|||
NMAuthSubject *subject,
|
||||
NMActivationType activation_type,
|
||||
NMActivationReason activation_reason,
|
||||
NMActivationStateFlags initial_state_flags,
|
||||
GError **error)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
|
|
@ -4693,6 +4774,7 @@ _new_active_connection (NMManager *self,
|
|||
parent_device,
|
||||
nm_dbus_object_get_path (NM_DBUS_OBJECT (parent)),
|
||||
activation_reason,
|
||||
initial_state_flags,
|
||||
subject);
|
||||
}
|
||||
|
||||
|
|
@ -4702,6 +4784,7 @@ _new_active_connection (NMManager *self,
|
|||
subject,
|
||||
activation_type,
|
||||
activation_reason,
|
||||
initial_state_flags,
|
||||
device);
|
||||
}
|
||||
|
||||
|
|
@ -4765,6 +4848,7 @@ fail:
|
|||
* @activation_type: whether to assume the connection. That is, take over gracefully,
|
||||
* non-destructible.
|
||||
* @activation_reason: the reason for activation
|
||||
* @initial_state_flags: the inital state flags for the activation.
|
||||
* @error: return location for an error
|
||||
*
|
||||
* Begins a new internally-initiated activation of @sett_conn on @device.
|
||||
|
|
@ -4786,6 +4870,7 @@ nm_manager_activate_connection (NMManager *self,
|
|||
NMAuthSubject *subject,
|
||||
NMActivationType activation_type,
|
||||
NMActivationReason activation_reason,
|
||||
NMActivationStateFlags initial_state_flags,
|
||||
GError **error)
|
||||
{
|
||||
NMManagerPrivate *priv;
|
||||
|
|
@ -4839,6 +4924,7 @@ nm_manager_activate_connection (NMManager *self,
|
|||
subject,
|
||||
activation_type,
|
||||
activation_reason,
|
||||
initial_state_flags,
|
||||
error);
|
||||
if (!active)
|
||||
return NULL;
|
||||
|
|
@ -5098,6 +5184,7 @@ impl_manager_activate_connection (NMDBusObject *obj,
|
|||
subject,
|
||||
NM_ACTIVATION_TYPE_MANAGED,
|
||||
NM_ACTIVATION_REASON_USER_REQUEST,
|
||||
_activation_bind_lifetime_to_profile_visibility (subject),
|
||||
&error);
|
||||
if (!active)
|
||||
goto error;
|
||||
|
|
@ -5372,12 +5459,18 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
|
|||
subject,
|
||||
NM_ACTIVATION_TYPE_MANAGED,
|
||||
NM_ACTIVATION_REASON_USER_REQUEST,
|
||||
_activation_bind_lifetime_to_profile_visibility (subject),
|
||||
&error);
|
||||
if (!active)
|
||||
goto error;
|
||||
|
||||
if (bind_dbus_client)
|
||||
nm_active_connection_bind_dbus_client (active, dbus_connection, sender);
|
||||
if (bind_dbus_client) {
|
||||
NMKeepAlive *keep_alive;
|
||||
|
||||
keep_alive = nm_active_connection_get_keep_alive (active);
|
||||
nm_keep_alive_set_dbus_client_watch (keep_alive, dbus_connection, sender);
|
||||
nm_keep_alive_arm (keep_alive);
|
||||
}
|
||||
|
||||
nm_active_connection_authorize (active,
|
||||
incompl_conn,
|
||||
|
|
@ -5406,31 +5499,26 @@ nm_manager_deactivate_connection (NMManager *manager,
|
|||
NMDeviceStateReason reason,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
|
||||
if (NM_IS_VPN_CONNECTION (active)) {
|
||||
NMActiveConnectionStateReason vpn_reason = NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED;
|
||||
|
||||
if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
|
||||
vpn_reason = NM_ACTIVE_CONNECTION_STATE_REASON_CONNECTION_REMOVED;
|
||||
|
||||
if (nm_vpn_connection_deactivate (NM_VPN_CONNECTION (active), vpn_reason, FALSE))
|
||||
success = TRUE;
|
||||
else
|
||||
if (!nm_vpn_connection_deactivate (NM_VPN_CONNECTION (active), vpn_reason, FALSE)) {
|
||||
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
|
||||
"The VPN connection was not active.");
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
g_assert (NM_IS_ACT_REQUEST (active));
|
||||
nm_device_state_changed (nm_active_connection_get_device (active),
|
||||
NM_DEVICE_STATE_DEACTIVATING,
|
||||
reason);
|
||||
success = TRUE;
|
||||
nm_assert (NM_IS_ACT_REQUEST (active));
|
||||
nm_device_disconnect_active_connection (active,
|
||||
reason,
|
||||
NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN);
|
||||
}
|
||||
|
||||
if (success)
|
||||
_notify (manager, PROP_ACTIVE_CONNECTIONS);
|
||||
|
||||
return success;
|
||||
_notify (manager, PROP_ACTIVE_CONNECTIONS);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -97,6 +97,19 @@ const CList * nm_manager_get_active_connections (NMManager *manager);
|
|||
}); \
|
||||
iter = c_list_entry (iter->active_connections_lst.next, NMActiveConnection, active_connections_lst))
|
||||
|
||||
#define nm_manager_for_each_active_connection_safe(manager, iter, tmp_list, iter_safe) \
|
||||
for (tmp_list = nm_manager_get_active_connections (manager), \
|
||||
iter_safe = tmp_list->next; \
|
||||
({ \
|
||||
if (iter_safe != tmp_list) { \
|
||||
iter = c_list_entry (iter_safe, NMActiveConnection, active_connections_lst); \
|
||||
iter_safe = iter_safe->next; \
|
||||
} else \
|
||||
iter = NULL; \
|
||||
(iter != NULL); \
|
||||
}); \
|
||||
)
|
||||
|
||||
NMSettingsConnection **nm_manager_get_activatable_connections (NMManager *manager,
|
||||
gboolean for_auto_activation,
|
||||
gboolean sort,
|
||||
|
|
@ -121,6 +134,19 @@ const CList * nm_manager_get_devices (NMManager *manager);
|
|||
}); \
|
||||
iter = c_list_entry (iter->devices_lst.next, NMDevice, devices_lst))
|
||||
|
||||
#define nm_manager_for_each_device_safe(manager, iter, tmp_list, iter_safe) \
|
||||
for (tmp_list = nm_manager_get_devices (manager), \
|
||||
iter_safe = tmp_list->next; \
|
||||
({ \
|
||||
if (iter_safe != tmp_list) { \
|
||||
iter = c_list_entry (iter_safe, NMDevice, devices_lst); \
|
||||
iter_safe = iter_safe->next; \
|
||||
} else \
|
||||
iter = NULL; \
|
||||
(iter != NULL); \
|
||||
}); \
|
||||
)
|
||||
|
||||
NMDevice * nm_manager_get_device_by_ifindex (NMManager *manager,
|
||||
int ifindex);
|
||||
NMDevice * nm_manager_get_device_by_path (NMManager *manager,
|
||||
|
|
@ -149,6 +175,7 @@ NMActiveConnection *nm_manager_activate_connection (NMManager *manager,
|
|||
NMAuthSubject *subject,
|
||||
NMActivationType activation_type,
|
||||
NMActivationReason activation_reason,
|
||||
NMActivationStateFlags initial_state_flags,
|
||||
GError **error);
|
||||
|
||||
gboolean nm_manager_deactivate_connection (NMManager *manager,
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-act-request.h"
|
||||
#include "nm-keep-alive.h"
|
||||
#include "devices/nm-device.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
#include "nm-setting-connection.h"
|
||||
|
|
@ -1283,6 +1284,7 @@ auto_activate_device (NMPolicy *self,
|
|||
subject,
|
||||
NM_ACTIVATION_TYPE_MANAGED,
|
||||
NM_ACTIVATION_REASON_AUTOCONNECT,
|
||||
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY,
|
||||
&error);
|
||||
if (!ac) {
|
||||
_LOGI (LOGD_DEVICE, "connection '%s' auto-activation failed: %s",
|
||||
|
|
@ -1673,9 +1675,14 @@ activate_secondary_connections (NMPolicy *self,
|
|||
GError *error = NULL;
|
||||
guint32 i;
|
||||
gboolean success = TRUE;
|
||||
NMActivationStateFlags initial_state_flags;
|
||||
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
nm_assert (s_con);
|
||||
nm_assert (NM_IS_SETTING_CONNECTION (s_con));
|
||||
|
||||
/* we propagate the activation's state flags. */
|
||||
initial_state_flags = nm_device_get_activation_state_flags (device)
|
||||
& NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY;
|
||||
|
||||
for (i = 0; i < nm_setting_connection_get_num_secondaries (s_con); i++) {
|
||||
NMSettingsConnection *sett_conn;
|
||||
|
|
@ -1699,7 +1706,6 @@ activate_secondary_connections (NMPolicy *self,
|
|||
}
|
||||
|
||||
req = nm_device_get_act_request (device);
|
||||
g_assert (req);
|
||||
|
||||
_LOGD (LOGD_DEVICE, "activating secondary connection '%s (%s)' for base connection '%s (%s)'",
|
||||
nm_settings_connection_get_id (sett_conn), sec_uuid,
|
||||
|
|
@ -1712,6 +1718,7 @@ activate_secondary_connections (NMPolicy *self,
|
|||
nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (req)),
|
||||
NM_ACTIVATION_TYPE_MANAGED,
|
||||
nm_active_connection_get_activation_reason (NM_ACTIVE_CONNECTION (req)),
|
||||
initial_state_flags,
|
||||
&error);
|
||||
if (ac)
|
||||
secondary_ac_list = g_slist_append (secondary_ac_list, g_object_ref (ac));
|
||||
|
|
@ -2161,6 +2168,8 @@ vpn_connection_retry_after_failure (NMVpnConnection *vpn, NMPolicy *self)
|
|||
nm_active_connection_get_subject (ac),
|
||||
NM_ACTIVATION_TYPE_MANAGED,
|
||||
nm_active_connection_get_activation_reason (ac),
|
||||
( nm_active_connection_get_state_flags (ac)
|
||||
& NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY),
|
||||
&error)) {
|
||||
_LOGW (LOGD_DEVICE, "VPN '%s' reconnect failed: %s",
|
||||
nm_settings_connection_get_id (connection),
|
||||
|
|
@ -2183,26 +2192,36 @@ active_connection_state_changed (NMActiveConnection *active,
|
|||
}
|
||||
|
||||
static void
|
||||
active_connection_keep_alive_changed (NMActiveConnection *ac,
|
||||
active_connection_keep_alive_changed (NMKeepAlive *keep_alive,
|
||||
GParamSpec *pspec,
|
||||
NMPolicy *self)
|
||||
{
|
||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||
NMPolicyPrivate *priv;
|
||||
NMActiveConnection *ac;
|
||||
GError *error = NULL;
|
||||
|
||||
if (nm_active_connection_get_keep_alive (ac))
|
||||
nm_assert (NM_IS_POLICY (self));
|
||||
nm_assert (NM_IS_KEEP_ALIVE (keep_alive));
|
||||
nm_assert (NM_IS_ACTIVE_CONNECTION (nm_keep_alive_get_owner (keep_alive)));
|
||||
|
||||
if (nm_keep_alive_is_alive (keep_alive))
|
||||
return;
|
||||
|
||||
if (nm_active_connection_get_state (ac) <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
|
||||
if (!nm_manager_deactivate_connection (priv->manager,
|
||||
ac,
|
||||
NM_DEVICE_STATE_REASON_CONNECTION_REMOVED,
|
||||
&error)) {
|
||||
_LOGW (LOGD_DEVICE, "connection '%s' is no longer kept alive, but error deactivating it: %s",
|
||||
nm_active_connection_get_settings_connection_id (ac),
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
ac = nm_keep_alive_get_owner (keep_alive);
|
||||
|
||||
if (nm_active_connection_get_state (ac) > NM_ACTIVE_CONNECTION_STATE_ACTIVATED)
|
||||
return;
|
||||
|
||||
priv = NM_POLICY_GET_PRIVATE (self);
|
||||
|
||||
if (!nm_manager_deactivate_connection (priv->manager,
|
||||
ac,
|
||||
NM_DEVICE_STATE_REASON_CONNECTION_REMOVED,
|
||||
&error)) {
|
||||
_LOGW (LOGD_DEVICE, "connection '%s' is no longer kept alive, but error deactivating it: %s",
|
||||
nm_active_connection_get_settings_connection_id (ac),
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2213,6 +2232,7 @@ active_connection_added (NMManager *manager,
|
|||
{
|
||||
NMPolicyPrivate *priv = user_data;
|
||||
NMPolicy *self = _PRIV_TO_SELF (priv);
|
||||
NMKeepAlive *keep_alive;
|
||||
|
||||
if (NM_IS_VPN_CONNECTION (active)) {
|
||||
g_signal_connect (active, NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED,
|
||||
|
|
@ -2223,13 +2243,18 @@ active_connection_added (NMManager *manager,
|
|||
self);
|
||||
}
|
||||
|
||||
keep_alive = nm_active_connection_get_keep_alive (active);
|
||||
|
||||
nm_keep_alive_arm (keep_alive);
|
||||
|
||||
g_signal_connect (active, "notify::" NM_ACTIVE_CONNECTION_STATE,
|
||||
G_CALLBACK (active_connection_state_changed),
|
||||
self);
|
||||
g_signal_connect (active, "notify::" NM_ACTIVE_CONNECTION_INT_KEEP_ALIVE,
|
||||
g_signal_connect (keep_alive,
|
||||
"notify::" NM_KEEP_ALIVE_ALIVE,
|
||||
G_CALLBACK (active_connection_keep_alive_changed),
|
||||
self);
|
||||
active_connection_keep_alive_changed (active, NULL, self);
|
||||
active_connection_keep_alive_changed (keep_alive, NULL, self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2249,6 +2274,9 @@ active_connection_removed (NMManager *manager,
|
|||
g_signal_handlers_disconnect_by_func (active,
|
||||
active_connection_state_changed,
|
||||
self);
|
||||
g_signal_handlers_disconnect_by_func (nm_active_connection_get_keep_alive (active),
|
||||
active_connection_keep_alive_changed,
|
||||
self);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -2386,12 +2414,12 @@ _deactivate_if_active (NMPolicy *self, NMSettingsConnection *connection)
|
|||
{
|
||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||
NMActiveConnection *ac;
|
||||
const CList *tmp_list;
|
||||
const CList *tmp_list, *tmp_safe;
|
||||
GError *error = NULL;
|
||||
|
||||
nm_assert (NM_IS_SETTINGS_CONNECTION (connection));
|
||||
|
||||
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
|
||||
nm_manager_for_each_active_connection_safe (priv->manager, ac, tmp_list, tmp_safe) {
|
||||
|
||||
if ( nm_active_connection_get_settings_connection (ac) == connection
|
||||
&& (nm_active_connection_get_state (ac) <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) {
|
||||
|
|
|
|||
|
|
@ -851,6 +851,7 @@ nm_vpn_connection_new (NMSettingsConnection *settings_connection,
|
|||
NMDevice *parent_device,
|
||||
const char *specific_object,
|
||||
NMActivationReason activation_reason,
|
||||
NMActivationStateFlags initial_state_flags,
|
||||
NMAuthSubject *subject)
|
||||
{
|
||||
g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
|
||||
|
|
@ -864,6 +865,7 @@ nm_vpn_connection_new (NMSettingsConnection *settings_connection,
|
|||
NM_ACTIVE_CONNECTION_INT_SUBJECT, subject,
|
||||
NM_ACTIVE_CONNECTION_INT_ACTIVATION_REASON, activation_reason,
|
||||
NM_ACTIVE_CONNECTION_VPN, TRUE,
|
||||
NM_ACTIVE_CONNECTION_STATE_FLAGS, (guint) initial_state_flags,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ NMVpnConnection * nm_vpn_connection_new (NMSettingsConnection *settings_connecti
|
|||
NMDevice *parent_device,
|
||||
const char *specific_object,
|
||||
NMActivationReason activation_reason,
|
||||
NMActivationStateFlags initial_state_flags,
|
||||
NMAuthSubject *subject);
|
||||
|
||||
void nm_vpn_connection_activate (NMVpnConnection *self,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue