diff options
| author | Michael Biebl <biebl@debian.org> | 2018-09-23 10:10:27 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2018-09-23 10:10:27 +0200 |
| commit | e126f3e804c35480c4f075777430419d6ece23da (patch) | |
| tree | 5d5821ebcda8cd6ac34d2483bb3354910e508930 /src/nm-manager.c | |
| parent | c240974325c552cad177c457d6ff04e381fd77a3 (diff) | |
New upstream version 1.12.4 upstream/1.12.4
Diffstat (limited to 'src/nm-manager.c')
| -rw-r--r-- | src/nm-manager.c | 857 |
1 files changed, 329 insertions, 528 deletions
diff --git a/src/nm-manager.c b/src/nm-manager.c index f8be6d37..ad906169 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -310,8 +310,7 @@ static void _emit_device_added_removed (NMManager *self, static NMActiveConnection *_new_active_connection (NMManager *self, gboolean is_vpn, - NMSettingsConnection *sett_conn, - NMConnection *incompl_conn, + NMConnection *connection, NMConnection *applied, const char *specific_object, NMDevice *device, @@ -320,7 +319,7 @@ static NMActiveConnection *_new_active_connection (NMManager *self, NMActivationReason activation_reason, GError **error); -static void policy_activating_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data); +static void policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data); static gboolean find_master (NMManager *self, NMConnection *connection, @@ -332,8 +331,7 @@ static gboolean find_master (NMManager *self, static void nm_manager_update_state (NMManager *manager); -static void connection_changed (NMManager *self, - NMSettingsConnection *sett_conn); +static void connection_changed (NMManager *self, NMConnection *connection); static void device_sleep_cb (NMDevice *device, GParamSpec *pspec, NMManager *self); @@ -355,7 +353,7 @@ static void active_connection_parent_active (NMActiveConnection *active, NMManager *self); static NMActiveConnection *active_connection_find (NMManager *self, - NMSettingsConnection *sett_conn, + NMSettingsConnection *settings_connection, const char *uuid, NMActiveConnectionState max_state, GPtrArray **out_all_matching); @@ -949,7 +947,7 @@ nm_manager_get_active_connections (NMManager *manager) static NMActiveConnection * active_connection_find (NMManager *self, - NMSettingsConnection *sett_conn, + NMSettingsConnection *settings_connection, const char *uuid, NMActiveConnectionState max_state /* candidates in state @max_state will be found */, GPtrArray **out_all_matching) @@ -959,18 +957,16 @@ active_connection_find (NMManager *self, NMActiveConnection *best_ac = NULL; GPtrArray *all = NULL; - nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn)); + nm_assert (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection)); nm_assert (!out_all_matching || !*out_all_matching); c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) { - NMSettingsConnection *ac_conn; + NMSettingsConnection *con; - ac_conn = nm_active_connection_get_settings_connection (ac); - if ( sett_conn - && sett_conn != ac_conn) + con = nm_active_connection_get_settings_connection (ac); + if (settings_connection && con != settings_connection) continue; - if ( uuid - && !nm_streq0 (uuid, nm_settings_connection_get_uuid (ac_conn))) + if (uuid && !nm_streq0 (uuid, nm_connection_get_uuid (NM_CONNECTION (con)))) continue; if (nm_active_connection_get_state (ac) > max_state) continue; @@ -1009,73 +1005,47 @@ active_connection_find (NMManager *self, static NMActiveConnection * active_connection_find_by_connection (NMManager *self, - NMSettingsConnection *sett_conn, NMConnection *connection, NMActiveConnectionState max_state, GPtrArray **out_all_matching) { + gboolean is_settings_connection; + nm_assert (NM_IS_MANAGER (self)); - nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn)); - nm_assert (!connection || NM_IS_CONNECTION (connection)); - nm_assert (sett_conn || connection); - nm_assert (!connection || !sett_conn || connection == nm_settings_connection_get_connection (sett_conn)); + nm_assert (NM_IS_CONNECTION (connection)); + is_settings_connection = NM_IS_SETTINGS_CONNECTION (connection); /* Depending on whether connection is a settings connection, * either lookup by object-identity of @connection, or compare the UUID */ return active_connection_find (self, - sett_conn, - sett_conn ? NULL : nm_connection_get_uuid (connection), + is_settings_connection ? NM_SETTINGS_CONNECTION (connection) : NULL, + is_settings_connection ? NULL : nm_connection_get_uuid (connection), max_state, out_all_matching); } -typedef struct { - NMManager *self; - gboolean for_auto_activation; -} GetActivatableConnectionsFilterData; - static gboolean _get_activatable_connections_filter (NMSettings *settings, - NMSettingsConnection *sett_conn, + NMSettingsConnection *connection, gpointer user_data) { - const GetActivatableConnectionsFilterData *d = user_data; - NMConnectionMultiConnect multi_connect; - - if (NM_FLAGS_HAS (nm_settings_connection_get_flags (sett_conn), + if (NM_FLAGS_HAS (nm_settings_connection_get_flags (connection), NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)) return FALSE; - multi_connect = _nm_connection_get_multi_connect (nm_settings_connection_get_connection (sett_conn)); - if ( multi_connect == NM_CONNECTION_MULTI_CONNECT_MULTIPLE - || ( multi_connect == NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE - && !d->for_auto_activation)) - return TRUE; - /* the connection is activatable, if it has no active-connections that are in state * activated, activating, or waiting to be activated. */ - return !active_connection_find (d->self, - sett_conn, - NULL, - NM_ACTIVE_CONNECTION_STATE_ACTIVATED, - NULL); + return !active_connection_find (user_data, connection, NULL, NM_ACTIVE_CONNECTION_STATE_ACTIVATED, NULL); } NMSettingsConnection ** -nm_manager_get_activatable_connections (NMManager *manager, - gboolean for_auto_activation, - gboolean sort, - guint *out_len) +nm_manager_get_activatable_connections (NMManager *manager, guint *out_len, gboolean sort) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - const GetActivatableConnectionsFilterData d = { - .self = manager, - .for_auto_activation = for_auto_activation, - }; return nm_settings_get_connections_clone (priv->settings, out_len, _get_activatable_connections_filter, - (gpointer) &d, + manager, sort ? nm_settings_connection_cmp_autoconnect_priority_p_with_data : NULL, NULL); } @@ -1086,8 +1056,8 @@ active_connection_get_by_path (NMManager *self, const char *path) NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMActiveConnection *ac; - ac = nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), - path); + ac = (NMActiveConnection *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), + path); if ( !ac || !NM_IS_ACTIVE_CONNECTION (ac) || c_list_is_empty (&ac->active_connections_lst)) @@ -1223,8 +1193,8 @@ nm_manager_get_device_by_path (NMManager *self, const char *path) g_return_val_if_fail (path, NULL); - device = nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), - path); + device = (NMDevice *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), + path); if ( !device || !NM_IS_DEVICE (device) || c_list_is_empty (&device->devices_lst)) @@ -1274,7 +1244,7 @@ find_device_by_permanent_hw_addr (NMManager *self, const char *hwaddr) } static NMDevice * -find_device_by_ip_iface (NMManager *self, const char *iface) +find_device_by_ip_iface (NMManager *self, const gchar *iface) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMDevice *device; @@ -1320,7 +1290,7 @@ find_device_by_iface (NMManager *self, if (strcmp (nm_device_get_iface (candidate), iface)) continue; - if (connection && !nm_device_check_connection_compatible (candidate, connection, NULL)) + if (connection && !nm_device_check_connection_compatible (candidate, connection)) continue; if (slave) { if (!nm_device_is_master (candidate)) @@ -1489,23 +1459,20 @@ manager_device_state_changed (NMDevice *device, && new_state > NM_DEVICE_STATE_UNMANAGED) retry_connections_for_parent_device (self, device); - if (NM_IN_SET (new_state, - NM_DEVICE_STATE_UNMANAGED, - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_PREPARE, - NM_DEVICE_STATE_FAILED)) + switch (new_state) { + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + case NM_DEVICE_STATE_DISCONNECTED: + case NM_DEVICE_STATE_PREPARE: + case NM_DEVICE_STATE_FAILED: _notify (self, PROP_ACTIVE_CONNECTIONS); + break; + default: + break; + } - if (NM_IN_SET (new_state, - NM_DEVICE_STATE_UNMANAGED, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_ACTIVATED)) - nm_manager_write_device_state (self, device); - - if (NM_IN_SET (new_state, - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_DISCONNECTED)) + if ( new_state == NM_DEVICE_STATE_UNAVAILABLE + || new_state == NM_DEVICE_STATE_DISCONNECTED) nm_settings_device_added (priv->settings, device); } @@ -1740,9 +1707,7 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection, NM return candidate; if ( !first_compatible - && nm_device_check_connection_compatible (candidate, - nm_settings_connection_get_connection (parent_connection), - NULL)) + && nm_device_check_connection_compatible (candidate, NM_CONNECTION (parent_connection))) first_compatible = candidate; } @@ -1836,13 +1801,13 @@ const char * nm_manager_iface_for_uuid (NMManager *self, const char *uuid) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection; - sett_conn = nm_settings_get_connection_by_uuid (priv->settings, uuid); - if (!sett_conn) + connection = nm_settings_get_connection_by_uuid (priv->settings, uuid); + if (!connection) return NULL; - return nm_connection_get_interface_name (nm_settings_connection_get_connection (sett_conn)); + return nm_connection_get_interface_name (NM_CONNECTION (connection)); } NMDevice * @@ -1912,7 +1877,7 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) /* See if there's a device that is already compatible with this connection */ c_list_for_each_entry (dev_candidate, &priv->devices_lst_head, devices_lst) { - if (nm_device_check_connection_compatible (dev_candidate, connection, NULL)) { + if (nm_device_check_connection_compatible (dev_candidate, connection)) { if (nm_device_is_real (dev_candidate)) { _LOG3D (LOGD_DEVICE, connection, "already created virtual interface name %s", iface); @@ -1965,10 +1930,10 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) NULL, NULL, nm_settings_connection_cmp_autoconnect_priority_p_with_data, NULL); for (i = 0; connections[i]; i++) { - NMConnection *candidate = nm_settings_connection_get_connection (connections[i]); + NMConnection *candidate = NM_CONNECTION (connections[i]); NMSettingConnection *s_con; - if (!nm_device_check_connection_compatible (device, candidate, NULL)) + if (!nm_device_check_connection_compatible (device, candidate)) continue; s_con = nm_connection_get_setting_connection (candidate); @@ -2011,19 +1976,18 @@ retry_connections_for_parent_device (NMManager *self, NMDevice *device) NULL, NULL, nm_settings_connection_cmp_autoconnect_priority_p_with_data, NULL); for (i = 0; connections[i]; i++) { - NMSettingsConnection *sett_conn = connections[i]; - NMConnection *connection = nm_settings_connection_get_connection (sett_conn); + NMConnection *candidate = NM_CONNECTION (connections[i]); gs_free_error GError *error = NULL; gs_free char *ifname = NULL; NMDevice *parent; - parent = find_parent_device_for_connection (self, connection, NULL); + parent = find_parent_device_for_connection (self, candidate, NULL); if (parent == device) { /* Only try to activate devices that don't already exist */ - ifname = nm_manager_get_connection_iface (self, connection, &parent, &error); + ifname = nm_manager_get_connection_iface (self, candidate, &parent, &error); if (ifname) { if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, ifname)) - connection_changed (self, sett_conn); + connection_changed (self, candidate); } } } @@ -2031,10 +1995,9 @@ retry_connections_for_parent_device (NMManager *self, NMDevice *device) static void connection_changed (NMManager *self, - NMSettingsConnection *sett_conn) + NMConnection *connection) { NMDevice *device; - NMConnection *connection = nm_settings_connection_get_connection (sett_conn); if (!nm_connection_is_virtual (connection)) return; @@ -2051,20 +2014,20 @@ connection_changed (NMManager *self, static void connection_added_cb (NMSettings *settings, - NMSettingsConnection *sett_conn, + NMConnection *connection, NMManager *self) { - connection_changed (self, sett_conn); + connection_changed (self, connection); } static void connection_updated_cb (NMSettings *settings, - NMSettingsConnection *sett_conn, + NMConnection *connection, gboolean by_user, NMManager *self) { if (by_user) - connection_changed (self, sett_conn); + connection_changed (self, connection); } /*****************************************************************************/ @@ -2407,20 +2370,6 @@ done: g_clear_error (&error); } -static gboolean -new_activation_allowed_for_connection (NMManager *self, - NMSettingsConnection *connection) -{ - if (NM_IN_SET (_nm_connection_get_multi_connect (nm_settings_connection_get_connection (connection)), - NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE, - NM_CONNECTION_MULTI_CONNECT_MULTIPLE)) - return TRUE; - - return !active_connection_find (self, connection, NULL, - NM_ACTIVE_CONNECTION_STATE_ACTIVATED, - NULL); -} - /** * get_existing_connection: * @manager: #NMManager instance @@ -2437,12 +2386,12 @@ get_existing_connection (NMManager *self, { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); gs_unref_object NMConnection *connection = NULL; - NMSettingsConnection *added; + NMSettingsConnection *added = NULL; GError *error = NULL; gs_free_error GError *gen_error = NULL; NMDevice *master = NULL; int ifindex = nm_device_get_ifindex (device); - NMSettingsConnection *matched = NULL; + NMSettingsConnection *matched; NMSettingsConnection *connection_checked = NULL; gboolean assume_state_guess_assume = FALSE; const char *assume_state_connection_uuid = NULL; @@ -2508,25 +2457,28 @@ get_existing_connection (NMManager *self, */ if ( assume_state_connection_uuid && (connection_checked = nm_settings_get_connection_by_uuid (priv->settings, assume_state_connection_uuid)) - && new_activation_allowed_for_connection (self, connection_checked) - && nm_device_check_connection_compatible (device, - nm_settings_connection_get_connection (connection_checked), - NULL)) { + && !active_connection_find (self, connection_checked, NULL, + NM_ACTIVE_CONNECTION_STATE_ACTIVATED, + NULL) + && nm_device_check_connection_compatible (device, NM_CONNECTION (connection_checked))) { if (connection) { - NMConnection *con = nm_settings_connection_get_connection (connection_checked); - - if (nm_utils_match_connection ((NMConnection *[]) { con, NULL }, - connection, - TRUE, - nm_device_has_carrier (device), - nm_device_get_route_metric (device, AF_INET), - nm_device_get_route_metric (device, AF_INET6), - NULL, NULL)) - matched = connection_checked; + NMConnection *const connections[] = { + NM_CONNECTION (connection_checked), + NULL, + }; + + matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections, + connection, + TRUE, + nm_device_has_carrier (device), + nm_device_get_route_metric (device, AF_INET), + nm_device_get_route_metric (device, AF_INET6), + NULL, NULL)); } else matched = connection_checked; - } + } else + matched = NULL; if (!matched && only_by_uuid) { _LOG2D (LOGD_DEVICE, device, "assume: cannot generate connection: %s", @@ -2535,51 +2487,32 @@ get_existing_connection (NMManager *self, } if (!matched && assume_state_guess_assume) { - gs_free NMSettingsConnection **sett_conns = NULL; + gs_free NMSettingsConnection **connections = NULL; guint len, i, j; /* the state file doesn't indicate a connection UUID to assume. Search the * persistent connections for a matching candidate. */ - sett_conns = nm_manager_get_activatable_connections (self, FALSE, FALSE, &len); + connections = nm_manager_get_activatable_connections (self, &len, FALSE); if (len > 0) { for (i = 0, j = 0; i < len; i++) { - NMSettingsConnection *sett_conn = sett_conns[i]; + NMConnection *con = NM_CONNECTION (connections[i]); - if ( sett_conn != connection_checked - && nm_device_check_connection_compatible (device, - nm_settings_connection_get_connection (sett_conn), - NULL)) - sett_conns[j++] = sett_conn; + if ( con != NM_CONNECTION (connection_checked) + && nm_device_check_connection_compatible (device, con)) + connections[j++] = connections[i]; } - sett_conns[j] = NULL; + connections[j] = NULL; len = j; - if (len > 0) { - gs_free NMConnection **conns = NULL; - NMConnection *con; - - g_qsort_with_data (sett_conns, len, sizeof (sett_conns[0]), - nm_settings_connection_cmp_timestamp_p_with_data, NULL); - - conns = nm_settings_connections_array_to_connections (sett_conns, len); - - con = nm_utils_match_connection (conns, - connection, - FALSE, - nm_device_has_carrier (device), - nm_device_get_route_metric (device, AF_INET), - nm_device_get_route_metric (device, AF_INET6), - NULL, - NULL); - if (con) { - for (i = 0; i < len; i++) { - if (conns[i] == con) { - matched = sett_conns[i]; - break; - } - } - nm_assert (matched); - } - } + g_qsort_with_data (connections, len, sizeof (connections[0]), + nm_settings_connection_cmp_timestamp_p_with_data, NULL); + + matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection ((NMConnection *const*) connections, + connection, + FALSE, + nm_device_has_carrier (device), + nm_device_get_route_metric (device, AF_INET), + nm_device_get_route_metric (device, AF_INET6), + NULL, NULL)); } } @@ -2608,7 +2541,7 @@ get_existing_connection (NMManager *self, return NULL; } - nm_settings_connection_set_flags (added, + nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added), NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE, TRUE); @@ -2620,7 +2553,7 @@ static gboolean recheck_assume_connection (NMManager *self, NMDevice *device) { - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection; gboolean was_unmanaged = FALSE; gboolean generated = FALSE; NMDeviceState state; @@ -2642,9 +2575,9 @@ recheck_assume_connection (NMManager *self, return FALSE; } - sett_conn = get_existing_connection (self, device, &generated); + connection = get_existing_connection (self, device, &generated); /* log no reason. get_existing_connection() already does it. */ - if (!sett_conn) + if (!connection) return FALSE; nm_device_sys_iface_state_set (device, @@ -2676,8 +2609,7 @@ recheck_assume_connection (NMManager *self, subject = nm_auth_subject_new_internal (); active = _new_active_connection (self, FALSE, - sett_conn, - NULL, + NM_CONNECTION (connection), NULL, NULL, device, @@ -2688,7 +2620,7 @@ recheck_assume_connection (NMManager *self, if (!active) { _LOGW (LOGD_DEVICE, "assume: assumed connection %s failed to activate: %s", - nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn)), + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)), error->message); g_error_free (error); @@ -2700,7 +2632,7 @@ recheck_assume_connection (NMManager *self, if (generated) { _LOG2D (LOGD_DEVICE, device, "assume: deleting generated connection after assuming failed"); - nm_settings_connection_delete (sett_conn, NULL); + nm_settings_connection_delete (connection, NULL); } else { if (nm_device_sys_iface_state_get (device) == NM_DEVICE_SYS_IFACE_STATE_ASSUME) nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL); @@ -2710,14 +2642,7 @@ recheck_assume_connection (NMManager *self, /* If the device is a slave or VLAN, find the master ActiveConnection */ master_ac = NULL; - if ( find_master (self, - nm_settings_connection_get_connection (sett_conn), - device, - NULL, - NULL, - &master_ac, - NULL) - && master_ac) + if (find_master (self, NM_CONNECTION (connection), device, NULL, NULL, &master_ac, NULL) && master_ac) nm_active_connection_set_master (active, master_ac); active_connection_add (self, active); @@ -3321,11 +3246,9 @@ nm_manager_get_devices (NMManager *manager) static NMDevice * nm_manager_get_best_device_for_connection (NMManager *self, - NMSettingsConnection *sett_conn, NMConnection *connection, gboolean for_user_request, - GHashTable *unavailable_devices, - GError **error) + GHashTable *unavailable_devices) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMActiveConnectionState ac_state; @@ -3334,25 +3257,16 @@ nm_manager_get_best_device_for_connection (NMManager *self, NMDevice *device; NMDeviceCheckConAvailableFlags flags; gs_unref_ptrarray GPtrArray *all_ac_arr = NULL; - gs_free_error GError *local_best = NULL; - - nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn)); - nm_assert (!connection || NM_IS_CONNECTION (connection)); - nm_assert (sett_conn || connection); - nm_assert (!connection || !sett_conn || connection == nm_settings_connection_get_connection (sett_conn)); - - if (!connection) - connection = nm_settings_connection_get_connection (sett_conn); flags = for_user_request ? NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST : NM_DEVICE_CHECK_CON_AVAILABLE_NONE; - ac = active_connection_find_by_connection (self, sett_conn, connection, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, &all_ac_arr); + ac = active_connection_find_by_connection (self, connection, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, &all_ac_arr); if (ac) { ac_device = nm_active_connection_get_device (ac); if ( ac_device && ( (unavailable_devices && g_hash_table_contains (unavailable_devices, ac_device)) - || !nm_device_check_connection_available (ac_device, connection, flags, NULL, NULL))) + || !nm_device_check_connection_available (ac_device, connection, flags, NULL))) ac_device = NULL; if (all_ac_arr) { @@ -3369,7 +3283,7 @@ nm_manager_get_best_device_for_connection (NMManager *self, if ( !ac_device2 || (unavailable_devices && g_hash_table_contains (unavailable_devices, ac_device2)) - || !nm_device_check_connection_available (ac_device2, connection, flags, NULL, NULL)) + || !nm_device_check_connection_available (ac_device2, connection, flags, NULL)) continue; ac_state2 = nm_active_connection_get_state (ac2); @@ -3417,53 +3331,15 @@ found_better: /* Pick the first device that's compatible with the connection. */ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { - GError *local = NULL; - if ( unavailable_devices - && g_hash_table_contains (unavailable_devices, device)) + if (unavailable_devices && g_hash_table_contains (unavailable_devices, device)) continue; - if (nm_device_check_connection_available (device, - connection, - flags, - NULL, - error ? &local : NULL)) + if (nm_device_check_connection_available (device, connection, flags, NULL)) return device; - - if (error) { - gboolean reset_error; - - if (!local_best) - reset_error = TRUE; - else if (local_best->domain != NM_UTILS_ERROR) - reset_error = (local->domain == NM_UTILS_ERROR); - else { - reset_error = ( local->domain == NM_UTILS_ERROR - && local_best->code < local->code); - } - - if (reset_error) { - g_clear_error (&local_best); - g_set_error (&local_best, - local->domain, - local->code, - "device %s not available because %s", - nm_device_get_iface (device), - local->message); - } - g_error_free (local); - } } - if (error) { - if (local_best) - g_propagate_error (error, g_steal_pointer (&local_best)); - else { - nm_utils_error_set_literal (error, - NM_UTILS_ERROR_UNKNOWN, - "no suitable device found"); - } - } + /* No luck. :( */ return NULL; } @@ -3632,7 +3508,7 @@ find_master (NMManager *self, NMSettingConnection *s_con; const char *master; NMDevice *master_device = NULL; - NMSettingsConnection *master_connection; + NMSettingsConnection *master_connection = NULL; s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -3651,9 +3527,7 @@ find_master (NMManager *self, } master_connection = nm_device_get_settings_connection (master_device); - if ( master_connection - && !is_compatible_with_slave (nm_settings_connection_get_connection (master_connection), - connection)) { + if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), connection)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED, "The active connection on %s is not compatible", nm_device_get_iface (master_device)); @@ -3753,9 +3627,7 @@ ensure_master_active_connection (NMManager *self, * be already activated on the device, eg returned from find_master(). */ g_assert (!master_connection || master_connection == device_connection); - if ( device_connection - && !is_compatible_with_slave (nm_settings_connection_get_connection (device_connection), - connection)) { + if (device_connection && !is_compatible_with_slave (NM_CONNECTION (device_connection), connection)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED, "The active connection %s is not compatible", nm_connection_get_id (connection)); @@ -3780,22 +3652,17 @@ ensure_master_active_connection (NMManager *self, g_assert (master_connection == NULL); /* Find a compatible connection and activate this device using it */ - connections = nm_manager_get_activatable_connections (self, FALSE, TRUE, NULL); + connections = nm_manager_get_activatable_connections (self, NULL, TRUE); for (i = 0; connections[i]; i++) { NMSettingsConnection *candidate = connections[i]; - NMConnection *cand_conn = nm_settings_connection_get_connection (candidate); /* Ensure eg bond/team slave and the candidate master is a * bond/team master */ - if (!is_compatible_with_slave (cand_conn, connection)) + if (!is_compatible_with_slave (NM_CONNECTION (candidate), connection)) continue; - if (nm_device_check_connection_available (master_device, - cand_conn, - NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, - NULL, - NULL)) { + if (nm_device_check_connection_available (master_device, NM_CONNECTION (candidate), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) { master_ac = nm_manager_activate_connection (self, candidate, NULL, @@ -3831,11 +3698,7 @@ ensure_master_active_connection (NMManager *self, continue; } - if (!nm_device_check_connection_available (candidate, - nm_settings_connection_get_connection (master_connection), - NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, - NULL, - NULL)) + if (!nm_device_check_connection_available (candidate, NM_CONNECTION (master_connection), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) continue; if (!nm_device_is_software (candidate)) { @@ -3874,18 +3737,18 @@ typedef struct { /** * find_slaves: * @manager: #NMManager object - * @sett_conn: the master #NMSettingsConnection to find slave connections for - * @device: the master #NMDevice for the @sett_conn + * @connection: the master #NMSettingsConnection to find slave connections for + * @device: the master #NMDevice for the @connection * @out_n_slaves: on return, the number of slaves found * - * Given an #NMSettingsConnection, attempts to find its slaves. If @sett_conn is not + * Given an #NMSettingsConnection, attempts to find its slaves. If @connection is not * master, or has not any slaves, this will return %NULL. * - * Returns: an array of #SlaveConnectionInfo for given master @sett_conn, or %NULL + * Returns: an array of #SlaveConnectionInfo for given master @connection, or %NULL **/ static SlaveConnectionInfo * find_slaves (NMManager *manager, - NMSettingsConnection *sett_conn, + NMSettingsConnection *connection, NMDevice *device, guint *out_n_slaves) { @@ -3900,7 +3763,7 @@ find_slaves (NMManager *manager, nm_assert (out_n_slaves); - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (sett_conn)); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); g_return_val_if_fail (s_con, NULL); devices = g_hash_table_new (nm_direct_hash, NULL); @@ -3915,23 +3778,15 @@ find_slaves (NMManager *manager, for (i = 0; i < n_all_connections; i++) { NMSettingsConnection *master_connection = NULL; NMDevice *master_device = NULL, *slave_device; - NMSettingsConnection *candidate = all_connections[i]; - - find_master (manager, - nm_settings_connection_get_connection (candidate), - NULL, - &master_connection, - &master_device, - NULL, - NULL); - if ( (master_connection && master_connection == sett_conn) + NMConnection *candidate = NM_CONNECTION (all_connections[i]); + + find_master (manager, candidate, NULL, &master_connection, &master_device, NULL, NULL); + if ( (master_connection && master_connection == connection) || (master_device && master_device == device)) { slave_device = nm_manager_get_best_device_for_connection (manager, candidate, - NULL, FALSE, - devices, - NULL); + devices); if (!slaves) { /* what we allocate is quite likely much too large. Don't bother, it is only @@ -3940,7 +3795,7 @@ find_slaves (NMManager *manager, } nm_assert (n_slaves < n_all_connections); - slaves[n_slaves].connection = candidate, + slaves[n_slaves].connection = NM_SETTINGS_CONNECTION (candidate), slaves[n_slaves].device = slave_device, n_slaves++; @@ -3959,29 +3814,32 @@ static gboolean should_connect_slaves (NMConnection *connection, NMDevice *device) { NMSettingConnection *s_con; - NMSettingConnectionAutoconnectSlaves val; + NMSettingConnectionAutoconnectSlaves autoconnect_slaves; + gs_free char *value = NULL; s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); - val = nm_setting_connection_get_autoconnect_slaves (s_con); - if (val != NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT) + /* Check autoconnect-slaves property */ + autoconnect_slaves = nm_setting_connection_get_autoconnect_slaves (s_con); + if (autoconnect_slaves != NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT) goto out; - val = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "connection.autoconnect-slaves", - device, - 0, 1, -1); + /* Check configuration default for autoconnect-slaves property */ + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "connection.autoconnect-slaves", device); + if (value) + autoconnect_slaves = _nm_utils_ascii_str_to_int64 (value, 10, 0, 1, -1); out: - if (val == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO) + if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO) return FALSE; - if (val == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES) + if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES) return TRUE; return FALSE; } -static int +static gint compare_slaves (gconstpointer a, gconstpointer b, gpointer sort_by_name) { const SlaveConnectionInfo *a_info = a; @@ -4009,8 +3867,7 @@ autoconnect_slaves (NMManager *self, { GError *local_err = NULL; - if (should_connect_slaves (nm_settings_connection_get_connection (master_connection), - master_device)) { + if (should_connect_slaves (NM_CONNECTION (master_connection), master_device)) { gs_free SlaveConnectionInfo *slaves = NULL; guint i, n_slaves = 0; @@ -4151,7 +4008,7 @@ active_connection_parent_active (NMActiveConnection *active, { NMDevice *device = nm_active_connection_get_device (active); GError *error = NULL; - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection; NMDevice *parent; g_signal_handlers_disconnect_by_func (active, @@ -4167,13 +4024,10 @@ active_connection_parent_active (NMActiveConnection *active, return; } - sett_conn = nm_active_connection_get_settings_connection (active); + connection = nm_active_connection_get_settings_connection (active); parent = nm_active_connection_get_device (parent_ac); - if (!nm_device_create_and_realize (device, - nm_settings_connection_get_connection (sett_conn), - parent, - &error)) { + if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, &error)) { _LOGW (LOGD_CORE, "Could not realize device '%s': %s", nm_device_get_iface (device), error->message); nm_active_connection_set_state_fail (active, @@ -4191,13 +4045,11 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * { NMDevice *device, *master_device = NULL; NMConnection *applied; - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection; NMSettingsConnection *master_connection = NULL; NMConnection *existing_connection = NULL; NMActiveConnection *master_ac = NULL; NMAuthSubject *subject; - GError *local = NULL; - NMConnectionMultiConnect multi_connect; g_return_val_if_fail (NM_IS_MANAGER (self), FALSE); g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE); @@ -4208,8 +4060,8 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * device = nm_active_connection_get_device (active); g_return_val_if_fail (device != NULL, FALSE); - sett_conn = nm_active_connection_get_settings_connection (active); - nm_assert (sett_conn); + connection = nm_active_connection_get_settings_connection (active); + nm_assert (connection); applied = nm_active_connection_get_applied_connection (active); @@ -4231,13 +4083,10 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * } /* Final connection must be available on device */ - if (!nm_device_check_connection_available (device, applied, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL, &local)) { + if (!nm_device_check_connection_available (device, applied, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, - "Connection '%s' is not available on device %s because %s", - nm_settings_connection_get_id (sett_conn), - nm_device_get_iface (device), - local->message); - g_error_free (local); + "Connection '%s' is not available on the device %s at this time.", + nm_settings_connection_get_id (connection), nm_device_get_iface (device)); return FALSE; } @@ -4248,9 +4097,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * if (!nm_device_is_real (device)) { NMDevice *parent; - parent = find_parent_device_for_connection (self, - nm_settings_connection_get_connection (sett_conn), - NULL); + parent = find_parent_device_for_connection (self, (NMConnection *) connection, NULL); if (parent && !nm_device_is_real (parent)) { NMSettingsConnection *parent_con; @@ -4262,11 +4109,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * return FALSE; } - parent_ac = nm_manager_activate_connection (self, - parent_con, - NULL, - NULL, - parent, + parent_ac = nm_manager_activate_connection (self, parent_con, NULL, NULL, parent, subject, NM_ACTIVATION_TYPE_MANAGED, nm_active_connection_get_activation_reason (active), @@ -4284,10 +4127,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * nm_active_connection_set_parent (active, parent_ac); } else { /* We can realize now; no need to wait for a parent device. */ - if (!nm_device_create_and_realize (device, - nm_settings_connection_get_connection (sett_conn), - parent, - error)) { + if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, error)) { g_prefix_error (error, "%s failed to create resources: ", nm_device_get_iface (device)); return FALSE; } @@ -4295,15 +4135,11 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * } /* Try to find the master connection/device if the connection has a dependency */ - if (!find_master (self, - applied, - device, - &master_connection, - &master_device, - &master_ac, + if (!find_master (self, applied, device, + &master_connection, &master_device, &master_ac, error)) { g_prefix_error (error, "Can not find a master for %s: ", - nm_settings_connection_get_id (sett_conn)); + nm_settings_connection_get_id (connection)); return FALSE; } @@ -4313,23 +4149,21 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * if (master_connection || master_device) { if (master_connection) { _LOGD (LOGD_CORE, "Activation of '%s' requires master connection '%s'", - nm_settings_connection_get_id (sett_conn), + nm_settings_connection_get_id (connection), nm_settings_connection_get_id (master_connection)); } if (master_device) { _LOGD (LOGD_CORE, "Activation of '%s' requires master device '%s'", - nm_settings_connection_get_id (sett_conn), + nm_settings_connection_get_id (connection), nm_device_get_ip_iface (master_device)); } /* Ensure eg bond slave and the candidate master is a bond master */ - if ( master_connection - && !is_compatible_with_slave (nm_settings_connection_get_connection (master_connection), - applied)) { + if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), applied)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED, "The master connection '%s' is not compatible with '%s'", nm_settings_connection_get_id (master_connection), - nm_settings_connection_get_id (sett_conn)); + nm_settings_connection_get_id (connection)); return FALSE; } @@ -4348,7 +4182,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * nm_device_get_ip_iface (device)); } else { g_prefix_error (error, "Master connection '%s' can't be activated: ", - nm_settings_connection_get_id (sett_conn)); + nm_settings_connection_get_id (connection)); } return FALSE; } @@ -4365,30 +4199,22 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * nm_active_connection_set_master (active, master_ac); _LOGD (LOGD_CORE, "Activation of '%s' depends on active connection %p %s", - nm_settings_connection_get_id (sett_conn), + nm_settings_connection_get_id (connection), master_ac, nm_dbus_object_get_path (NM_DBUS_OBJECT (master_ac)) ?: ""); } /* Check slaves for master connection and possibly activate them */ - autoconnect_slaves (self, sett_conn, device, nm_active_connection_get_subject (active)); - - multi_connect = _nm_connection_get_multi_connect (nm_settings_connection_get_connection (sett_conn)); - if ( multi_connect == NM_CONNECTION_MULTI_CONNECT_MULTIPLE - || ( multi_connect == NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE - && NM_IN_SET (nm_active_connection_get_activation_reason (active), - NM_ACTIVATION_REASON_ASSUME, - NM_ACTIVATION_REASON_AUTOCONNECT_SLAVES, - NM_ACTIVATION_REASON_USER_REQUEST))) { - /* the profile can be activated multiple times. Proceed. */ - } else { + autoconnect_slaves (self, connection, device, nm_active_connection_get_subject (active)); + + { gs_unref_ptrarray GPtrArray *all_ac_arr = NULL; NMActiveConnection *ac; guint i, n_all; /* Disconnect the connection if already connected or queued for activation. * The connection cannot be active multiple times (at the same time). */ - ac = active_connection_find (self, sett_conn, NULL, NM_ACTIVE_CONNECTION_STATE_ACTIVATED, + ac = active_connection_find (self, connection, NULL, NM_ACTIVE_CONNECTION_STATE_ACTIVATED, &all_ac_arr); if (ac) { n_all = all_ac_arr ? all_ac_arr->len : ((guint) 1); @@ -4451,7 +4277,7 @@ _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError * is exported, make sure the manager's activating-connection property * is up-to-date. */ - policy_activating_ac_changed (G_OBJECT (priv->policy), NULL, self); + policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self); } return success; @@ -4460,8 +4286,7 @@ _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError static NMActiveConnection * _new_active_connection (NMManager *self, gboolean is_vpn, - NMSettingsConnection *sett_conn, - NMConnection *incompl_conn, + NMConnection *connection, NMConnection *applied, const char *specific_object, NMDevice *device, @@ -4471,19 +4296,18 @@ _new_active_connection (NMManager *self, GError **error) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMSettingsConnection *settings_connection = NULL; NMDevice *parent_device; - nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn)); - nm_assert (!incompl_conn || NM_IS_CONNECTION (incompl_conn)); - nm_assert ((!incompl_conn) ^ (!sett_conn)); - nm_assert (NM_IS_AUTH_SUBJECT (subject)); - nm_assert (is_vpn == _connection_is_vpn (sett_conn - ? nm_settings_connection_get_connection (sett_conn) - : incompl_conn)); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); + + nm_assert (is_vpn == _connection_is_vpn (connection)); nm_assert (is_vpn || NM_IS_DEVICE (device)); nm_assert (!nm_streq0 (specific_object, "/")); - nm_assert (!applied || NM_IS_CONNECTION (applied)); - nm_assert (!is_vpn || !applied); + + if (NM_IS_SETTINGS_CONNECTION (connection)) + settings_connection = (NMSettingsConnection *) connection; if (is_vpn) { NMActiveConnection *parent; @@ -4491,20 +4315,21 @@ _new_active_connection (NMManager *self, /* FIXME: for VPN connections, we don't allow re-activating an * already active connection. It's a bug, and should be fixed together * when reworking VPN handling. */ - if (active_connection_find_by_connection (self, - sett_conn, - incompl_conn, - NM_ACTIVE_CONNECTION_STATE_ACTIVATED, - NULL)) { + if (active_connection_find_by_connection (self, connection, NM_ACTIVE_CONNECTION_STATE_ACTIVATED, NULL)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE, "Connection '%s' is already active", - sett_conn ? nm_settings_connection_get_id (sett_conn) : nm_connection_get_id (incompl_conn)); + nm_connection_get_id (connection)); return NULL; } + /* FIXME: apparently, activation here only works if @connection is + * a settings-connection. Which is not the case during AddAndActivatate. + * Probably, AddAndActivate is broken for VPN. */ if (activation_type != NM_ACTIVATION_TYPE_MANAGED) g_return_val_if_reached (NULL); + g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL); + if (specific_object) { /* Find the specific connection the client requested we use */ parent = active_connection_get_by_path (self, specific_object); @@ -4535,14 +4360,14 @@ _new_active_connection (NMManager *self, return NULL; } - return (NMActiveConnection *) nm_vpn_connection_new (sett_conn, + return (NMActiveConnection *) nm_vpn_connection_new (settings_connection, parent_device, nm_dbus_object_get_path (NM_DBUS_OBJECT (parent)), activation_reason, subject); } - return (NMActiveConnection *) nm_act_request_new (sett_conn, + return (NMActiveConnection *) nm_act_request_new (settings_connection, applied, specific_object, subject, @@ -4603,17 +4428,17 @@ fail: /** * nm_manager_activate_connection(): * @self: the #NMManager - * @sett_conn: the #NMSettingsConnection to activate on @device + * @connection: the #NMSettingsConnection to activate on @device * @applied: (allow-none): the applied connection to activate on @device * @specific_object: the specific object path, if any, for the activation - * @device: the #NMDevice to activate @sett_conn on. Can be %NULL for VPNs. + * @device: the #NMDevice to activate @connection on. Can be %NULL for VPNs. * @subject: the subject which requested activation * @activation_type: whether to assume the connection. That is, take over gracefully, * non-destructible. * @activation_reason: the reason for activation * @error: return location for an error * - * Begins a new internally-initiated activation of @sett_conn on @device. + * Begins a new internally-initiated activation of @connection on @device. * @subject should be the subject of the activation that triggered this * one, or if this is an autoconnect request, a new internal subject. * The returned #NMActiveConnection is owned by the Manager and should be @@ -4621,11 +4446,11 @@ fail: * is supplied, it shall not be modified by the caller afterwards. * * Returns: (transfer none): the new #NMActiveConnection that tracks - * activation of @sett_conn on @device + * activation of @connection on @device */ NMActiveConnection * nm_manager_activate_connection (NMManager *self, - NMSettingsConnection *sett_conn, + NMSettingsConnection *connection, NMConnection *applied, const char *specific_object, NMDevice *device, @@ -4640,15 +4465,15 @@ nm_manager_activate_connection (NMManager *self, gboolean is_vpn; g_return_val_if_fail (NM_IS_MANAGER (self), NULL); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn), NULL); - is_vpn = _connection_is_vpn (nm_settings_connection_get_connection (sett_conn)); + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), NULL); + is_vpn = _connection_is_vpn (NM_CONNECTION (connection)); g_return_val_if_fail (is_vpn || NM_IS_DEVICE (device), NULL); g_return_val_if_fail (!error || !*error, NULL); nm_assert (!nm_streq0 (specific_object, "/")); priv = NM_MANAGER_GET_PRIVATE (self); - if (!nm_auth_is_subject_in_acl_set_error (nm_settings_connection_get_connection (sett_conn), + if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (connection), subject, NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -4666,7 +4491,7 @@ nm_manager_activate_connection (NMManager *self, continue; active = async_op_data->ac_auth.active; - if ( sett_conn == nm_active_connection_get_settings_connection (active) + if ( connection == nm_active_connection_get_settings_connection (active) && nm_streq0 (nm_active_connection_get_specific_object (active), specific_object) && (!device || nm_active_connection_get_device (active) == device) && nm_auth_subject_is_internal (nm_active_connection_get_subject (active)) @@ -4677,8 +4502,7 @@ nm_manager_activate_connection (NMManager *self, active = _new_active_connection (self, is_vpn, - sett_conn, - NULL, + NM_CONNECTION (connection), applied, specific_object, device, @@ -4701,9 +4525,7 @@ nm_manager_activate_connection (NMManager *self, * validate_activation_request: * @self: the #NMManager * @context: the D-Bus context of the requestor - * @sett_conn: the #NMSettingsConnection to be activated, or %NULL if there - * is only a partial activation. - * @connection: the partial #NMConnection to be activated (if @sett_conn is unspecified) + * @connection: the partial or complete #NMConnection to be activated * @device_path: the object path of the device to be activated, or NULL * @out_device: on successful reutrn, the #NMDevice to be activated with @connection * The caller may pass in a device which shortcuts the lookup by path. @@ -4722,7 +4544,6 @@ nm_manager_activate_connection (NMManager *self, static NMAuthSubject * validate_activation_request (NMManager *self, GDBusMethodInvocation *context, - NMSettingsConnection *sett_conn, NMConnection *connection, const char *device_path, NMDevice **out_device, @@ -4733,16 +4554,10 @@ validate_activation_request (NMManager *self, gboolean is_vpn = FALSE; gs_unref_object NMAuthSubject *subject = NULL; - nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn)); - nm_assert (!connection || NM_IS_CONNECTION (connection)); - nm_assert (sett_conn || connection); - nm_assert (!connection || !sett_conn || connection == nm_settings_connection_get_connection (sett_conn)); + nm_assert (NM_IS_CONNECTION (connection)); nm_assert (out_device); nm_assert (out_is_vpn); - if (!connection) - connection = nm_settings_connection_get_connection (sett_conn); - /* Validate the caller */ subject = nm_auth_subject_new_unix_process_from_context (context); if (!subject) { @@ -4778,20 +4593,17 @@ validate_activation_request (NMManager *self, return NULL; } } else if (!is_vpn) { - gs_free_error GError *local = NULL; - - device = nm_manager_get_best_device_for_connection (self, sett_conn, connection, TRUE, NULL, &local); + device = nm_manager_get_best_device_for_connection (self, connection, TRUE, NULL); if (!device) { gs_free char *iface = NULL; /* VPN and software-device connections don't need a device yet, * but non-virtual connections do ... */ if (!nm_connection_is_virtual (connection)) { - g_set_error (error, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_UNKNOWN_DEVICE, - "No suitable device found for this connection (%s).", - local->message); + g_set_error_literal (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "No suitable device found for this connection."); return NULL; } @@ -4877,7 +4689,7 @@ impl_manager_activate_connection (NMDBusObject *obj, NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); gs_unref_object NMActiveConnection *active = NULL; gs_unref_object NMAuthSubject *subject = NULL; - NMSettingsConnection *sett_conn = NULL; + NMSettingsConnection *connection = NULL; NMDevice *device = NULL; gboolean is_vpn = FALSE; GError *error = NULL; @@ -4897,8 +4709,8 @@ impl_manager_activate_connection (NMDBusObject *obj, * (since this is an explicit request, not an auto-activation request). */ if (connection_path) { - sett_conn = nm_settings_get_connection_by_path (priv->settings, connection_path); - if (!sett_conn) { + connection = nm_settings_get_connection_by_path (priv->settings, connection_path); + if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, "Connection could not be found."); @@ -4918,15 +4730,14 @@ impl_manager_activate_connection (NMDBusObject *obj, goto error; } - sett_conn = nm_device_get_best_connection (device, specific_object_path, &error); - if (!sett_conn) + connection = nm_device_get_best_connection (device, specific_object_path, &error); + if (!connection) goto error; } subject = validate_activation_request (self, invocation, - sett_conn, - NULL, + NM_CONNECTION (connection), device_path, &device, &is_vpn, @@ -4936,8 +4747,7 @@ impl_manager_activate_connection (NMDBusObject *obj, active = _new_active_connection (self, is_vpn, - sett_conn, - NULL, + NM_CONNECTION (connection), NULL, specific_object_path, device, @@ -4961,8 +4771,8 @@ impl_manager_activate_connection (NMDBusObject *obj, return; error: - if (sett_conn) { - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, sett_conn, FALSE, NULL, + if (connection) { + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, NULL, subject, error->message); } g_dbus_method_invocation_take_error (invocation, error); @@ -5077,7 +4887,7 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, { NMManager *self = NM_MANAGER (obj); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - gs_unref_object NMConnection *incompl_conn = NULL; + gs_unref_object NMConnection *connection = NULL; NMActiveConnection *active = NULL; gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; @@ -5086,7 +4896,6 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, gs_unref_variant GVariant *settings = NULL; const char *device_path; const char *specific_object_path; - gs_free NMConnection **conns = NULL; g_variant_get (parameters, "(@a{sa{sv}}&o&o)", &settings, &device_path, &specific_object_path); @@ -5100,14 +4909,13 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, * specific data being in the connection till then (especially in * validate_activation_request()). */ - incompl_conn = nm_simple_connection_new (); + connection = nm_simple_connection_new (); if (settings && g_variant_n_children (settings)) - _nm_connection_replace_settings (incompl_conn, settings, NM_SETTING_PARSE_FLAGS_STRICT, NULL); + _nm_connection_replace_settings (connection, settings, NM_SETTING_PARSE_FLAGS_STRICT, NULL); subject = validate_activation_request (self, invocation, - NULL, - incompl_conn, + connection, device_path, &device, &is_vpn, @@ -5117,7 +4925,7 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, if (is_vpn) { /* Try to fill the VPN's connection setting and name at least */ - if (!nm_connection_get_setting_vpn (incompl_conn)) { + if (!nm_connection_get_setting_vpn (connection)) { error = g_error_new_literal (NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING, "VPN connections require a 'vpn' setting"); @@ -5125,31 +4933,27 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, goto error; } - conns = nm_settings_connections_array_to_connections (nm_settings_get_connections (priv->settings, NULL), -1); - nm_utils_complete_generic (priv->platform, - incompl_conn, + connection, NM_SETTING_VPN_SETTING_NAME, - conns, + (NMConnection *const*) nm_settings_get_connections (priv->settings, NULL), NULL, _("VPN connection"), NULL, FALSE); /* No IPv6 by default for now */ } else { - conns = nm_settings_connections_array_to_connections (nm_settings_get_connections (priv->settings, NULL), -1); /* Let each device subclass complete the connection */ if (!nm_device_complete_connection (device, - incompl_conn, + connection, specific_object_path, - conns, + (NMConnection *const*) nm_settings_get_connections (priv->settings, NULL), &error)) goto error; } active = _new_active_connection (self, is_vpn, - NULL, - incompl_conn, + connection, NULL, specific_object_path, device, @@ -5160,16 +4964,15 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, if (!active) goto error; - nm_active_connection_authorize (active, - incompl_conn, + nm_active_connection_authorize (active, connection, _async_op_complete_ac_auth_cb, _async_op_data_new_ac_auth_add_and_activate (self, active, invocation, - incompl_conn)); + connection)); /* we passed the pointers on to _async_op_data_new_ac_auth_add_and_activate() */ - g_steal_pointer (&incompl_conn); + g_steal_pointer (&connection); g_steal_pointer (&active); return; @@ -5286,7 +5089,7 @@ impl_manager_deactivate_connection (NMDBusObject *obj, NMManager *self = NM_MANAGER (obj); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMActiveConnection *ac; - NMSettingsConnection *sett_conn = NULL; + NMSettingsConnection *connection = NULL; GError *error = NULL; NMAuthSubject *subject = NULL; NMAuthChain *chain; @@ -5297,9 +5100,9 @@ impl_manager_deactivate_connection (NMDBusObject *obj, /* Find the connection by its object path */ ac = active_connection_get_by_path (self, active_path); if (ac) - sett_conn = nm_active_connection_get_settings_connection (ac); + connection = nm_active_connection_get_settings_connection (ac); - if (!sett_conn) { + if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, "The connection was not active."); @@ -5315,7 +5118,7 @@ impl_manager_deactivate_connection (NMDBusObject *obj, goto done; } - if (!nm_auth_is_subject_in_acl_set_error (nm_settings_connection_get_connection (sett_conn), + if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (connection), subject, NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -5337,9 +5140,8 @@ impl_manager_deactivate_connection (NMDBusObject *obj, done: if (error) { - if (sett_conn) { - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, - sett_conn, FALSE, NULL, + if (connection) { + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE, NULL, subject, error->message); } g_dbus_method_invocation_take_error (invocation, error); @@ -6088,76 +5890,66 @@ start_factory (NMDeviceFactory *factory, gpointer user_data) nm_device_factory_start (factory); } -gboolean -nm_manager_write_device_state (NMManager *self, NMDevice *device) +void +nm_manager_write_device_state (NMManager *self) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - int ifindex; - gboolean managed; - NMConfigDeviceStateManagedType managed_type; - const char *uuid = NULL; - const char *perm_hw_addr_fake = NULL; - gboolean perm_hw_addr_is_fake; - guint32 route_metric_default_aspired; - guint32 route_metric_default_effective; - int nm_owned; - - ifindex = nm_device_get_ip_ifindex (device); - if (ifindex <= 0) - return FALSE; - if (ifindex == 1) { - /* ignore loopback */ - return FALSE; - } + NMDevice *device; + gs_unref_hashtable GHashTable *seen_ifindexes = NULL; + gint nm_owned; - if (!nm_platform_link_get (priv->platform, ifindex)) - return FALSE; + seen_ifindexes = g_hash_table_new (nm_direct_hash, NULL); - managed = nm_device_get_managed (device, FALSE); - if (managed) { - NMSettingsConnection *sett_conn; + c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { + int ifindex; + gboolean managed; + NMConfigDeviceStateManagedType managed_type; + NMConnection *settings_connection; + const char *uuid = NULL; + const char *perm_hw_addr_fake = NULL; + gboolean perm_hw_addr_is_fake; + guint32 route_metric_default_aspired; + guint32 route_metric_default_effective; + + ifindex = nm_device_get_ip_ifindex (device); + if (ifindex <= 0) + continue; + if (ifindex == 1) { + /* ignore loopback */ + continue; + } - sett_conn = nm_device_get_settings_connection (device); - if (sett_conn) - uuid = nm_settings_connection_get_uuid (sett_conn); - managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_MANAGED; - } else if (nm_device_get_unmanaged_flags (device, NM_UNMANAGED_USER_EXPLICIT)) - managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNMANAGED; - else - managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNKNOWN; + if (!nm_platform_link_get (priv->platform, ifindex)) + continue; - perm_hw_addr_fake = nm_device_get_permanent_hw_address_full (device, FALSE, &perm_hw_addr_is_fake); - if (perm_hw_addr_fake && !perm_hw_addr_is_fake) - perm_hw_addr_fake = NULL; + managed = nm_device_get_managed (device, FALSE); + if (managed) { + settings_connection = NM_CONNECTION (nm_device_get_settings_connection (device)); + if (settings_connection) + uuid = nm_connection_get_uuid (settings_connection); + managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_MANAGED; + } else if (nm_device_get_unmanaged_flags (device, NM_UNMANAGED_USER_EXPLICIT)) + managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNMANAGED; + else + managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNKNOWN; - nm_owned = nm_device_is_software (device) ? nm_device_is_nm_owned (device) : -1; + perm_hw_addr_fake = nm_device_get_permanent_hw_address_full (device, FALSE, &perm_hw_addr_is_fake); + if (perm_hw_addr_fake && !perm_hw_addr_is_fake) + perm_hw_addr_fake = NULL; - route_metric_default_effective = _device_route_metric_get (self, ifindex, NM_DEVICE_TYPE_UNKNOWN, - TRUE, &route_metric_default_aspired); + nm_owned = nm_device_is_software (device) ? nm_device_is_nm_owned (device) : -1; - return nm_config_device_state_write (ifindex, - managed_type, - perm_hw_addr_fake, - uuid, - nm_owned, - route_metric_default_aspired, - route_metric_default_effective); -} + route_metric_default_effective = _device_route_metric_get (self, ifindex, NM_DEVICE_TYPE_UNKNOWN, + TRUE, &route_metric_default_aspired); -void -nm_manager_write_device_state_all (NMManager *self) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - gs_unref_hashtable GHashTable *seen_ifindexes = NULL; - NMDevice *device; - - seen_ifindexes = g_hash_table_new (nm_direct_hash, NULL); - - c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { - if (nm_manager_write_device_state (self, device)) { - g_hash_table_add (seen_ifindexes, - GINT_TO_POINTER (nm_device_get_ip_ifindex (device))); - } + if (nm_config_device_state_write (ifindex, + managed_type, + perm_hw_addr_fake, + uuid, + nm_owned, + route_metric_default_aspired, + route_metric_default_effective)) + g_hash_table_add (seen_ifindexes, GINT_TO_POINTER (ifindex)); } nm_config_device_state_prune_unseen (seen_ifindexes); @@ -6237,7 +6029,7 @@ nm_manager_start (NMManager *self, GError **error) NULL, NULL, nm_settings_connection_cmp_autoconnect_priority_p_with_data, NULL); for (i = 0; connections[i]; i++) - connection_changed (self, connections[i]); + connection_changed (self, NM_CONNECTION (connections[i])); nm_clear_g_source (&priv->devices_inited_id); priv->devices_inited_id = g_idle_add_full (G_PRIORITY_LOW + 10, devices_inited_cb, self, NULL); @@ -6337,19 +6129,25 @@ connection_metered_changed (GObject *object, } static void -policy_default_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data) +policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data) { NMManager *self = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMDevice *best; NMActiveConnection *ac; /* Note: this assumes that it's not possible for the IP4 default * route to be going over the default-ip6-device. If that changes, * we need something more complicated here. */ - ac = nm_policy_get_default_ip4_ac (priv->policy); - if (!ac) - ac = nm_policy_get_default_ip6_ac (priv->policy); + best = nm_policy_get_default_ip4_device (priv->policy); + if (!best) + best = nm_policy_get_default_ip6_device (priv->policy); + + if (best) + ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (best)); + else + ac = NULL; if (ac != priv->primary_connection) { if (priv->primary_connection) { @@ -6362,12 +6160,10 @@ policy_default_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_dat priv->primary_connection = ac ? g_object_ref (ac) : NULL; if (priv->primary_connection) { - g_signal_connect (priv->primary_connection, - NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED, + g_signal_connect (priv->primary_connection, NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED, G_CALLBACK (connection_metered_changed), self); } - _LOGD (LOGD_CORE, "PrimaryConnection now %s", - ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)"); + _LOGD (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)"); _notify (self, PROP_PRIMARY_CONNECTION); _notify (self, PROP_PRIMARY_CONNECTION_TYPE); nm_manager_update_metered (self); @@ -6375,29 +6171,34 @@ policy_default_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_dat } static void -policy_activating_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data) +policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data) { NMManager *self = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMActiveConnection *activating, *best; + NMDevice *activating, *best; + NMActiveConnection *ac; - /* We only look at activating-ip6-ac if activating-ip4-ac - * AND default-ip4-ac are NULL; if default-ip4-ac is - * non-NULL, then activating-ip6-ac is irrelevant, since while - * that AC might become the new default-ip6-ac, it can't - * become primary-connection while default-ip4-ac is set to + /* We only look at activating-ip6-device if activating-ip4-device + * AND default-ip4-device are NULL; if default-ip4-device is + * non-NULL, then activating-ip6-device is irrelevant, since while + * that device might become the new default-ip6-device, it can't + * become primary-connection while default-ip4-device is set to * something else. */ - activating = nm_policy_get_activating_ip4_ac (priv->policy); - best = nm_policy_get_default_ip4_ac (priv->policy); + activating = nm_policy_get_activating_ip4_device (priv->policy); + best = nm_policy_get_default_ip4_device (priv->policy); if (!activating && !best) - activating = nm_policy_get_activating_ip6_ac (priv->policy); + activating = nm_policy_get_activating_ip6_device (priv->policy); - if (nm_g_object_ref_set (&priv->activating_connection, activating)) { - _LOGD (LOGD_CORE, "ActivatingConnection now %s", - activating - ? nm_active_connection_get_settings_connection_id (activating) - : "(none)"); + if (activating) + ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (activating)); + else + ac = NULL; + + if (ac != priv->activating_connection) { + g_clear_object (&priv->activating_connection); + priv->activating_connection = ac ? g_object_ref (ac) : NULL; + _LOGD (LOGD_CORE, "ActivatingConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)"); _notify (self, PROP_ACTIVATING_CONNECTION); } } @@ -6902,12 +6703,12 @@ nm_manager_set_capability (NMManager *self, priv = NM_MANAGER_GET_PRIVATE (self); - idx = nm_utils_array_find_binary_search (&g_array_index (priv->capabilities, guint32, 0), - sizeof (guint32), - priv->capabilities->len, - &cap_i, - nm_cmp_uint32_p_with_data, - NULL); + idx = _nm_utils_array_find_binary_search (&g_array_index (priv->capabilities, guint32, 0), + sizeof (guint32), + priv->capabilities->len, + &cap_i, + nm_cmp_uint32_p_with_data, + NULL); if (idx >= 0) return; @@ -6988,14 +6789,14 @@ constructed (GObject *object) */ priv->policy = nm_policy_new (self, priv->settings); - g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_AC, - G_CALLBACK (policy_default_ac_changed), self); - g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_AC, - G_CALLBACK (policy_default_ac_changed), self); - g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_AC, - G_CALLBACK (policy_activating_ac_changed), self); - g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_AC, - G_CALLBACK (policy_activating_ac_changed), self); + g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_DEVICE, + G_CALLBACK (policy_default_device_changed), self); + g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_DEVICE, + G_CALLBACK (policy_default_device_changed), self); + g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_DEVICE, + G_CALLBACK (policy_activating_device_changed), self); + g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_DEVICE, + G_CALLBACK (policy_activating_device_changed), self); priv->config = g_object_ref (nm_config_get ()); g_signal_connect (G_OBJECT (priv->config), @@ -7333,8 +7134,8 @@ dispose (GObject *object) } if (priv->policy) { - g_signal_handlers_disconnect_by_func (priv->policy, policy_default_ac_changed, self); - g_signal_handlers_disconnect_by_func (priv->policy, policy_activating_ac_changed, self); + g_signal_handlers_disconnect_by_func (priv->policy, policy_default_device_changed, self); + g_signal_handlers_disconnect_by_func (priv->policy, policy_activating_device_changed, self); g_clear_object (&priv->policy); } |