core: track NMActiveConnection in manager with CList

Using CList, we embed the list element in NMActiveConnection struct
itself. That means for example, that you couldn't track a
NMActiveConnection more then once. But we anyway never want that.

The advantage is, that removing an active connection from the list
is O(1), and we safe additional GSlice allocations for each node
element.
This commit is contained in:
Thomas Haller 2017-11-23 21:30:09 +01:00
parent 51531c9539
commit 3a907377ac
6 changed files with 166 additions and 163 deletions

View file

@ -1289,6 +1289,8 @@ nm_active_connection_init (NMActiveConnection *self)
priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionPrivate);
self->_priv = priv;
c_list_init (&self->active_connections_lst);
_LOGT ("creating");
priv->activation_type = NM_ACTIVATION_TYPE_MANAGED;
@ -1331,6 +1333,8 @@ dispose (GObject *object)
NMActiveConnection *self = NM_ACTIVE_CONNECTION (object);
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
nm_assert (!c_list_is_linked (&self->active_connections_lst));
_LOGD ("disposing");
if (priv->chain) {

View file

@ -24,6 +24,8 @@
#include "nm-exported-object.h"
#include "nm-connection.h"
#include "nm-utils/c-list.h"
#define NM_TYPE_ACTIVE_CONNECTION (nm_active_connection_get_type ())
#define NM_ACTIVE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnection))
#define NM_ACTIVE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionClass))
@ -71,6 +73,10 @@ struct _NMActiveConnectionPrivate;
struct _NMActiveConnection {
NMExportedObject parent;
struct _NMActiveConnectionPrivate *_priv;
/* active connection can be tracked in a list by NMManager. This is
* the list node. */
CList active_connections_lst;
};
typedef struct {

View file

@ -125,10 +125,10 @@ find_settings_connection (NMCheckpoint *self,
gboolean *need_activation)
{
NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (self);
const GSList *active_connections, *iter;
NMActiveConnection *active = NULL;
NMActiveConnection *active;
NMSettingsConnection *connection;
const char *uuid, *ac_uuid;
const CList *tmp_clist;
*need_activation = FALSE;
*need_update = FALSE;
@ -149,9 +149,7 @@ find_settings_connection (NMCheckpoint *self,
}
/* ... is active, ... */
active_connections = nm_manager_get_active_connections (priv->manager);
for (iter = active_connections; iter; iter = g_slist_next (iter)) {
active = iter->data;
nm_manager_for_each_active_connection (priv->manager, active, tmp_clist) {
ac_uuid = nm_settings_connection_get_uuid (nm_active_connection_get_settings_connection (active));
if (nm_streq (uuid, ac_uuid)) {
_LOGT ("rollback: connection %s is active", uuid);
@ -159,7 +157,7 @@ find_settings_connection (NMCheckpoint *self,
}
}
if (!iter) {
if (!active) {
_LOGT ("rollback: connection %s is not active", uuid);
*need_activation = TRUE;
return connection;

View file

@ -114,7 +114,7 @@ typedef struct {
GArray *capabilities;
GSList *active_connections;
CList active_connections_lst_head;
GSList *authorizing_connections;
guint ac_cleanup_id;
NMActiveConnection *primary_connection;
@ -314,39 +314,38 @@ static gboolean
active_connection_remove (NMManager *self, NMActiveConnection *active)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
gboolean notify = nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active));
GSList *found;
NMSettingsConnection *connection;
gboolean notify;
/* FIXME: switch to a GList for faster removal */
found = g_slist_find (priv->active_connections, active);
if (found) {
NMSettingsConnection *connection;
nm_assert (NM_IS_ACTIVE_CONNECTION (active));
nm_assert (c_list_contains (&priv->active_connections_lst_head, &active->active_connections_lst));
priv->active_connections = g_slist_remove (priv->active_connections, active);
g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active);
g_signal_handlers_disconnect_by_func (active, active_connection_state_changed, self);
g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self);
g_signal_handlers_disconnect_by_func (active, active_connection_parent_active, self);
notify = nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active));
if ( (connection = nm_active_connection_get_settings_connection (active))
&& nm_settings_connection_get_volatile (connection))
g_object_ref (connection);
else
connection = NULL;
c_list_unlink_init (&active->active_connections_lst);
g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active);
g_signal_handlers_disconnect_by_func (active, active_connection_state_changed, self);
g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self);
g_signal_handlers_disconnect_by_func (active, active_connection_parent_active, self);
nm_exported_object_clear_and_unexport (&active);
if ( (connection = nm_active_connection_get_settings_connection (active))
&& nm_settings_connection_get_volatile (connection))
g_object_ref (connection);
else
connection = NULL;
if (connection) {
if (nm_settings_has_connection (priv->settings, connection)) {
_LOGD (LOGD_DEVICE, "assumed connection disconnected. Deleting generated connection '%s' (%s)",
nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
nm_settings_connection_delete (connection, NULL);
}
g_object_unref (connection);
nm_exported_object_clear_and_unexport (&active);
if (connection) {
if (nm_settings_has_connection (priv->settings, connection)) {
_LOGD (LOGD_DEVICE, "assumed connection disconnected. Deleting generated connection '%s' (%s)",
nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
nm_settings_connection_delete (connection, NULL);
}
g_object_unref (connection);
}
return found && notify;
return notify;
}
static gboolean
@ -354,16 +353,12 @@ _active_connection_cleanup (gpointer user_data)
{
NMManager *self = NM_MANAGER (user_data);
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
GSList *iter;
NMActiveConnection *ac, *ac_safe;
priv->ac_cleanup_id = 0;
g_object_freeze_notify (G_OBJECT (self));
iter = priv->active_connections;
while (iter) {
NMActiveConnection *ac = iter->data;
iter = iter->next;
c_list_for_each_entry_safe (ac, ac_safe, &priv->active_connections_lst_head, active_connections_lst) {
if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
if (active_connection_remove (self, ac))
_notify (self, PROP_ACTIVE_CONNECTIONS);
@ -421,10 +416,11 @@ active_connection_add (NMManager *self, NMActiveConnection *active)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
g_return_if_fail (g_slist_find (priv->active_connections, active) == FALSE);
nm_assert (NM_IS_ACTIVE_CONNECTION (active));
nm_assert (!c_list_is_linked (&active->active_connections_lst));
priv->active_connections = g_slist_prepend (priv->active_connections,
g_object_ref (active));
c_list_link_front (&priv->active_connections_lst_head, &active->active_connections_lst);
g_object_ref (active);
g_signal_connect (active,
"notify::" NM_ACTIVE_CONNECTION_STATE,
@ -446,10 +442,10 @@ active_connection_add (NMManager *self, NMActiveConnection *active)
_notify (self, PROP_ACTIVE_CONNECTIONS);
}
const GSList *
const CList *
nm_manager_get_active_connections (NMManager *manager)
{
return NM_MANAGER_GET_PRIVATE (manager)->active_connections;
return &NM_MANAGER_GET_PRIVATE (manager)->active_connections_lst_head;
}
static NMActiveConnection *
@ -458,16 +454,12 @@ active_connection_find_first (NMManager *self,
const char *uuid,
NMActiveConnectionState max_state)
{
NMManagerPrivate *priv;
GSList *iter;
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMActiveConnection *ac;
g_return_val_if_fail (NM_IS_MANAGER (self), NULL);
g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
nm_assert (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection));
priv = NM_MANAGER_GET_PRIVATE (self);
for (iter = priv->active_connections; iter; iter = iter->next) {
NMActiveConnection *ac = iter->data;
c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) {
NMSettingsConnection *con;
con = nm_active_connection_get_settings_connection (ac);
@ -527,16 +519,13 @@ static NMActiveConnection *
active_connection_get_by_path (NMManager *manager, const char *path)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
GSList *iter;
NMActiveConnection *ac;
g_return_val_if_fail (manager != NULL, NULL);
g_return_val_if_fail (path != NULL, NULL);
nm_assert (path);
for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
NMActiveConnection *candidate = iter->data;
if (g_strcmp0 (path, nm_exported_object_get_path (NM_EXPORTED_OBJECT (candidate))) == 0)
return candidate;
c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) {
if (nm_streq0 (path, nm_exported_object_get_path (NM_EXPORTED_OBJECT (ac))))
return ac;
}
return NULL;
}
@ -818,10 +807,9 @@ find_best_device_state (NMManager *manager)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
NMState best_state = NM_STATE_DISCONNECTED;
GSList *iter;
NMActiveConnection *ac;
for (iter = priv->active_connections; iter; iter = iter->next) {
NMActiveConnection *ac = NM_ACTIVE_CONNECTION (iter->data);
c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) {
NMActiveConnectionState ac_state = nm_active_connection_get_state (ac);
switch (ac_state) {
@ -3624,11 +3612,11 @@ _internal_activation_auth_done (NMActiveConnection *active,
gpointer user_data1,
gpointer user_data2)
{
_nm_unused gs_unref_object NMActiveConnection *active_to_free = active;
NMManager *self = user_data1;
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMActiveConnection *candidate;
GError *error = NULL;
GSList *iter;
NMActiveConnection *ac;
gs_free_error GError *error = NULL;
priv->authorizing_connections = g_slist_remove (priv->authorizing_connections, active);
@ -3637,12 +3625,12 @@ _internal_activation_auth_done (NMActiveConnection *active,
* detect a duplicate if the existing active connection is undergoing
* authorization in impl_manager_activate_connection().
*/
if (success && nm_auth_subject_is_internal (nm_active_connection_get_subject (active))) {
for (iter = priv->active_connections; iter; iter = iter->next) {
candidate = iter->data;
if ( nm_active_connection_get_device (candidate) == nm_active_connection_get_device (active)
&& nm_active_connection_get_settings_connection (candidate) == nm_active_connection_get_settings_connection (active)
&& NM_IN_SET (nm_active_connection_get_state (candidate),
if ( success
&& nm_auth_subject_is_internal (nm_active_connection_get_subject (active))) {
c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) {
if ( nm_active_connection_get_device (ac) == nm_active_connection_get_device (active)
&& nm_active_connection_get_settings_connection (ac) == nm_active_connection_get_settings_connection (active)
&& NM_IN_SET (nm_active_connection_get_state (ac),
NM_ACTIVE_CONNECTION_STATE_ACTIVATING,
NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) {
g_set_error (&error,
@ -3657,16 +3645,12 @@ _internal_activation_auth_done (NMActiveConnection *active,
}
if (success) {
if (_internal_activate_generic (self, active, &error)) {
g_object_unref (active);
if (_internal_activate_generic (self, active, &error))
return;
}
}
g_assert (error_desc || error);
nm_assert (error_desc || error);
_internal_activation_failed (self, active, error_desc ? error_desc : error->message);
g_object_unref (active);
g_clear_error (&error);
}
/**
@ -5990,19 +5974,15 @@ periodic_update_active_connection_timestamps (gpointer user_data)
{
NMManager *manager = NM_MANAGER (user_data);
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
GSList *iter;
for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
NMActiveConnection *ac = iter->data;
NMSettingsConnection *connection;
NMActiveConnection *ac;
c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) {
if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
connection = nm_active_connection_get_settings_connection (ac);
nm_settings_connection_update_timestamp (connection, (guint64) time (NULL), FALSE);
nm_settings_connection_update_timestamp (nm_active_connection_get_settings_connection (ac),
(guint64) time (NULL), FALSE);
}
}
return TRUE;
return G_SOURCE_CONTINUE;
}
static void
@ -6164,6 +6144,7 @@ nm_manager_init (NMManager *self)
GFile *file;
c_list_init (&priv->link_cb_lst);
c_list_init (&priv->active_connections_lst_head);
priv->platform = g_object_ref (NM_PLATFORM_GET);
@ -6252,6 +6233,10 @@ get_property (GObject *object, guint prop_id,
const NMGlobalDnsConfig *dns_config;
const char *type;
char **strv;
const char *path;
NMActiveConnection *ac;
GPtrArray *ptrarr;
gboolean vbool;
switch (prop_id) {
case PROP_VERSION:
@ -6291,7 +6276,14 @@ get_property (GObject *object, guint prop_id,
g_value_set_boolean (value, FALSE);
break;
case PROP_ACTIVE_CONNECTIONS:
nm_utils_g_value_set_object_path_array (value, priv->active_connections, NULL, NULL);
ptrarr = g_ptr_array_new ();
c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) {
path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (ac));
if (path)
g_ptr_array_add (ptrarr, g_strdup (path));
}
g_ptr_array_add (ptrarr, NULL);
g_value_take_boxed (value, g_ptr_array_free (ptrarr, FALSE));
break;
case PROP_CONNECTIVITY:
g_value_set_uint (value, priv->connectivity_state);
@ -6302,15 +6294,11 @@ get_property (GObject *object, guint prop_id,
break;
case PROP_CONNECTIVITY_CHECK_ENABLED:
#if WITH_CONCHECK
{
NMConnectivity *connectivity;
connectivity = nm_connectivity_get ();
g_value_set_boolean (value, nm_connectivity_check_enabled (connectivity));
}
vbool = nm_connectivity_check_enabled (nm_connectivity_get ());
#else
g_value_set_boolean (value, FALSE);
vbool = FALSE;
#endif
g_value_set_boolean (value, FALSE);
break;
case PROP_PRIMARY_CONNECTION:
nm_utils_g_value_set_object_path (value, priv->primary_connection);
@ -6415,6 +6403,7 @@ dispose (GObject *object)
NMManager *self = NM_MANAGER (object);
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
CList *iter, *iter_safe;
NMActiveConnection *ac, *ac_safe;
g_signal_handlers_disconnect_by_func (priv->platform,
G_CALLBACK (platform_link_cb),
@ -6448,9 +6437,9 @@ dispose (GObject *object)
nm_clear_g_source (&priv->ac_cleanup_id);
while (priv->active_connections)
active_connection_remove (self, NM_ACTIVE_CONNECTION (priv->active_connections->data));
g_clear_pointer (&priv->active_connections, g_slist_free);
c_list_for_each_entry_safe (ac, ac_safe, &priv->active_connections_lst_head, active_connections_lst)
active_connection_remove (self, ac);
nm_assert (c_list_is_empty (&priv->active_connections_lst_head));
g_clear_object (&priv->primary_connection);
g_clear_object (&priv->activating_connection);

View file

@ -24,6 +24,7 @@
#include "nm-exported-object.h"
#include "settings/nm-settings-connection.h"
#include "nm-utils/c-list.h"
#define NM_TYPE_MANAGER (nm_manager_get_type ())
#define NM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MANAGER, NMManager))
@ -85,7 +86,19 @@ gboolean nm_manager_start (NMManager *manager,
GError **error);
void nm_manager_stop (NMManager *manager);
NMState nm_manager_get_state (NMManager *manager);
const GSList *nm_manager_get_active_connections (NMManager *manager);
const CList * nm_manager_get_active_connections (NMManager *manager);
#define nm_manager_for_each_active_connection(manager, iter, tmp_list) \
for (tmp_list = nm_manager_get_active_connections (manager), \
iter = c_list_entry (tmp_list->next, NMActiveConnection, active_connections_lst); \
({ \
gboolean _has_next = (&iter->active_connections_lst != tmp_list); \
\
if (!_has_next) \
iter = NULL; \
_has_next; \
}); \
iter = c_list_entry (iter->active_connections_lst.next, NMActiveConnection, active_connections_lst))
NMSettingsConnection **nm_manager_get_activatable_connections (NMManager *manager,
guint *out_len,

View file

@ -312,8 +312,9 @@ device_ip6_prefix_delegated (NMDevice *device,
NMPolicyPrivate *priv = user_data;
NMPolicy *self = _PRIV_TO_SELF (priv);
IP6PrefixDelegation *delegation = NULL;
const GSList *connections, *iter;
guint i;
const CList *tmp_list;
NMActiveConnection *ac;
_LOGI (LOGD_IP6, "ipv6-pd: received a prefix %s/%d from %s",
nm_utils_inet6_ntop (&prefix->address, NULL),
@ -344,10 +345,10 @@ device_ip6_prefix_delegated (NMDevice *device,
* so traversing it from the beginning makes it likely for newly
* activated connections that have no subnet assigned to be served
* first. That is a simple yet fair policy, which is good. */
connections = nm_manager_get_active_connections (priv->manager);
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMDevice *to_device = nm_active_connection_get_device (iter->data);
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
NMDevice *to_device;
to_device = nm_active_connection_get_device (ac);
if (nm_device_needs_ip6_subnet (to_device))
ip6_subnet_from_delegation (delegation, to_device);
}
@ -822,16 +823,16 @@ update_default_ac (NMPolicy *self,
void (*set_active_func)(NMActiveConnection*, gboolean))
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
const GSList *connections, *iter;
const CList *tmp_list;
NMActiveConnection *ac;
/* Clear the 'default[6]' flag on all active connections that aren't the new
* default active connection. We'll set the new default after; this ensures
* we don't ever have two marked 'default[6]' simultaneously.
*/
connections = nm_manager_get_active_connections (priv->manager);
for (iter = connections; iter; iter = g_slist_next (iter)) {
if (NM_ACTIVE_CONNECTION (iter->data) != best)
set_active_func (NM_ACTIVE_CONNECTION (iter->data), FALSE);
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
if (ac != best)
set_active_func (ac, FALSE);
}
/* Mark new default active connection */
@ -850,19 +851,19 @@ get_best_ip_config (NMPolicy *self,
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
NMDevice *device;
gpointer conf;
const GSList *iter;
const CList *tmp_list;
NMActiveConnection *ac;
nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
for (iter = nm_manager_get_active_connections (priv->manager); iter; iter = iter->next) {
NMActiveConnection *active = NM_ACTIVE_CONNECTION (iter->data);
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
NMVpnConnection *candidate;
NMVpnConnectionState vpn_state;
if (!NM_IS_VPN_CONNECTION (active))
if (!NM_IS_VPN_CONNECTION (ac))
continue;
candidate = NM_VPN_CONNECTION (active);
candidate = NM_VPN_CONNECTION (ac);
vpn_state = nm_vpn_connection_get_vpn_state (candidate);
if (vpn_state != NM_VPN_CONNECTION_STATE_ACTIVATED)
@ -887,7 +888,7 @@ get_best_ip_config (NMPolicy *self,
* best metric. */
NM_SET_OUT (out_device, NULL);
NM_SET_OUT (out_vpn, candidate);
NM_SET_OUT (out_ac, active);
NM_SET_OUT (out_ac, ac);
NM_SET_OUT (out_ip_iface, nm_vpn_connection_get_ip_iface (candidate, TRUE));
return conf;
}
@ -926,6 +927,8 @@ update_ip4_routing (NMPolicy *self, gboolean force_update)
NMVpnConnection *vpn = NULL;
NMActiveConnection *best_ac = NULL;
const char *ip_iface = NULL;
const CList *tmp_list;
NMActiveConnection *ac;
/* Note that we might have an IPv4 VPN tunneled over an IPv6-only device,
* so we can get (vpn != NULL && best == NULL).
@ -945,16 +948,11 @@ update_ip4_routing (NMPolicy *self, gboolean force_update)
return;
if (best) {
const GSList *connections, *iter;
connections = nm_manager_get_active_connections (priv->manager);
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMActiveConnection *active = iter->data;
if ( NM_IS_VPN_CONNECTION (active)
&& nm_vpn_connection_get_ip4_config (NM_VPN_CONNECTION (active))
&& !nm_active_connection_get_device (active))
nm_active_connection_set_device (active, best);
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
if ( NM_IS_VPN_CONNECTION (ac)
&& nm_vpn_connection_get_ip4_config (NM_VPN_CONNECTION (ac))
&& !nm_active_connection_get_device (ac))
nm_active_connection_set_device (ac, best);
}
}
@ -977,12 +975,12 @@ static void
update_ip6_dns_delegation (NMPolicy *self)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
const GSList *connections, *iter;
connections = nm_manager_get_active_connections (priv->manager);
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMDevice *device = nm_active_connection_get_device (iter->data);
NMDevice *device;
NMActiveConnection *ac;
const CList *tmp_list;
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
device = nm_active_connection_get_device (ac);
if (device && nm_device_needs_ip6_subnet (device))
nm_device_copy_ip6_dns_config (device, priv->default_device6);
}
@ -992,13 +990,13 @@ static void
update_ip6_prefix_delegation (NMPolicy *self)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
const GSList *connections, *iter;
NMDevice *device;
NMActiveConnection *ac;
const CList *tmp_list;
/* There's new default IPv6 connection, try to get a prefix for everyone. */
connections = nm_manager_get_active_connections (priv->manager);
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMDevice *device = nm_active_connection_get_device (iter->data);
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
device = nm_active_connection_get_device (ac);
if (device && nm_device_needs_ip6_subnet (device))
ip6_subnet_from_device (self, priv->default_device6, device);
}
@ -1012,6 +1010,8 @@ update_ip6_routing (NMPolicy *self, gboolean force_update)
NMVpnConnection *vpn = NULL;
NMActiveConnection *best_ac = NULL;
const char *ip_iface = NULL;
NMActiveConnection *ac;
const CList *tmp_list;
/* Note that we might have an IPv6 VPN tunneled over an IPv4-only device,
* so we can get (vpn != NULL && best == NULL).
@ -1031,16 +1031,11 @@ update_ip6_routing (NMPolicy *self, gboolean force_update)
return;
if (best) {
const GSList *connections, *iter;
connections = nm_manager_get_active_connections (priv->manager);
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMActiveConnection *active = iter->data;
if ( NM_IS_VPN_CONNECTION (active)
&& nm_vpn_connection_get_ip6_config (NM_VPN_CONNECTION (active))
&& !nm_active_connection_get_device (active))
nm_active_connection_set_device (active, best);
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
if ( NM_IS_VPN_CONNECTION (ac)
&& nm_vpn_connection_get_ip6_config (NM_VPN_CONNECTION (ac))
&& !nm_active_connection_get_device (ac))
nm_active_connection_set_device (ac, best);
}
}
@ -1472,7 +1467,8 @@ schedule_activate_check (NMPolicy *self, NMDevice *device)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
ActivateData *data;
const GSList *active_connections, *iter;
NMActiveConnection *ac;
const CList *tmp_list;
if (nm_manager_get_state (priv->manager) == NM_STATE_ASLEEP)
return;
@ -1483,9 +1479,8 @@ schedule_activate_check (NMPolicy *self, NMDevice *device)
if (find_pending_activation (self, device))
return;
active_connections = nm_manager_get_active_connections (priv->manager);
for (iter = active_connections; iter; iter = iter->next) {
if (nm_active_connection_get_device (NM_ACTIVE_CONNECTION (iter->data)) == device)
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
if (nm_active_connection_get_device (ac) == device)
return;
}
@ -2302,19 +2297,21 @@ connection_updated (NMSettings *settings,
}
static void
_deactivate_if_active (NMManager *manager, NMSettingsConnection *connection)
_deactivate_if_active (NMPolicy *self, NMSettingsConnection *connection)
{
const GSList *active, *iter;
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
NMActiveConnection *ac;
const CList *tmp_list;
GError *error = NULL;
active = nm_manager_get_active_connections (manager);
for (iter = active; iter; iter = g_slist_next (iter)) {
NMActiveConnection *ac = iter->data;
nm_assert (NM_IS_SETTINGS_CONNECTION (connection));
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
NMActiveConnectionState state = nm_active_connection_get_state (ac);
GError *error = NULL;
if (nm_active_connection_get_settings_connection (ac) == connection &&
(state <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) {
if (!nm_manager_deactivate_connection (manager,
if ( nm_active_connection_get_settings_connection (ac) == connection
&& (state <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) {
if (!nm_manager_deactivate_connection (priv->manager,
ac,
NM_DEVICE_STATE_REASON_CONNECTION_REMOVED,
&error)) {
@ -2333,9 +2330,7 @@ connection_removed (NMSettings *settings,
NMSettingsConnection *connection,
gpointer user_data)
{
NMPolicyPrivate *priv = user_data;
_deactivate_if_active (priv->manager, connection);
_deactivate_if_active (user_data, connection);
}
static void
@ -2349,7 +2344,7 @@ connection_visibility_changed (NMSettings *settings,
if (nm_settings_connection_is_visible (connection))
schedule_activate_all (self);
else
_deactivate_if_active (priv->manager, connection);
_deactivate_if_active (self, connection);
}
static void
@ -2551,7 +2546,6 @@ dispose (GObject *object)
{
NMPolicy *self = NM_POLICY (object);
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
const GSList *connections;
GHashTableIter h_iter;
NMDevice *device;
ActivateData *data, *data_safe;
@ -2592,8 +2586,7 @@ dispose (GObject *object)
* will have called active_connection_removed() and thus we don't need
* to clean anything up. Assert that this is TRUE.
*/
connections = nm_manager_get_active_connections (priv->manager);
g_assert (connections == NULL);
nm_assert (c_list_is_empty (nm_manager_get_active_connections (priv->manager)));
nm_clear_g_source (&priv->reset_retries_id);
nm_clear_g_source (&priv->schedule_activate_all_id);