summaryrefslogtreecommitdiff
path: root/src/nm-policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm-policy.c')
-rw-r--r--src/nm-policy.c338
1 files changed, 166 insertions, 172 deletions
diff --git a/src/nm-policy.c b/src/nm-policy.c
index fcada5454..aed2f897b 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -36,9 +36,6 @@
#include "nm-device-wifi.h"
#include "nm-device-ethernet.h"
#include "nm-device-modem.h"
-#if WITH_WIMAX
-#include "nm-device-wimax.h"
-#endif
#include "nm-dbus-manager.h"
#include "nm-setting-ip4-config.h"
#include "nm-setting-connection.h"
@@ -51,16 +48,13 @@ struct NMPolicy {
NMManager *manager;
guint update_state_id;
GSList *pending_activation_checks;
- GSList *manager_ids;
- GSList *settings_ids;
- GSList *dev_ids;
+ GSList *signal_ids;
+ GSList *dev_signal_ids;
NMVPNManager *vpn_manager;
gulong vpn_activated_id;
gulong vpn_deactivated_id;
- NMSettings *settings;
-
NMDevice *default_device4;
NMDevice *default_device6;
@@ -70,8 +64,20 @@ struct NMPolicy {
char *cur_hostname; /* hostname we want to assign */
};
-#define RETRIES_TAG "autoconnect-retries"
-#define RETRIES_DEFAULT 4
+#define INVALID_TAG "invalid"
+
+static const char *
+get_connection_id (NMConnection *connection)
+{
+ NMSettingConnection *s_con;
+
+ g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ g_return_val_if_fail (s_con != NULL, NULL);
+
+ return nm_setting_connection_get_id (s_con);
+}
static NMDevice *
get_best_ip4_device (NMManager *manager, NMActRequest **out_req)
@@ -281,7 +287,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6)
/* Hostname precedence order:
*
- * 1) a configured hostname (from settings)
+ * 1) a configured hostname (from system-settings)
* 2) automatic hostname from the default device's config (DHCP, VPN, etc)
* 3) the original hostname when NM started
* 4) reverse-DNS of the best device's IPv4 address
@@ -470,6 +476,7 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update)
dns_type = NM_DNS_IP_CONFIG_TYPE_VPN;
}
+ g_object_unref (candidate);
}
g_slist_free (vpns);
@@ -594,6 +601,7 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update)
dns_type = NM_DNS_IP_CONFIG_TYPE_VPN;
}
+ g_object_unref (candidate);
}
g_slist_free (vpns);
#endif
@@ -666,20 +674,6 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update)
update_system_hostname (policy, policy->default_device4, policy->default_device6);
}
-static void
-set_connection_auto_retries (NMConnection *connection, guint retries)
-{
- /* add +1 so that the tag still exists if the # retries is 0 */
- g_object_set_data (G_OBJECT (connection), RETRIES_TAG, GUINT_TO_POINTER (retries + 1));
-}
-
-static guint32
-get_connection_auto_retries (NMConnection *connection)
-{
- /* subtract 1 to handle the +1 from set_connection_auto_retries() */
- return GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), RETRIES_TAG)) - 1;
-}
-
typedef struct {
NMPolicy *policy;
NMDevice *device;
@@ -705,21 +699,23 @@ auto_activate_device (gpointer user_data)
if (nm_device_get_act_request (data->device))
goto out;
- iter = connections = nm_settings_get_connections (policy->settings);
+ /* System connections first, then user connections */
+ connections = nm_manager_get_connections (policy->manager, NM_CONNECTION_SCOPE_SYSTEM);
+ if (nm_manager_auto_user_connections_allowed (policy->manager))
+ connections = g_slist_concat (connections, nm_manager_get_connections (policy->manager, NM_CONNECTION_SCOPE_USER));
- /* Remove connections that shouldn't be auto-activated */
+ /* Remove connections that are in the invalid list. */
+ iter = connections;
while (iter) {
- NMConnection *candidate = NM_CONNECTION (iter->data);
-
- /* Grab next item before we possibly delete the current item */
- iter = g_slist_next (iter);
+ NMConnection *iter_connection = NM_CONNECTION (iter->data);
+ GSList *next = g_slist_next (iter);
- /* Ignore connections that were tried too many times or are not visible
- * to any logged-in users.
- */
- if ( get_connection_auto_retries (candidate) == 0
- || nm_settings_connection_is_visible (NM_SETTINGS_CONNECTION (candidate)) == FALSE)
- connections = g_slist_remove (connections, candidate);
+ if (g_object_get_data (G_OBJECT (iter_connection), INVALID_TAG)) {
+ connections = g_slist_remove_link (connections, iter);
+ g_object_unref (iter_connection);
+ g_slist_free (iter);
+ }
+ iter = next;
}
best_connection = nm_device_get_best_auto_connection (data->device, connections, &specific_object);
@@ -730,14 +726,20 @@ auto_activate_device (gpointer user_data)
best_connection,
specific_object,
nm_device_get_path (data->device),
- NULL,
+ FALSE,
&error)) {
+ NMSettingConnection *s_con;
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (best_connection, NM_TYPE_SETTING_CONNECTION));
+ g_assert (s_con);
+
nm_log_info (LOGD_DEVICE, "Connection '%s' auto-activation failed: (%d) %s",
- nm_connection_get_id (best_connection), error->code, error->message);
+ nm_setting_connection_get_id (s_con), error->code, error->message);
g_error_free (error);
}
}
+ g_slist_foreach (connections, (GFunc) g_object_unref, NULL);
g_slist_free (connections);
out:
@@ -783,18 +785,18 @@ hostname_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
static void
sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
{
- NMPolicy *policy = user_data;
gboolean sleeping = FALSE, enabled = FALSE;
GSList *connections, *iter;
g_object_get (G_OBJECT (manager), NM_MANAGER_SLEEPING, &sleeping, NULL);
g_object_get (G_OBJECT (manager), NM_MANAGER_NETWORKING_ENABLED, &enabled, NULL);
- /* Reset retries on all connections so they'll checked on wakeup */
+ /* Clear the invalid flag on all connections so they'll get retried on wakeup */
if (sleeping || !enabled) {
- connections = nm_settings_get_connections (policy->settings);
+ connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM);
+ connections = g_slist_concat (connections, nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_USER));
for (iter = connections; iter; iter = g_slist_next (iter))
- set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT);
+ g_object_set_data (G_OBJECT (iter->data), INVALID_TAG, NULL);
g_slist_free (connections);
}
}
@@ -859,32 +861,16 @@ device_state_changed (NMDevice *device,
* it doesn't get automatically chosen over and over and over again.
*/
if (connection && IS_ACTIVATING_STATE (old_state)) {
- guint32 tries = get_connection_auto_retries (connection);
-
- if (reason == NM_DEVICE_STATE_REASON_NO_SECRETS) {
- /* If the connection couldn't get the secrets it needed (ex because
- * the user canceled, or no secrets exist), there's no point in
- * automatically retrying because it's just going to fail anyway.
- */
- set_connection_auto_retries (connection, 0);
- } else if (tries > 0) {
- /* Otherwise if it's a random failure, just decrease the number
- * of automatic retries so that the connection gets tried again
- * if it still has a retry count.
- */
- set_connection_auto_retries (connection, tries - 1);
- }
-
- if (get_connection_auto_retries (connection) == 0)
- nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", nm_connection_get_id (connection));
+ g_object_set_data (G_OBJECT (connection), INVALID_TAG, GUINT_TO_POINTER (TRUE));
+ nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", get_connection_id (connection));
nm_connection_clear_secrets (connection);
}
schedule_activate_check (policy, device, 3);
break;
case NM_DEVICE_STATE_ACTIVATED:
if (connection) {
- /* Reset auto retries back to default since connection was successful */
- set_connection_auto_retries (connection, RETRIES_DEFAULT);
+ /* Clear the invalid tag on the connection */
+ g_object_set_data (G_OBJECT (connection), INVALID_TAG, NULL);
/* And clear secrets so they will always be requested from the
* settings service when the next connection is made.
@@ -919,48 +905,56 @@ wireless_networks_changed (NMDeviceWifi *device, NMAccessPoint *ap, gpointer use
schedule_activate_check ((NMPolicy *) user_data, NM_DEVICE (device), 0);
}
-#if WITH_WIMAX
-static void
-nsps_changed (NMDeviceWimax *device, NMWimaxNsp *nsp, gpointer user_data)
-{
- schedule_activate_check ((NMPolicy *) user_data, NM_DEVICE (device), 0);
-}
-#endif
-
typedef struct {
gulong id;
NMDevice *device;
-} DeviceSignalId;
+} DeviceSignalID;
-static void
-_connect_device_signal (NMPolicy *policy, NMDevice *device, const char *name, gpointer callback)
+static GSList *
+add_device_signal_id (GSList *list, gulong id, NMDevice *device)
{
- DeviceSignalId *data;
+ DeviceSignalID *data;
- data = g_slice_new0 (DeviceSignalId);
- g_assert (data);
- data->id = g_signal_connect (device, name, callback, policy);
+ data = g_malloc0 (sizeof (DeviceSignalID));
+ if (!data)
+ return list;
+
+ data->id = id;
data->device = device;
- policy->dev_ids = g_slist_prepend (policy->dev_ids, data);
+ return g_slist_append (list, data);
}
static void
device_added (NMManager *manager, NMDevice *device, gpointer user_data)
{
NMPolicy *policy = (NMPolicy *) user_data;
+ gulong id;
+
+ id = g_signal_connect (device, "state-changed",
+ G_CALLBACK (device_state_changed),
+ policy);
+ policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
- _connect_device_signal (policy, device, "state-changed", device_state_changed);
- _connect_device_signal (policy, device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG, device_ip_config_changed);
- _connect_device_signal (policy, device, "notify::" NM_DEVICE_INTERFACE_IP6_CONFIG, device_ip_config_changed);
+ id = g_signal_connect (device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG,
+ G_CALLBACK (device_ip_config_changed),
+ policy);
+ policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
+
+ id = g_signal_connect (device, "notify::" NM_DEVICE_INTERFACE_IP6_CONFIG,
+ G_CALLBACK (device_ip_config_changed),
+ policy);
+ policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
if (NM_IS_DEVICE_WIFI (device)) {
- _connect_device_signal (policy, device, "access-point-added", wireless_networks_changed);
- _connect_device_signal (policy, device, "access-point-removed", wireless_networks_changed);
-#if WITH_WIMAX
- } else if (NM_IS_DEVICE_WIMAX (device)) {
- _connect_device_signal (policy, device, "nsp-added", nsps_changed);
- _connect_device_signal (policy, device, "nsp-removed", nsps_changed);
-#endif
+ id = g_signal_connect (device, "access-point-added",
+ G_CALLBACK (wireless_networks_changed),
+ policy);
+ policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
+
+ id = g_signal_connect (device, "access-point-removed",
+ G_CALLBACK (wireless_networks_changed),
+ policy);
+ policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
}
}
@@ -986,15 +980,15 @@ device_removed (NMManager *manager, NMDevice *device, gpointer user_data)
}
/* Clear any signal handlers for this device */
- iter = policy->dev_ids;
+ iter = policy->dev_signal_ids;
while (iter) {
- DeviceSignalId *data = iter->data;
+ DeviceSignalID *data = (DeviceSignalID *) iter->data;
GSList *next = g_slist_next (iter);
if (data->device == device) {
g_signal_handler_disconnect (data->device, data->id);
- g_slice_free (DeviceSignalId, data);
- policy->dev_ids = g_slist_delete_link (policy->dev_ids, iter);
+ g_free (data);
+ policy->dev_signal_ids = g_slist_delete_link (policy->dev_signal_ids, iter);
}
iter = next;
}
@@ -1013,38 +1007,48 @@ schedule_activate_all (NMPolicy *policy)
}
static void
-connection_added (NMSettings *settings,
- NMConnection *connection,
- gpointer user_data)
+connections_added (NMManager *manager,
+ NMConnectionScope scope,
+ gpointer user_data)
{
- set_connection_auto_retries (connection, RETRIES_DEFAULT);
schedule_activate_all ((NMPolicy *) user_data);
}
static void
-connections_loaded (NMSettings *settings,
- gpointer user_data)
+connection_added (NMManager *manager,
+ NMConnection *connection,
+ NMConnectionScope scope,
+ gpointer user_data)
{
schedule_activate_all ((NMPolicy *) user_data);
}
static void
-connection_updated (NMSettings *settings,
+connection_updated (NMManager *manager,
NMConnection *connection,
+ NMConnectionScope scope,
gpointer user_data)
{
- /* Reset auto retries back to default since connection was updated */
- set_connection_auto_retries (connection, RETRIES_DEFAULT);
+ /* Clear the invalid tag on the connection if it got updated. */
+ g_object_set_data (G_OBJECT (connection), INVALID_TAG, NULL);
schedule_activate_all ((NMPolicy *) user_data);
}
static void
-_deactivate_if_active (NMManager *manager, NMConnection *connection)
+connection_removed (NMManager *manager,
+ NMConnection *connection,
+ NMConnectionScope scope,
+ gpointer user_data)
{
+ NMSettingConnection *s_con;
GPtrArray *list;
int i;
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ if (!s_con)
+ return;
+
list = nm_manager_get_active_connections_by_connection (manager, connection);
if (!list)
return;
@@ -1055,7 +1059,7 @@ _deactivate_if_active (NMManager *manager, NMConnection *connection)
if (!nm_manager_deactivate_connection (manager, path, NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, &error)) {
nm_log_warn (LOGD_DEVICE, "Connection '%s' disappeared, but error deactivating it: (%d) %s",
- nm_connection_get_id (connection), error->code, error->message);
+ nm_setting_connection_get_id (s_con), error->code, error->message);
g_error_free (error);
}
g_free (path);
@@ -1064,50 +1068,13 @@ _deactivate_if_active (NMManager *manager, NMConnection *connection)
}
static void
-connection_removed (NMSettings *settings,
- NMConnection *connection,
- gpointer user_data)
-{
- NMPolicy *policy = user_data;
-
- _deactivate_if_active (policy->manager, connection);
-}
-
-static void
-connection_visibility_changed (NMSettings *settings,
- NMSettingsConnection *connection,
- gpointer user_data)
-{
- NMPolicy *policy = user_data;
-
- if (nm_settings_connection_is_visible (connection))
- schedule_activate_all (policy);
- else
- _deactivate_if_active (policy->manager, NM_CONNECTION (connection));
-}
-
-static void
-_connect_manager_signal (NMPolicy *policy, const char *name, gpointer callback)
-{
- guint id;
-
- id = g_signal_connect (policy->manager, name, callback, policy);
- policy->manager_ids = g_slist_prepend (policy->manager_ids, GUINT_TO_POINTER (id));
-}
-
-static void
-_connect_settings_signal (NMPolicy *policy, const char *name, gpointer callback)
+manager_user_permissions_changed (NMManager *manager, NMPolicy *policy)
{
- guint id;
-
- id = g_signal_connect (policy->settings, name, callback, policy);
- policy->settings_ids = g_slist_prepend (policy->settings_ids, GUINT_TO_POINTER (id));
+ schedule_activate_all (policy);
}
NMPolicy *
-nm_policy_new (NMManager *manager,
- NMVPNManager *vpn_manager,
- NMSettings *settings)
+nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager)
{
NMPolicy *policy;
static gboolean initialized = FALSE;
@@ -1119,7 +1086,6 @@ nm_policy_new (NMManager *manager,
policy = g_malloc0 (sizeof (NMPolicy));
policy->manager = g_object_ref (manager);
- policy->settings = g_object_ref (settings);
policy->update_state_id = 0;
/* Grab hostname on startup and use that if nothing provides one */
@@ -1138,21 +1104,54 @@ nm_policy_new (NMManager *manager,
G_CALLBACK (vpn_connection_deactivated), policy);
policy->vpn_deactivated_id = id;
- _connect_manager_signal (policy, "state-changed", global_state_changed);
- _connect_manager_signal (policy, "notify::" NM_MANAGER_HOSTNAME, hostname_changed);
- _connect_manager_signal (policy, "notify::" NM_MANAGER_SLEEPING, sleeping_changed);
- _connect_manager_signal (policy, "notify::" NM_MANAGER_NETWORKING_ENABLED, sleeping_changed);
- _connect_manager_signal (policy, "device-added", device_added);
- _connect_manager_signal (policy, "device-removed", device_removed);
-
- _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED, connections_loaded);
- _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, connection_added);
- _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, connection_updated);
- _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, connection_removed);
- _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
- connection_visibility_changed);
-
- initialized = TRUE;
+ id = g_signal_connect (manager, "state-changed",
+ G_CALLBACK (global_state_changed), policy);
+ policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
+
+ id = g_signal_connect (manager, "notify::" NM_MANAGER_HOSTNAME,
+ G_CALLBACK (hostname_changed), policy);
+ policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
+
+ id = g_signal_connect (manager, "notify::" NM_MANAGER_SLEEPING,
+ G_CALLBACK (sleeping_changed), policy);
+ policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
+
+ id = g_signal_connect (manager, "notify::" NM_MANAGER_NETWORKING_ENABLED,
+ G_CALLBACK (sleeping_changed), policy);
+ policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
+
+ id = g_signal_connect (manager, "device-added",
+ G_CALLBACK (device_added), policy);
+ policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
+
+ id = g_signal_connect (manager, "device-removed",
+ G_CALLBACK (device_removed), policy);
+ policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
+
+ /* Large batch of connections added, manager doesn't want us to
+ * process each one individually.
+ */
+ id = g_signal_connect (manager, "connections-added",
+ G_CALLBACK (connections_added), policy);
+ policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
+
+ /* Single connection added */
+ id = g_signal_connect (manager, "connection-added",
+ G_CALLBACK (connection_added), policy);
+ policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
+
+ id = g_signal_connect (manager, "connection-updated",
+ G_CALLBACK (connection_updated), policy);
+ policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
+
+ id = g_signal_connect (manager, "connection-removed",
+ G_CALLBACK (connection_removed), policy);
+ policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
+
+ id = g_signal_connect (manager, "user-permissions-changed",
+ G_CALLBACK (manager_user_permissions_changed), policy);
+ policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
+
return policy;
}
@@ -1184,26 +1183,21 @@ nm_policy_destroy (NMPolicy *policy)
g_signal_handler_disconnect (policy->vpn_manager, policy->vpn_deactivated_id);
g_object_unref (policy->vpn_manager);
- for (iter = policy->manager_ids; iter; iter = g_slist_next (iter))
- g_signal_handler_disconnect (policy->manager, GPOINTER_TO_UINT (iter->data));
- g_slist_free (policy->manager_ids);
+ for (iter = policy->signal_ids; iter; iter = g_slist_next (iter))
+ g_signal_handler_disconnect (policy->manager, (gulong) iter->data);
+ g_slist_free (policy->signal_ids);
- for (iter = policy->settings_ids; iter; iter = g_slist_next (iter))
- g_signal_handler_disconnect (policy->settings, GPOINTER_TO_UINT (iter->data));
- g_slist_free (policy->settings_ids);
-
- for (iter = policy->dev_ids; iter; iter = g_slist_next (iter)) {
- DeviceSignalId *data = iter->data;
+ for (iter = policy->dev_signal_ids; iter; iter = g_slist_next (iter)) {
+ DeviceSignalID *data = (DeviceSignalID *) iter->data;
g_signal_handler_disconnect (data->device, data->id);
- g_slice_free (DeviceSignalId, data);
+ g_free (data);
}
- g_slist_free (policy->dev_ids);
+ g_slist_free (policy->dev_signal_ids);
g_free (policy->orig_hostname);
g_free (policy->cur_hostname);
- g_object_unref (policy->settings);
g_object_unref (policy->manager);
g_free (policy);
}