2008-11-03 04:13:42 +00:00
|
|
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
|
|
|
|
/* NetworkManager -- Network link manager
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
|
*
|
2009-05-20 12:02:18 -04:00
|
|
|
* Copyright (C) 2007 - 2009 Novell, Inc.
|
2012-02-05 23:18:32 -06:00
|
|
|
* Copyright (C) 2007 - 2012 Red Hat, Inc.
|
2008-11-03 04:13:42 +00:00
|
|
|
*/
|
2007-08-15 07:52:25 +00:00
|
|
|
|
2016-02-19 14:57:48 +01:00
|
|
|
#include "nm-default.h"
|
2010-08-13 13:18:58 -05:00
|
|
|
|
2016-05-16 18:08:08 +02:00
|
|
|
#include "nm-manager.h"
|
|
|
|
|
|
2013-05-27 20:35:33 +02:00
|
|
|
#include <stdlib.h>
|
2011-04-22 14:56:31 -05:00
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <errno.h>
|
2007-02-08 15:34:26 +00:00
|
|
|
#include <string.h>
|
2012-02-22 16:52:41 +01:00
|
|
|
#include <unistd.h>
|
2007-02-08 15:34:26 +00:00
|
|
|
|
2016-06-01 12:31:36 +02:00
|
|
|
#include "nm-common-macros.h"
|
2015-04-16 14:20:51 -04:00
|
|
|
#include "nm-bus-manager.h"
|
2008-03-26 13:43:01 +00:00
|
|
|
#include "nm-vpn-manager.h"
|
2011-11-17 22:39:34 -06:00
|
|
|
#include "nm-device.h"
|
2013-04-17 10:41:15 -04:00
|
|
|
#include "nm-device-generic.h"
|
2013-01-21 15:12:24 +01:00
|
|
|
#include "nm-platform.h"
|
2013-05-09 10:24:08 -04:00
|
|
|
#include "nm-rfkill-manager.h"
|
2014-04-02 15:52:04 -05:00
|
|
|
#include "nm-dhcp-manager.h"
|
2010-10-27 20:05:23 -05:00
|
|
|
#include "nm-settings.h"
|
2011-01-26 11:38:12 -06:00
|
|
|
#include "nm-settings-connection.h"
|
2014-08-16 01:33:46 +02:00
|
|
|
#include "nm-auth-utils.h"
|
2014-08-14 13:34:57 +02:00
|
|
|
#include "nm-auth-manager.h"
|
2011-01-13 13:30:30 -06:00
|
|
|
#include "NetworkManagerUtils.h"
|
2012-02-05 23:18:32 -06:00
|
|
|
#include "nm-device-factory.h"
|
2012-02-08 12:56:52 -05:00
|
|
|
#include "nm-enum-types.h"
|
2012-10-09 00:36:35 -04:00
|
|
|
#include "nm-sleep-monitor.h"
|
2011-10-21 21:21:30 +02:00
|
|
|
#include "nm-connectivity.h"
|
2013-08-22 10:10:17 -04:00
|
|
|
#include "nm-policy.h"
|
2014-07-17 17:06:44 -04:00
|
|
|
#include "nm-session-monitor.h"
|
|
|
|
|
#include "nm-activation-request.h"
|
2014-10-21 22:09:52 -04:00
|
|
|
#include "nm-core-internal.h"
|
2014-10-29 09:12:18 -05:00
|
|
|
#include "nm-config.h"
|
2015-07-14 10:26:54 +02:00
|
|
|
#include "nm-audit-manager.h"
|
2015-04-15 14:53:30 -04:00
|
|
|
#include "nm-dbus-compat.h"
|
2016-07-01 12:11:01 +02:00
|
|
|
#include "nm-checkpoint.h"
|
|
|
|
|
#include "nm-checkpoint-manager.h"
|
2015-08-10 16:38:26 +02:00
|
|
|
#include "NetworkManagerUtils.h"
|
2007-02-08 15:34:26 +00:00
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
#include "nmdbus-manager.h"
|
2015-09-15 11:34:00 +02:00
|
|
|
#include "nmdbus-device.h"
|
2007-02-12 09:23:43 +00:00
|
|
|
|
2015-12-08 14:51:56 +01:00
|
|
|
static gboolean add_device (NMManager *self, NMDevice *device, GError **error);
|
2009-01-19 11:01:00 +02:00
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
static NMActiveConnection *_new_active_connection (NMManager *self,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
const char *specific_object,
|
|
|
|
|
NMDevice *device,
|
|
|
|
|
NMAuthSubject *subject,
|
|
|
|
|
GError **error);
|
|
|
|
|
|
|
|
|
|
static void policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
|
2009-08-05 18:03:09 -04:00
|
|
|
|
2013-11-07 01:05:04 -06:00
|
|
|
static gboolean find_master (NMManager *self,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
NMDevice *device,
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection **out_master_connection,
|
2014-01-29 11:48:03 -05:00
|
|
|
NMDevice **out_master_device,
|
2014-01-28 17:24:26 -05:00
|
|
|
NMActiveConnection **out_master_ac,
|
2014-01-29 11:48:03 -05:00
|
|
|
GError **error);
|
2013-11-07 01:05:04 -06:00
|
|
|
|
2013-11-08 12:23:43 -05:00
|
|
|
static void nm_manager_update_state (NMManager *manager);
|
|
|
|
|
|
2016-04-13 16:03:06 +02:00
|
|
|
static void connection_changed (NMManager *self, NMConnection *connection);
|
2016-05-05 14:14:40 +02:00
|
|
|
static void device_sleep_cb (NMDevice *device,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMManager *self);
|
2016-01-07 17:54:38 +01:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
#define TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE "act-con-add-and-activate"
|
2007-10-01 15:38:39 +00:00
|
|
|
|
2009-12-23 00:03:45 -08:00
|
|
|
typedef struct {
|
2010-09-01 17:08:10 -05:00
|
|
|
gboolean user_enabled;
|
|
|
|
|
gboolean sw_enabled;
|
2009-12-23 00:03:45 -08:00
|
|
|
gboolean hw_enabled;
|
2010-03-25 11:36:19 -07:00
|
|
|
RfKillType rtype;
|
2015-11-06 16:45:27 +01:00
|
|
|
NMConfigRunStatePropertyType key;
|
2009-12-23 00:03:45 -08:00
|
|
|
const char *desc;
|
|
|
|
|
const char *prop;
|
|
|
|
|
const char *hw_prop;
|
|
|
|
|
} RadioState;
|
|
|
|
|
|
2007-02-08 15:34:26 +00:00
|
|
|
typedef struct {
|
2016-09-15 23:34:24 +03:00
|
|
|
GArray *capabilities;
|
|
|
|
|
|
2012-08-22 17:11:31 -05:00
|
|
|
GSList *active_connections;
|
2015-06-23 20:52:04 +02:00
|
|
|
GSList *authorizing_connections;
|
2012-08-22 17:11:31 -05:00
|
|
|
guint ac_cleanup_id;
|
2013-08-22 13:06:51 -04:00
|
|
|
NMActiveConnection *primary_connection;
|
|
|
|
|
NMActiveConnection *activating_connection;
|
2015-06-03 09:15:24 +02:00
|
|
|
NMMetered metered;
|
2012-08-22 17:11:31 -05:00
|
|
|
|
2007-02-08 15:34:26 +00:00
|
|
|
GSList *devices;
|
2007-09-25 16:47:53 +00:00
|
|
|
NMState state;
|
2015-01-30 19:52:53 +01:00
|
|
|
NMConfig *config;
|
2011-10-21 21:21:30 +02:00
|
|
|
NMConnectivity *connectivity;
|
2007-09-09 22:18:42 +00:00
|
|
|
|
2013-08-22 10:10:17 -04:00
|
|
|
NMPolicy *policy;
|
|
|
|
|
|
2015-04-16 14:20:51 -04:00
|
|
|
NMBusManager *dbus_mgr;
|
2015-08-20 14:25:46 +02:00
|
|
|
struct {
|
|
|
|
|
GDBusConnection *connection;
|
|
|
|
|
guint id;
|
|
|
|
|
} prop_filter;
|
2013-05-09 10:24:08 -04:00
|
|
|
NMRfkillManager *rfkill_mgr;
|
2008-01-02 13:42:52 +00:00
|
|
|
|
2016-07-01 12:11:01 +02:00
|
|
|
NMCheckpointManager *checkpoint_mgr;
|
|
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
NMSettings *settings;
|
2008-09-18 Dan Williams <dcbw@redhat.com>
Implement support for honoring configured and automatic hostnames, and for
setting the configured hostname.
* introspection/nm-ip4-config.xml
src/nm-ip4-config.c
src/nm-ip4-config.h
src/dhcp-manager/nm-dhcp-manager.c
- Remove useless hostname property; it's not really part of the IPv4
config
* introspection/nm-settings-system.xml
libnm-glib/nm-dbus-settings-system.c
libnm-glib/nm-dbus-settings-system.h
- Add SetHostname() call to system settings D-Bus interface
- Add Hostname property to system settings D-Bus interface
- (nm_dbus_settings_system_save_hostname,
nm_dbus_settings_system_get_hostname): implement
* src/nm-device.c
src/nm-device.h
- (nm_device_get_dhcp4_config): implement
* src/nm-manager.c
src/nm-manager.h
- Fetch and track system settings service hostname changes, and proxy
the changes via a GObject property of the manager
* system-settings/src/nm-system-config-interface.c
system-settings/src/nm-system-config-interface.h
- Replace nm_system_config_interface_supports_add() with a capabilities
bitfield
* system-settings/src/nm-system-config-error.c
system-settings/src/nm-system-config-error.h
- Add additional errors
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (get_property, nm_sysconfig_settings_class_init): add hostname
property; first plugin returning a hostname wins
- (impl_settings_add_connection): use plugin capabilities instead of
nm_system_config_interface_supports_add()
- (impl_settings_save_hostname): implement hostname saving
* src/NetworkManagerPolicy.c
- (lookup_thread_run_cb, lookup_thread_worker, lookup_thread_new,
lookup_thread_die): implement an asynchronous hostname lookup thread
which given an IPv4 address tries to look up the hostname for that
address with reverse DNS
- (get_best_device): split out best device code from
update_routing_and_dns()
- (update_etc_hosts): update /etc/hosts with the machine's new hostname
to preserve the 127.0.0.1 reverse mapping that so many things require
- (set_system_hostname): set a given hostname
- (update_system_hostname): implement hostname policy; a configured
hostname (from the system settings service) is used if available,
otherwise an automatically determined hostname from DHCP, VPN, etc.
If there was no automatically determined hostname, reverse DNS of
the best device's IP address will be used, and as a last resort the
hostname 'localhost.localdomain' is set.
- (update_routing_and_dns): use get_best_device(); update the system
hostname when the network config changes
- (hostname_changed): update system hostname if the system settings
service signals a hostname change
- (nm_policy_new): list for system settings service hostname changes
- (nm_policy_destroy): ensure that an in-progress hostname lookup thread
gets told to die
* system-settings/plugins/keyfile/plugin.c
system-settings/plugins/ifcfg-suse/plugin.c
- (get_property, sc_plugin_ifcfg_class_init): implement hostname and
capabilities properties
* system-settings/plugins/ifcfg-fedora/shvar.c
- (svOpenFile): re-enable R/W access of ifcfg files since the plugin
writes out /etc/sysconfig/network now
* system-settings/plugins/ifcfg-fedora/plugin.c
- (plugin_get_hostname): get hostname from /etc/sysconfig/network
- (plugin_set_hostname): save hostname to /etc/sysconfig/network
- (sc_network_changed_cb): handle changes to /etc/sysconfig/network
- (sc_plugin_ifcfg_init): monitor /etc/sysconfig/network for changes
- (get_property, set_property, sc_plugin_ifcfg_class_init): implement
hostname get/set and capabilities get
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4077 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-09-18 15:16:44 +00:00
|
|
|
char *hostname;
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2009-12-23 00:03:45 -08:00
|
|
|
RadioState radio_states[RFKILL_TYPE_MAX];
|
2007-02-08 15:34:26 +00:00
|
|
|
gboolean sleeping;
|
2010-05-22 08:55:30 -07:00
|
|
|
gboolean net_enabled;
|
2008-02-06 16:50:43 +00:00
|
|
|
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
NMVpnManager *vpn_manager;
|
2008-03-26 13:43:01 +00:00
|
|
|
|
2012-10-09 00:36:35 -04:00
|
|
|
NMSleepMonitor *sleep_monitor;
|
2008-07-09 14:05:49 +00:00
|
|
|
|
2016-07-01 14:25:34 +02:00
|
|
|
NMAuthManager *auth_mgr;
|
|
|
|
|
|
2010-05-28 18:23:00 -07:00
|
|
|
GSList *auth_chains;
|
2016-05-05 14:14:40 +02:00
|
|
|
GHashTable *sleep_devices;
|
2010-05-28 18:23:00 -07:00
|
|
|
|
2010-07-01 10:32:11 -07:00
|
|
|
/* Firmware dir monitor */
|
|
|
|
|
GFileMonitor *fw_monitor;
|
|
|
|
|
guint fw_changed_id;
|
|
|
|
|
|
2010-10-19 11:10:17 +02:00
|
|
|
guint timestamp_update_id;
|
|
|
|
|
|
2013-08-13 17:45:34 -04:00
|
|
|
gboolean startup;
|
2015-08-25 13:32:53 +02:00
|
|
|
gboolean devices_inited;
|
2007-02-08 15:34:26 +00:00
|
|
|
} NMManagerPrivate;
|
|
|
|
|
|
2016-04-28 14:03:32 +02:00
|
|
|
struct _NMManager {
|
|
|
|
|
NMExportedObject parent;
|
2016-07-01 15:23:29 +02:00
|
|
|
NMManagerPrivate _priv;
|
2016-04-28 14:03:32 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
NMExportedObjectClass parent;
|
|
|
|
|
} NMManagerClass;
|
|
|
|
|
|
2015-04-13 13:31:42 -04:00
|
|
|
G_DEFINE_TYPE (NMManager, nm_manager, NM_TYPE_EXPORTED_OBJECT)
|
2007-02-08 15:34:26 +00:00
|
|
|
|
2016-09-05 16:55:07 +02:00
|
|
|
#define NM_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMManager, NM_IS_MANAGER)
|
|
|
|
|
|
2007-02-08 15:34:26 +00:00
|
|
|
enum {
|
|
|
|
|
DEVICE_ADDED,
|
2014-10-06 11:21:54 -05:00
|
|
|
INTERNAL_DEVICE_ADDED,
|
2007-02-08 15:34:26 +00:00
|
|
|
DEVICE_REMOVED,
|
2014-10-06 11:21:54 -05:00
|
|
|
INTERNAL_DEVICE_REMOVED,
|
2008-03-07 23:17:48 +00:00
|
|
|
STATE_CHANGED,
|
2010-05-28 18:23:00 -07:00
|
|
|
CHECK_PERMISSIONS,
|
2012-08-22 18:33:17 -05:00
|
|
|
ACTIVE_CONNECTION_ADDED,
|
|
|
|
|
ACTIVE_CONNECTION_REMOVED,
|
2014-10-29 09:12:18 -05:00
|
|
|
CONFIGURE_QUIT,
|
2007-02-08 15:34:26 +00:00
|
|
|
|
|
|
|
|
LAST_SIGNAL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static guint signals[LAST_SIGNAL] = { 0 };
|
|
|
|
|
|
2016-04-01 17:34:51 +02:00
|
|
|
NM_GOBJECT_PROPERTIES_DEFINE (NMManager,
|
2010-09-27 10:34:56 +02:00
|
|
|
PROP_VERSION,
|
2016-09-15 23:34:24 +03:00
|
|
|
PROP_CAPABILITIES,
|
2007-02-08 15:34:26 +00:00
|
|
|
PROP_STATE,
|
2013-08-13 17:45:34 -04:00
|
|
|
PROP_STARTUP,
|
2010-05-22 08:55:30 -07:00
|
|
|
PROP_NETWORKING_ENABLED,
|
2007-02-08 15:34:26 +00:00
|
|
|
PROP_WIRELESS_ENABLED,
|
2007-10-15 14:46:37 +00:00
|
|
|
PROP_WIRELESS_HARDWARE_ENABLED,
|
2009-12-23 00:18:18 -08:00
|
|
|
PROP_WWAN_ENABLED,
|
|
|
|
|
PROP_WWAN_HARDWARE_ENABLED,
|
2009-12-29 11:27:10 +02:00
|
|
|
PROP_WIMAX_ENABLED,
|
|
|
|
|
PROP_WIMAX_HARDWARE_ENABLED,
|
2008-03-20 19:56:12 +00:00
|
|
|
PROP_ACTIVE_CONNECTIONS,
|
2013-07-30 16:31:31 -04:00
|
|
|
PROP_CONNECTIVITY,
|
2013-08-22 13:06:51 -04:00
|
|
|
PROP_PRIMARY_CONNECTION,
|
2014-10-23 13:56:52 -04:00
|
|
|
PROP_PRIMARY_CONNECTION_TYPE,
|
2013-08-22 13:06:51 -04:00
|
|
|
PROP_ACTIVATING_CONNECTION,
|
2014-01-08 12:18:33 -06:00
|
|
|
PROP_DEVICES,
|
2015-06-03 09:15:24 +02:00
|
|
|
PROP_METERED,
|
2015-07-03 11:06:39 +02:00
|
|
|
PROP_GLOBAL_DNS_CONFIGURATION,
|
2014-10-06 11:21:54 -05:00
|
|
|
PROP_ALL_DEVICES,
|
2007-02-08 15:34:26 +00:00
|
|
|
|
2008-09-18 Dan Williams <dcbw@redhat.com>
Implement support for honoring configured and automatic hostnames, and for
setting the configured hostname.
* introspection/nm-ip4-config.xml
src/nm-ip4-config.c
src/nm-ip4-config.h
src/dhcp-manager/nm-dhcp-manager.c
- Remove useless hostname property; it's not really part of the IPv4
config
* introspection/nm-settings-system.xml
libnm-glib/nm-dbus-settings-system.c
libnm-glib/nm-dbus-settings-system.h
- Add SetHostname() call to system settings D-Bus interface
- Add Hostname property to system settings D-Bus interface
- (nm_dbus_settings_system_save_hostname,
nm_dbus_settings_system_get_hostname): implement
* src/nm-device.c
src/nm-device.h
- (nm_device_get_dhcp4_config): implement
* src/nm-manager.c
src/nm-manager.h
- Fetch and track system settings service hostname changes, and proxy
the changes via a GObject property of the manager
* system-settings/src/nm-system-config-interface.c
system-settings/src/nm-system-config-interface.h
- Replace nm_system_config_interface_supports_add() with a capabilities
bitfield
* system-settings/src/nm-system-config-error.c
system-settings/src/nm-system-config-error.h
- Add additional errors
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (get_property, nm_sysconfig_settings_class_init): add hostname
property; first plugin returning a hostname wins
- (impl_settings_add_connection): use plugin capabilities instead of
nm_system_config_interface_supports_add()
- (impl_settings_save_hostname): implement hostname saving
* src/NetworkManagerPolicy.c
- (lookup_thread_run_cb, lookup_thread_worker, lookup_thread_new,
lookup_thread_die): implement an asynchronous hostname lookup thread
which given an IPv4 address tries to look up the hostname for that
address with reverse DNS
- (get_best_device): split out best device code from
update_routing_and_dns()
- (update_etc_hosts): update /etc/hosts with the machine's new hostname
to preserve the 127.0.0.1 reverse mapping that so many things require
- (set_system_hostname): set a given hostname
- (update_system_hostname): implement hostname policy; a configured
hostname (from the system settings service) is used if available,
otherwise an automatically determined hostname from DHCP, VPN, etc.
If there was no automatically determined hostname, reverse DNS of
the best device's IP address will be used, and as a last resort the
hostname 'localhost.localdomain' is set.
- (update_routing_and_dns): use get_best_device(); update the system
hostname when the network config changes
- (hostname_changed): update system hostname if the system settings
service signals a hostname change
- (nm_policy_new): list for system settings service hostname changes
- (nm_policy_destroy): ensure that an in-progress hostname lookup thread
gets told to die
* system-settings/plugins/keyfile/plugin.c
system-settings/plugins/ifcfg-suse/plugin.c
- (get_property, sc_plugin_ifcfg_class_init): implement hostname and
capabilities properties
* system-settings/plugins/ifcfg-fedora/shvar.c
- (svOpenFile): re-enable R/W access of ifcfg files since the plugin
writes out /etc/sysconfig/network now
* system-settings/plugins/ifcfg-fedora/plugin.c
- (plugin_get_hostname): get hostname from /etc/sysconfig/network
- (plugin_set_hostname): save hostname to /etc/sysconfig/network
- (sc_network_changed_cb): handle changes to /etc/sysconfig/network
- (sc_plugin_ifcfg_init): monitor /etc/sysconfig/network for changes
- (get_property, set_property, sc_plugin_ifcfg_class_init): implement
hostname get/set and capabilities get
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4077 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-09-18 15:16:44 +00:00
|
|
|
/* Not exported */
|
|
|
|
|
PROP_HOSTNAME,
|
2009-10-20 15:25:04 -07:00
|
|
|
PROP_SLEEPING,
|
2016-04-01 17:34:51 +02:00
|
|
|
);
|
2007-02-08 15:34:26 +00:00
|
|
|
|
2016-01-18 14:04:56 +01:00
|
|
|
NM_DEFINE_SINGLETON_INSTANCE (NMManager);
|
|
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
|
|
|
|
|
|
#define _NMLOG_PREFIX_NAME "manager"
|
2016-03-02 11:38:26 +01:00
|
|
|
#define _NMLOG(level, domain, ...) \
|
2016-01-18 14:04:56 +01:00
|
|
|
G_STMT_START { \
|
2016-03-02 11:38:26 +01:00
|
|
|
const NMLogLevel __level = (level); \
|
|
|
|
|
const NMLogDomain __domain = (domain); \
|
2016-01-18 14:04:56 +01:00
|
|
|
\
|
2016-03-02 11:38:26 +01:00
|
|
|
if (nm_logging_enabled (__level, __domain)) { \
|
|
|
|
|
const NMManager *const __self = (self); \
|
|
|
|
|
char __sbuf[32]; \
|
|
|
|
|
\
|
|
|
|
|
_nm_log (__level, __domain, 0, \
|
|
|
|
|
"%s%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
|
|
|
|
|
_NMLOG_PREFIX_NAME, \
|
|
|
|
|
(__self && __self != singleton_instance) \
|
|
|
|
|
? nm_sprintf_buf (__sbuf, "[%p]", __self) \
|
|
|
|
|
: "" \
|
|
|
|
|
_NM_UTILS_MACRO_REST (__VA_ARGS__)); \
|
|
|
|
|
} \
|
2016-01-18 14:04:56 +01:00
|
|
|
} G_STMT_END
|
2011-01-10 23:39:12 -06:00
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
|
|
2012-08-22 17:11:31 -05:00
|
|
|
static void active_connection_state_changed (NMActiveConnection *active,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMManager *self);
|
2014-06-06 15:30:24 -04:00
|
|
|
static void active_connection_default_changed (NMActiveConnection *active,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMManager *self);
|
2016-03-24 15:20:44 +01:00
|
|
|
static void active_connection_parent_active (NMActiveConnection *active,
|
|
|
|
|
NMActiveConnection *parent_ac,
|
|
|
|
|
NMManager *self);
|
2012-08-22 17:11:31 -05:00
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
/* Returns: whether to notify D-Bus of the removal or not */
|
|
|
|
|
static gboolean
|
|
|
|
|
active_connection_remove (NMManager *self, NMActiveConnection *active)
|
2013-08-30 17:57:56 -05:00
|
|
|
{
|
2013-08-28 16:19:20 -05:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2015-04-03 10:08:52 -04:00
|
|
|
gboolean notify = nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active));
|
2014-02-26 16:04:45 -06:00
|
|
|
GSList *found;
|
2013-08-28 16:19:20 -05:00
|
|
|
|
2014-02-26 16:04:45 -06:00
|
|
|
/* FIXME: switch to a GList for faster removal */
|
|
|
|
|
found = g_slist_find (priv->active_connections, active);
|
|
|
|
|
if (found) {
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *connection;
|
2014-06-20 20:13:14 +02:00
|
|
|
|
2014-02-26 16:04:45 -06:00
|
|
|
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);
|
2014-06-06 15:30:24 -04:00
|
|
|
g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self);
|
2016-03-24 15:20:44 +01:00
|
|
|
g_signal_handlers_disconnect_by_func (active, active_connection_parent_active, self);
|
2014-06-20 20:13:14 +02:00
|
|
|
|
|
|
|
|
if ( nm_active_connection_get_assumed (active)
|
2015-07-14 16:53:24 +02:00
|
|
|
&& (connection = nm_active_connection_get_settings_connection (active))
|
|
|
|
|
&& nm_settings_connection_get_nm_generated_assumed (connection))
|
2014-06-20 20:13:14 +02:00
|
|
|
g_object_ref (connection);
|
|
|
|
|
else
|
|
|
|
|
connection = NULL;
|
|
|
|
|
|
2015-07-23 10:03:21 -05:00
|
|
|
nm_exported_object_clear_and_unexport (&active);
|
2014-06-20 20:13:14 +02:00
|
|
|
|
manager: don't try to delete generated connection if it's already gone
Move the cleanup of the generated assumed connection to active connection
dispose. If the connection vanishes earlier (explicit deletion from client),
tear down the reference so that we don't try to remove it redundantly.
NetworkManager[9221]: <info> (eth2): device state change: deactivating -> disconnected (reason 'connection-removed') [110 30 38]
NetworkManager[9221]: <info> (eth2): deactivating device (reason 'connection-removed') [38]
(NetworkManager:9221): GLib-GObject-WARNING **: g_object_weak_unref: couldn't find weak ref 0x496610(0x7c2ba0)
Program received signal SIGTRAP, Trace/breakpoint trap.
g_logv (log_domain=0x7ffff4d4f1a4 "GLib-GObject", log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, args=args@entry=0x7fffffffd860) at gmessages.c:1046
1046 g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));
(gdb) bt
#0 0x00007ffff4a2cc60 in g_logv (log_domain=0x7ffff4d4f1a4 "GLib-GObject", log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, args=args@entry=0x7fffffffd860) at gmessages.c:1046
#1 0x00007ffff4a2ce9f in g_log (log_domain=<optimized out>, log_level=<optimized out>, format=<optimized out>) at gmessages.c:1079
#2 0x000000000049780b in nm_dbus_manager_unregister_object (self=0x7c2ba0 [NMDBusManager], object=0x80f3e0) at nm-dbus-manager.c:921
#3 0x000000000047cc83 in nm_settings_connection_signal_remove (self=self@entry=0x80f3e0 [NMIfcfgConnection]) at settings/nm-settings-connection.c:1752
#4 0x000000000047cd22 in do_delete (connection=0x80f3e0 [NMIfcfgConnection], callback=0x479d60 <ignore_cb>, user_data=0x0) at settings/nm-settings-connection.c:687
#5 0x00000000004b1eb6 in active_connection_remove (self=self@entry=0x8701c0 [NMManager], active=active@entry=0x8b02f0) at nm-manager.c:292
#6 0x00000000004b2174 in _active_connection_cleanup (user_data=<optimized out>) at nm-manager.c:316
#7 0x00007ffff4a25aeb in g_main_context_dispatch (context=0x7be3a0) at gmain.c:3111
#8 0x00007ffff4a25aeb in g_main_context_dispatch (context=context@entry=0x7be3a0) at gmain.c:3710
#9 0x00007ffff4a25e88 in g_main_context_iterate (context=0x7be3a0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3781
#10 0x00007ffff4a261b2 in g_main_loop_run (loop=0x7be460) at gmain.c:3975
#11 0x0000000000432f55 in main (argc=1, argv=0x7fffffffded8) at main.c:460
(gdb)
https://bugzilla.gnome.org/show_bug.cgi?id=744812
2015-04-22 15:05:18 +02:00
|
|
|
if ( connection
|
|
|
|
|
&& nm_settings_has_connection (priv->settings, connection)) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "assumed connection disconnected. Deleting generated connection '%s' (%s)",
|
|
|
|
|
nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
|
2014-06-20 20:13:14 +02:00
|
|
|
nm_settings_connection_delete (NM_SETTINGS_CONNECTION (connection), NULL, NULL);
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
}
|
2014-02-26 16:04:45 -06:00
|
|
|
}
|
2013-08-28 16:19:20 -05:00
|
|
|
|
2014-02-26 16:04:45 -06:00
|
|
|
return found && notify;
|
2013-08-30 17:57:56 -05:00
|
|
|
}
|
|
|
|
|
|
2012-08-22 17:11:31 -05:00
|
|
|
static gboolean
|
|
|
|
|
_active_connection_cleanup (gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
|
|
priv->ac_cleanup_id = 0;
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
g_object_freeze_notify (G_OBJECT (self));
|
2012-08-22 17:11:31 -05:00
|
|
|
iter = priv->active_connections;
|
|
|
|
|
while (iter) {
|
|
|
|
|
NMActiveConnection *ac = iter->data;
|
|
|
|
|
|
|
|
|
|
iter = iter->next;
|
|
|
|
|
if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
|
2013-08-28 16:19:20 -05:00
|
|
|
if (active_connection_remove (self, ac))
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_ACTIVE_CONNECTIONS);
|
2012-08-22 17:11:31 -05:00
|
|
|
}
|
|
|
|
|
}
|
2013-08-28 16:19:20 -05:00
|
|
|
g_object_thaw_notify (G_OBJECT (self));
|
2012-08-22 17:11:31 -05:00
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
active_connection_state_changed (NMActiveConnection *active,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
NMActiveConnectionState state;
|
|
|
|
|
|
|
|
|
|
state = nm_active_connection_get_state (active);
|
|
|
|
|
if (state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
|
|
|
|
|
/* Destroy active connections from an idle handler to ensure that
|
|
|
|
|
* their last property change notifications go out, which wouldn't
|
|
|
|
|
* happen if we destroyed them immediately when their state was set
|
|
|
|
|
* to DEACTIVATED.
|
|
|
|
|
*/
|
|
|
|
|
if (!priv->ac_cleanup_id)
|
|
|
|
|
priv->ac_cleanup_id = g_idle_add (_active_connection_cleanup, self);
|
|
|
|
|
}
|
2013-11-08 12:23:43 -05:00
|
|
|
|
|
|
|
|
nm_manager_update_state (self);
|
2012-08-22 17:11:31 -05:00
|
|
|
}
|
|
|
|
|
|
2014-06-06 15:30:24 -04:00
|
|
|
static void
|
|
|
|
|
active_connection_default_changed (NMActiveConnection *active,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
nm_manager_update_state (self);
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-26 16:04:45 -06:00
|
|
|
/**
|
|
|
|
|
* active_connection_add():
|
|
|
|
|
* @self: the #NMManager
|
|
|
|
|
* @active: the #NMActiveConnection to manage
|
|
|
|
|
*
|
|
|
|
|
* Begins to track and manage @active. Increases the refcount of @active.
|
|
|
|
|
*/
|
2012-08-22 17:11:31 -05:00
|
|
|
static void
|
|
|
|
|
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);
|
|
|
|
|
|
2014-02-26 16:04:45 -06:00
|
|
|
priv->active_connections = g_slist_prepend (priv->active_connections,
|
|
|
|
|
g_object_ref (active));
|
|
|
|
|
|
|
|
|
|
g_signal_connect (active,
|
|
|
|
|
"notify::" NM_ACTIVE_CONNECTION_STATE,
|
2012-08-22 17:11:31 -05:00
|
|
|
G_CALLBACK (active_connection_state_changed),
|
|
|
|
|
self);
|
2014-06-06 15:30:24 -04:00
|
|
|
g_signal_connect (active,
|
|
|
|
|
"notify::" NM_ACTIVE_CONNECTION_DEFAULT,
|
|
|
|
|
G_CALLBACK (active_connection_default_changed),
|
|
|
|
|
self);
|
|
|
|
|
g_signal_connect (active,
|
|
|
|
|
"notify::" NM_ACTIVE_CONNECTION_DEFAULT6,
|
|
|
|
|
G_CALLBACK (active_connection_default_changed),
|
|
|
|
|
self);
|
2012-08-22 18:33:17 -05:00
|
|
|
|
|
|
|
|
g_signal_emit (self, signals[ACTIVE_CONNECTION_ADDED], 0, active);
|
2013-08-28 16:19:20 -05:00
|
|
|
|
|
|
|
|
/* Only notify D-Bus if the active connection is actually exported */
|
2015-04-03 10:08:52 -04:00
|
|
|
if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active)))
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_ACTIVE_CONNECTIONS);
|
2012-08-22 17:11:31 -05:00
|
|
|
}
|
|
|
|
|
|
2012-08-22 17:21:56 -05:00
|
|
|
const GSList *
|
|
|
|
|
nm_manager_get_active_connections (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->active_connections;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-12 10:28:21 -04:00
|
|
|
static NMActiveConnection *
|
|
|
|
|
find_ac_for_connection (NMManager *manager, NMConnection *connection)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
GSList *iter;
|
2015-07-14 16:53:24 +02:00
|
|
|
const char *uuid = NULL;
|
|
|
|
|
gboolean is_settings_connection;
|
|
|
|
|
|
|
|
|
|
is_settings_connection = NM_IS_SETTINGS_CONNECTION (connection);
|
|
|
|
|
|
2015-09-30 12:10:39 +02:00
|
|
|
if (!is_settings_connection)
|
2015-07-14 16:53:24 +02:00
|
|
|
uuid = nm_connection_get_uuid (connection);
|
2013-09-12 10:28:21 -04:00
|
|
|
|
|
|
|
|
for (iter = priv->active_connections; iter; iter = iter->next) {
|
2015-07-14 16:53:24 +02:00
|
|
|
NMActiveConnection *ac = iter->data;
|
|
|
|
|
NMSettingsConnection *con;
|
2013-09-12 10:28:21 -04:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
con = nm_active_connection_get_settings_connection (ac);
|
|
|
|
|
|
|
|
|
|
/* depending on whether we have a NMSettingsConnection or a NMConnection,
|
|
|
|
|
* we lookup by UUID or by reference. */
|
|
|
|
|
if (is_settings_connection) {
|
|
|
|
|
if (con != (NMSettingsConnection *) connection)
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
if (strcmp (uuid, nm_connection_get_uuid (NM_CONNECTION (con))) != 0)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (nm_active_connection_get_state (ac) < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
|
2013-09-12 10:28:21 -04:00
|
|
|
return ac;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-29 14:59:48 +01:00
|
|
|
/* Filter out connections that are already active.
|
2016-05-16 19:24:23 +02:00
|
|
|
* nm_settings_get_connections_sorted() returns sorted list. We need to preserve the
|
2013-11-29 14:59:48 +01:00
|
|
|
* order so that we didn't change auto-activation order (recent timestamps
|
|
|
|
|
* are first).
|
|
|
|
|
* Caller is responsible for freeing the returned list with g_slist_free().
|
|
|
|
|
*/
|
2013-09-12 10:28:21 -04:00
|
|
|
GSList *
|
|
|
|
|
nm_manager_get_activatable_connections (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
2016-05-16 19:24:23 +02:00
|
|
|
GSList *all_connections = nm_settings_get_connections_sorted (priv->settings);
|
2013-09-12 10:28:21 -04:00
|
|
|
GSList *connections = NULL, *iter;
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *connection;
|
2013-09-12 10:28:21 -04:00
|
|
|
|
|
|
|
|
for (iter = all_connections; iter; iter = iter->next) {
|
|
|
|
|
connection = iter->data;
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
if (!find_ac_for_connection (manager, NM_CONNECTION (connection)))
|
2013-09-12 10:28:21 -04:00
|
|
|
connections = g_slist_prepend (connections, connection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_slist_free (all_connections);
|
2013-11-29 14:59:48 +01:00
|
|
|
return g_slist_reverse (connections);
|
2013-09-12 10:28:21 -04:00
|
|
|
}
|
|
|
|
|
|
2012-09-14 15:21:29 -05:00
|
|
|
static NMActiveConnection *
|
|
|
|
|
active_connection_get_by_path (NMManager *manager, const char *path)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (manager != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (path != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
for (iter = priv->active_connections; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
NMActiveConnection *candidate = iter->data;
|
|
|
|
|
|
2015-04-03 10:08:52 -04:00
|
|
|
if (g_strcmp0 (path, nm_exported_object_get_path (NM_EXPORTED_OBJECT (candidate))) == 0)
|
2012-09-14 15:21:29 -05:00
|
|
|
return candidate;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-22 17:11:31 -05:00
|
|
|
/************************************************************************/
|
|
|
|
|
|
2015-01-30 19:52:53 +01:00
|
|
|
static void
|
2015-01-21 12:58:32 +01:00
|
|
|
_config_changed_cb (NMConfig *config, NMConfigData *config_data, NMConfigChangeFlags changes, NMConfigData *old_data, NMManager *self)
|
2015-01-30 19:52:53 +01:00
|
|
|
{
|
|
|
|
|
g_object_set (NM_MANAGER_GET_PRIVATE (self)->connectivity,
|
|
|
|
|
NM_CONNECTIVITY_URI, nm_config_data_get_connectivity_uri (config_data),
|
|
|
|
|
NM_CONNECTIVITY_INTERVAL, nm_config_data_get_connectivity_interval (config_data),
|
|
|
|
|
NM_CONNECTIVITY_RESPONSE, nm_config_data_get_connectivity_response (config_data),
|
|
|
|
|
NULL);
|
2015-07-03 11:06:39 +02:00
|
|
|
|
|
|
|
|
if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_GLOBAL_DNS_CONFIG))
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_GLOBAL_DNS_CONFIGURATION);
|
2015-01-30 19:52:53 +01:00
|
|
|
}
|
|
|
|
|
|
2016-05-30 15:42:44 +02:00
|
|
|
static void
|
|
|
|
|
_reload_auth_cb (NMAuthChain *chain,
|
|
|
|
|
GError *error,
|
|
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
GError *ret_error = NULL;
|
|
|
|
|
NMAuthCallResult result;
|
|
|
|
|
guint32 flags;
|
|
|
|
|
NMAuthSubject *subject;
|
|
|
|
|
char s_buf[60];
|
2016-05-30 16:43:39 +02:00
|
|
|
NMConfigChangeFlags reload_type = NM_CONFIG_CHANGE_NONE;
|
2016-05-30 15:42:44 +02:00
|
|
|
|
|
|
|
|
g_assert (context);
|
|
|
|
|
|
|
|
|
|
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
|
|
|
|
|
flags = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "flags"));
|
|
|
|
|
|
|
|
|
|
subject = nm_auth_chain_get_subject (chain);
|
|
|
|
|
|
|
|
|
|
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_RELOAD);
|
|
|
|
|
if (error) {
|
|
|
|
|
_LOGD (LOGD_CORE, "Reload request failed: %s", error->message);
|
|
|
|
|
ret_error = g_error_new (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Reload request failed: %s",
|
|
|
|
|
error->message);
|
|
|
|
|
} else if (result != NM_AUTH_CALL_RESULT_YES) {
|
|
|
|
|
ret_error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Not authorized to reload configuration");
|
2016-05-30 16:43:39 +02:00
|
|
|
} else {
|
|
|
|
|
if (NM_FLAGS_ANY (flags, ~NM_MANAGER_RELOAD_FLAGS_ALL)) {
|
|
|
|
|
/* invalid flags */
|
|
|
|
|
} else if (flags == 0)
|
|
|
|
|
reload_type = NM_CONFIG_CHANGE_CAUSE_SIGHUP;
|
|
|
|
|
else {
|
|
|
|
|
if (NM_FLAGS_HAS (flags, NM_MANAGER_RELOAD_FLAGS_CONF))
|
|
|
|
|
reload_type |= NM_CONFIG_CHANGE_CAUSE_CONF;
|
|
|
|
|
if (NM_FLAGS_HAS (flags, NM_MANAGER_RELOAD_FLAGS_DNS_RC))
|
|
|
|
|
reload_type |= NM_CONFIG_CHANGE_CAUSE_DNS_RC;
|
|
|
|
|
if (NM_FLAGS_HAS (flags, NM_MANAGER_RELOAD_FLAGS_DNS_FULL))
|
|
|
|
|
reload_type |= NM_CONFIG_CHANGE_CAUSE_DNS_FULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (reload_type == NM_CONFIG_CHANGE_NONE) {
|
|
|
|
|
ret_error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_INVALID_ARGUMENTS,
|
|
|
|
|
"Invalid flags for reload");
|
|
|
|
|
}
|
2016-05-30 15:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_audit_log_control_op (NM_AUDIT_OP_RELOAD,
|
|
|
|
|
nm_sprintf_buf (s_buf, "%u", flags),
|
|
|
|
|
ret_error == NULL, subject,
|
|
|
|
|
ret_error ? ret_error->message : NULL);
|
|
|
|
|
|
|
|
|
|
if (ret_error) {
|
|
|
|
|
g_dbus_method_invocation_take_error (context, ret_error);
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-30 16:43:39 +02:00
|
|
|
nm_config_reload (priv->config, reload_type);
|
2016-05-30 15:42:44 +02:00
|
|
|
g_dbus_method_invocation_return_value (context, NULL);
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
nm_auth_chain_unref (chain);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
impl_manager_reload (NMManager *self,
|
|
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
guint32 flags)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv;
|
|
|
|
|
NMAuthChain *chain;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (self));
|
|
|
|
|
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
chain = nm_auth_chain_new_context (context, _reload_auth_cb, self);
|
|
|
|
|
if (!chain) {
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Unable to authenticate request");
|
|
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
|
|
|
|
nm_auth_chain_set_data (chain, "flags", GUINT_TO_POINTER (flags), NULL);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_RELOAD, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-30 19:52:53 +01:00
|
|
|
/************************************************************************/
|
|
|
|
|
|
2016-07-01 12:11:01 +02:00
|
|
|
NMDevice *
|
2011-01-10 23:39:12 -06:00
|
|
|
nm_manager_get_device_by_path (NMManager *manager, const char *path)
|
|
|
|
|
{
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
2011-03-15 17:04:35 -05:00
|
|
|
g_return_val_if_fail (path != NULL, NULL);
|
|
|
|
|
|
2011-01-10 23:39:12 -06:00
|
|
|
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
|
2015-04-03 10:08:52 -04:00
|
|
|
if (!strcmp (nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data)), path))
|
2011-01-10 23:39:12 -06:00
|
|
|
return NM_DEVICE (iter->data);
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-03 13:55:51 -04:00
|
|
|
NMDevice *
|
|
|
|
|
nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex)
|
|
|
|
|
{
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
|
|
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
|
|
|
|
|
NMDevice *device = NM_DEVICE (iter->data);
|
|
|
|
|
|
|
|
|
|
if (nm_device_get_ifindex (device) == ifindex)
|
|
|
|
|
return device;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-29 10:56:36 +02:00
|
|
|
static NMDevice *
|
2016-06-15 13:43:34 +02:00
|
|
|
find_device_by_permanent_hw_addr (NMManager *manager, const char *hwaddr)
|
2015-04-29 10:56:36 +02:00
|
|
|
{
|
|
|
|
|
GSList *iter;
|
2014-09-18 17:50:47 -05:00
|
|
|
const char *device_addr;
|
2015-04-29 10:56:36 +02:00
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
g_return_val_if_fail (hwaddr != NULL, NULL);
|
2015-04-29 10:56:36 +02:00
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
if (nm_utils_hwaddr_valid (hwaddr, -1)) {
|
|
|
|
|
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
|
2016-06-15 13:43:34 +02:00
|
|
|
device_addr = nm_device_get_permanent_hw_address (NM_DEVICE (iter->data), FALSE);
|
2014-09-18 17:50:47 -05:00
|
|
|
if (device_addr && nm_utils_hwaddr_matches (hwaddr, -1, device_addr, -1))
|
|
|
|
|
return NM_DEVICE (iter->data);
|
|
|
|
|
}
|
2015-04-29 10:56:36 +02:00
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMDevice *
|
|
|
|
|
find_device_by_ip_iface (NMManager *self, const gchar *iface)
|
|
|
|
|
{
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
g_return_val_if_fail (iface != NULL, NULL);
|
2015-04-29 10:56:36 +02:00
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = g_slist_next (iter)) {
|
2014-09-24 16:58:07 -05:00
|
|
|
NMDevice *candidate = iter->data;
|
|
|
|
|
|
|
|
|
|
if ( nm_device_is_real (candidate)
|
|
|
|
|
&& g_strcmp0 (nm_device_get_ip_iface (candidate), iface) == 0)
|
|
|
|
|
return candidate;
|
2015-04-29 10:56:36 +02:00
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-15 21:17:45 -05:00
|
|
|
/**
|
|
|
|
|
* find_device_by_iface:
|
|
|
|
|
* @self: the #NMManager
|
|
|
|
|
* @iface: the device interface to find
|
|
|
|
|
* @connection: a connection to ensure the returned device is compatible with
|
|
|
|
|
* @slave: a slave connection to ensure a master is compatible with
|
|
|
|
|
*
|
|
|
|
|
* Finds a device by interface name, preferring realized devices. If @slave
|
|
|
|
|
* is given, this function will only return master devices and will ensure
|
|
|
|
|
* @slave, when activated, can be a slave of the returned master device. If
|
|
|
|
|
* @connection is given, this function will only consider devices that are
|
|
|
|
|
* compatible with @connection.
|
|
|
|
|
*
|
|
|
|
|
* Returns: the matching #NMDevice
|
|
|
|
|
*/
|
2014-09-24 14:57:14 -05:00
|
|
|
static NMDevice *
|
2014-10-15 21:17:45 -05:00
|
|
|
find_device_by_iface (NMManager *self,
|
|
|
|
|
const char *iface,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
NMConnection *slave)
|
2014-09-24 14:57:14 -05:00
|
|
|
{
|
2014-10-15 21:17:45 -05:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
NMDevice *fallback = NULL;
|
2014-09-24 14:57:14 -05:00
|
|
|
GSList *iter;
|
|
|
|
|
|
2014-10-15 21:17:45 -05:00
|
|
|
g_return_val_if_fail (iface != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
for (iter = priv->devices; iter; iter = iter->next) {
|
|
|
|
|
NMDevice *candidate = iter->data;
|
|
|
|
|
|
|
|
|
|
if (strcmp (nm_device_get_iface (candidate), iface))
|
|
|
|
|
continue;
|
|
|
|
|
if (connection && !nm_device_check_connection_compatible (candidate, connection))
|
|
|
|
|
continue;
|
|
|
|
|
if (slave) {
|
|
|
|
|
if (!nm_device_is_master (candidate))
|
|
|
|
|
continue;
|
|
|
|
|
if (!nm_device_check_slave_connection_compatible (candidate, slave))
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nm_device_is_real (candidate))
|
|
|
|
|
return candidate;
|
|
|
|
|
else if (!fallback)
|
|
|
|
|
fallback = candidate;
|
2014-09-24 14:57:14 -05:00
|
|
|
}
|
2014-10-15 21:17:45 -05:00
|
|
|
return fallback;
|
2014-09-24 14:57:14 -05:00
|
|
|
}
|
|
|
|
|
|
2010-05-22 08:55:30 -07:00
|
|
|
static gboolean
|
|
|
|
|
manager_sleeping (NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->sleeping || !priv->net_enabled)
|
|
|
|
|
return TRUE;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-15 17:55:17 +02:00
|
|
|
static const char *
|
|
|
|
|
_nm_state_to_string (NMState state)
|
2013-07-31 09:14:39 -04:00
|
|
|
{
|
|
|
|
|
switch (state) {
|
|
|
|
|
case NM_STATE_ASLEEP:
|
2014-04-15 17:55:17 +02:00
|
|
|
return "ASLEEP";
|
2013-07-31 09:14:39 -04:00
|
|
|
case NM_STATE_DISCONNECTED:
|
2014-04-15 17:55:17 +02:00
|
|
|
return "DISCONNECTED";
|
2013-07-31 09:14:39 -04:00
|
|
|
case NM_STATE_DISCONNECTING:
|
2014-04-15 17:55:17 +02:00
|
|
|
return "DISCONNECTING";
|
2013-07-31 09:14:39 -04:00
|
|
|
case NM_STATE_CONNECTING:
|
2014-04-15 17:55:17 +02:00
|
|
|
return "CONNECTING";
|
2013-07-31 09:14:39 -04:00
|
|
|
case NM_STATE_CONNECTED_LOCAL:
|
2014-04-15 17:55:17 +02:00
|
|
|
return "CONNECTED_LOCAL";
|
2013-07-31 09:14:39 -04:00
|
|
|
case NM_STATE_CONNECTED_SITE:
|
2014-04-15 17:55:17 +02:00
|
|
|
return "CONNECTED_SITE";
|
2013-07-31 09:14:39 -04:00
|
|
|
case NM_STATE_CONNECTED_GLOBAL:
|
2014-04-15 17:55:17 +02:00
|
|
|
return "CONNECTED_GLOBAL";
|
2013-07-31 09:14:39 -04:00
|
|
|
case NM_STATE_UNKNOWN:
|
|
|
|
|
default:
|
2014-04-15 17:55:17 +02:00
|
|
|
return "UNKNOWN";
|
2013-07-31 09:14:39 -04:00
|
|
|
}
|
2014-04-15 17:55:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2016-03-02 11:38:26 +01:00
|
|
|
set_state (NMManager *self, NMState state)
|
2014-04-15 17:55:17 +02:00
|
|
|
{
|
2016-03-02 11:38:26 +01:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2014-04-15 17:55:17 +02:00
|
|
|
|
|
|
|
|
if (priv->state == state)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
priv->state = state;
|
2013-07-31 09:14:39 -04:00
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_CORE, "NetworkManager state is now %s", _nm_state_to_string (state));
|
2013-07-31 09:14:39 -04:00
|
|
|
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_STATE);
|
2016-03-02 11:38:26 +01:00
|
|
|
g_signal_emit (self, signals[STATE_CHANGED], 0, priv->state);
|
2013-07-31 09:14:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
checked_connectivity (GObject *object, GAsyncResult *result, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *manager = user_data;
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
2013-07-30 16:31:31 -04:00
|
|
|
NMConnectivityState connectivity;
|
2013-07-31 09:14:39 -04:00
|
|
|
|
|
|
|
|
if (priv->state == NM_STATE_CONNECTING || priv->state == NM_STATE_CONNECTED_SITE) {
|
2013-07-30 16:31:31 -04:00
|
|
|
connectivity = nm_connectivity_check_finish (priv->connectivity, result, NULL);
|
|
|
|
|
|
|
|
|
|
if (connectivity == NM_CONNECTIVITY_FULL)
|
2013-07-31 09:14:39 -04:00
|
|
|
set_state (manager, NM_STATE_CONNECTED_GLOBAL);
|
2013-07-30 16:31:31 -04:00
|
|
|
else if ( connectivity == NM_CONNECTIVITY_PORTAL
|
|
|
|
|
|| connectivity == NM_CONNECTIVITY_LIMITED)
|
2013-07-31 09:14:39 -04:00
|
|
|
set_state (manager, NM_STATE_CONNECTED_SITE);
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (manager, PROP_CONNECTIVITY);
|
2013-07-31 09:14:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_object_unref (manager);
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-08 12:23:43 -05:00
|
|
|
static NMState
|
2015-01-13 14:48:29 -05:00
|
|
|
find_best_device_state (NMManager *manager)
|
2013-11-08 12:23:43 -05:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
NMState best_state = NM_STATE_DISCONNECTED;
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
|
|
for (iter = priv->active_connections; iter; iter = iter->next) {
|
|
|
|
|
NMActiveConnection *ac = NM_ACTIVE_CONNECTION (iter->data);
|
|
|
|
|
NMActiveConnectionState ac_state = nm_active_connection_get_state (ac);
|
|
|
|
|
|
|
|
|
|
switch (ac_state) {
|
|
|
|
|
case NM_ACTIVE_CONNECTION_STATE_ACTIVATED:
|
|
|
|
|
if ( nm_active_connection_get_default (ac)
|
|
|
|
|
|| nm_active_connection_get_default6 (ac)) {
|
2015-01-13 14:48:29 -05:00
|
|
|
if (nm_connectivity_get_state (priv->connectivity) == NM_CONNECTIVITY_FULL)
|
2013-11-08 12:23:43 -05:00
|
|
|
return NM_STATE_CONNECTED_GLOBAL;
|
|
|
|
|
|
2015-01-13 14:48:29 -05:00
|
|
|
best_state = NM_STATE_CONNECTED_SITE;
|
2013-11-08 12:23:43 -05:00
|
|
|
} else {
|
|
|
|
|
if (best_state < NM_STATE_CONNECTING)
|
|
|
|
|
best_state = NM_STATE_CONNECTED_LOCAL;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case NM_ACTIVE_CONNECTION_STATE_ACTIVATING:
|
|
|
|
|
if (!nm_active_connection_get_assumed (ac)) {
|
|
|
|
|
if (best_state != NM_STATE_CONNECTED_GLOBAL)
|
|
|
|
|
best_state = NM_STATE_CONNECTING;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case NM_ACTIVE_CONNECTION_STATE_DEACTIVATING:
|
|
|
|
|
if (!nm_active_connection_get_assumed (ac)) {
|
|
|
|
|
if (best_state < NM_STATE_DISCONNECTING)
|
|
|
|
|
best_state = NM_STATE_DISCONNECTING;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return best_state;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-03 09:15:24 +02:00
|
|
|
static void
|
2016-03-02 11:38:26 +01:00
|
|
|
nm_manager_update_metered (NMManager *self)
|
2015-06-03 09:15:24 +02:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv;
|
|
|
|
|
NMDevice *device;
|
|
|
|
|
NMMetered value = NM_METERED_UNKNOWN;
|
|
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
g_return_if_fail (NM_IS_MANAGER (self));
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (self);
|
2015-06-03 09:15:24 +02:00
|
|
|
|
|
|
|
|
if (priv->primary_connection) {
|
|
|
|
|
device = nm_active_connection_get_device (priv->primary_connection);
|
|
|
|
|
if (device)
|
|
|
|
|
value = nm_device_get_metered (device);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (value != priv->metered) {
|
|
|
|
|
priv->metered = value;
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "new metered value: %d", (int) priv->metered);
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_METERED);
|
2015-06-03 09:15:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-20 12:02:18 -04:00
|
|
|
static void
|
|
|
|
|
nm_manager_update_state (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv;
|
|
|
|
|
NMState new_state = NM_STATE_DISCONNECTED;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
|
|
|
|
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
|
2010-05-22 08:55:30 -07:00
|
|
|
if (manager_sleeping (manager))
|
2009-05-20 12:02:18 -04:00
|
|
|
new_state = NM_STATE_ASLEEP;
|
2013-11-08 12:23:43 -05:00
|
|
|
else
|
2015-01-13 14:48:29 -05:00
|
|
|
new_state = find_best_device_state (manager);
|
2009-05-20 12:02:18 -04:00
|
|
|
|
2015-01-13 15:35:10 -05:00
|
|
|
nm_connectivity_set_online (priv->connectivity, new_state >= NM_STATE_CONNECTED_LOCAL);
|
|
|
|
|
|
2015-01-13 14:48:29 -05:00
|
|
|
if (new_state == NM_STATE_CONNECTED_SITE) {
|
2013-07-31 09:14:39 -04:00
|
|
|
nm_connectivity_check_async (priv->connectivity,
|
|
|
|
|
checked_connectivity,
|
|
|
|
|
g_object_ref (manager));
|
2015-01-13 15:35:10 -05:00
|
|
|
}
|
2013-07-31 09:14:39 -04:00
|
|
|
|
|
|
|
|
set_state (manager, new_state);
|
2009-05-20 12:02:18 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
manager_device_state_changed (NMDevice *device,
|
|
|
|
|
NMDeviceState new_state,
|
|
|
|
|
NMDeviceState old_state,
|
|
|
|
|
NMDeviceStateReason reason,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2011-12-14 13:41:57 -06:00
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
2015-12-13 22:08:23 +01:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2009-05-20 12:02:18 -04:00
|
|
|
|
|
|
|
|
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:
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_ACTIVE_CONNECTIONS);
|
2009-05-20 12:02:18 -04:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-12-13 22:08:23 +01:00
|
|
|
|
|
|
|
|
if ( new_state == NM_DEVICE_STATE_UNAVAILABLE
|
|
|
|
|
|| new_state == NM_DEVICE_STATE_DISCONNECTED)
|
|
|
|
|
nm_settings_device_added (priv->settings, device);
|
2009-05-20 12:02:18 -04:00
|
|
|
}
|
|
|
|
|
|
2013-08-13 17:45:34 -04:00
|
|
|
static void device_has_pending_action_changed (NMDevice *device,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMManager *self);
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
check_if_startup_complete (NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
|
|
if (!priv->startup)
|
|
|
|
|
return;
|
|
|
|
|
|
2015-08-25 13:32:53 +02:00
|
|
|
if (!priv->devices_inited)
|
|
|
|
|
return;
|
|
|
|
|
|
2014-12-18 16:04:07 -05:00
|
|
|
if (!nm_settings_get_startup_complete (priv->settings)) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "check_if_startup_complete returns FALSE because of NMSettings");
|
2014-12-18 16:04:07 -05:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-13 17:45:34 -04:00
|
|
|
for (iter = priv->devices; iter; iter = iter->next) {
|
|
|
|
|
NMDevice *dev = iter->data;
|
|
|
|
|
|
|
|
|
|
if (nm_device_has_pending_action (dev)) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "check_if_startup_complete returns FALSE because of %s",
|
|
|
|
|
nm_device_get_iface (dev));
|
2013-08-13 17:45:34 -04:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_CORE, "startup complete");
|
2013-08-13 17:45:34 -04:00
|
|
|
|
|
|
|
|
priv->startup = FALSE;
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_STARTUP);
|
2013-08-13 17:45:34 -04:00
|
|
|
|
|
|
|
|
/* We don't have to watch notify::has-pending-action any more. */
|
|
|
|
|
for (iter = priv->devices; iter; iter = iter->next) {
|
|
|
|
|
NMDevice *dev = iter->data;
|
|
|
|
|
|
|
|
|
|
g_signal_handlers_disconnect_by_func (dev, G_CALLBACK (device_has_pending_action_changed), self);
|
|
|
|
|
}
|
2014-10-29 09:12:18 -05:00
|
|
|
|
2016-07-01 14:30:00 +02:00
|
|
|
if (nm_config_get_configure_and_quit (priv->config))
|
2014-10-29 09:12:18 -05:00
|
|
|
g_signal_emit (self, signals[CONFIGURE_QUIT], 0);
|
2013-08-13 17:45:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
device_has_pending_action_changed (NMDevice *device,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
check_if_startup_complete (self);
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-18 16:04:07 -05:00
|
|
|
static void
|
|
|
|
|
settings_startup_complete_changed (NMSettings *settings,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
check_if_startup_complete (self);
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-15 12:58:22 -04:00
|
|
|
static void
|
2016-03-02 11:38:26 +01:00
|
|
|
remove_device (NMManager *self,
|
2014-10-13 11:58:26 -05:00
|
|
|
NMDevice *device,
|
|
|
|
|
gboolean quitting,
|
|
|
|
|
gboolean allow_unmanage)
|
2009-05-20 12:02:18 -04:00
|
|
|
{
|
2016-03-02 11:38:26 +01:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2016-04-20 17:46:41 +02:00
|
|
|
gboolean unmanage = FALSE;
|
2009-07-09 11:06:31 -04:00
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "(%s): removing device (allow_unmanage %d, managed %d)",
|
|
|
|
|
nm_device_get_iface (device), allow_unmanage, nm_device_get_managed (device, FALSE));
|
2014-12-18 10:23:06 -06:00
|
|
|
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
if (allow_unmanage && nm_device_get_managed (device, FALSE)) {
|
2013-11-08 15:07:20 -06:00
|
|
|
|
2016-06-21 11:04:38 +02:00
|
|
|
if (quitting)
|
|
|
|
|
unmanage = nm_device_unmanage_on_quit (device);
|
|
|
|
|
else {
|
2016-04-01 11:04:34 +02:00
|
|
|
/* the device is already gone. Unmanage it. */
|
2016-06-21 11:04:38 +02:00
|
|
|
unmanage = TRUE;
|
2016-04-01 11:04:34 +02:00
|
|
|
}
|
core: fix deactivation of assumed connections on device removal (bgo #729833)
The following procedure leaves an NMActiveConnection around for a deactivated
device, which causes errors in libnm-glib clients when they cannot create the
GObject for the non-existent device of the AC.
1) allow a device which can assume connections to be activated
2) stop NM, which should leave the device's IP configuration up
3) start NM and allow it to assume the device's existing connection
4) remove the device, either by unplugging it or 'rmmod'
The device is removed by nm-manager.c::remove_device(), but the device object
is not moved to UNMANAGED state, leaving the NMActiveConnection completely
unaware the device has gone away.
The nm-manager.c::remove_device() code did not correctly handle moving a
forcibly removed (eg, by unplugging or 'ip link del' or 'rmmod') device to
the UNMANAGED state when the device was active with an assumed connection.
To fix this, make the conditions when the device should be deactivated
on removal much more explicit.
A device should be deactivated on removal if:
1) it is forcibly removed, eg by the kernel network interface being
removed due to 'ip link del' or hotplugging, or internally by NM due
to a parent WWAN interface taking priority over a WWAN ethernet interface
2) if the device cannot assume connections, in which case NetworkManager
must have activated the device and since we cannot assume the connection
on restart, we should deactivate it
3) if the device is not activated, to ensure that its IPv6 parameters
and other things get reset to the pre-NetworkManager values
https://bugzilla.gnome.org/show_bug.cgi?id=729833
2014-05-08 14:32:02 -05:00
|
|
|
|
2014-05-23 18:25:05 -05:00
|
|
|
if (unmanage) {
|
|
|
|
|
if (quitting)
|
2016-01-13 12:03:47 +01:00
|
|
|
nm_device_set_unmanaged_by_quitting (device);
|
2014-05-23 18:25:05 -05:00
|
|
|
else
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_PLATFORM_INIT, TRUE, NM_DEVICE_STATE_REASON_REMOVED);
|
2016-07-01 14:30:00 +02:00
|
|
|
} else if (quitting && nm_config_get_configure_and_quit (priv->config)) {
|
2014-10-29 09:12:18 -05:00
|
|
|
nm_device_spawn_iface_helper (device);
|
2014-05-23 18:25:05 -05:00
|
|
|
}
|
2009-08-03 17:15:03 -04:00
|
|
|
}
|
2009-05-20 12:02:18 -04:00
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
g_signal_handlers_disconnect_matched (device, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
|
2009-05-20 12:02:18 -04:00
|
|
|
|
2013-11-14 11:33:12 -06:00
|
|
|
nm_settings_device_removed (priv->settings, device, quitting);
|
2014-03-27 12:16:46 -04:00
|
|
|
priv->devices = g_slist_remove (priv->devices, device);
|
|
|
|
|
|
2014-10-06 11:21:54 -05:00
|
|
|
if (nm_device_is_real (device)) {
|
2016-04-20 17:46:41 +02:00
|
|
|
gboolean unconfigure_ip_config = !quitting || unmanage;
|
|
|
|
|
|
|
|
|
|
/* When we don't unmanage the device on shutdown, we want to preserve the DNS
|
|
|
|
|
* configuration in resolv.conf. For that, we must leak the configuration
|
|
|
|
|
* in NMPolicy/NMDnsManager. We do that, by emitting the device-removed signal
|
|
|
|
|
* with device's ip-config object still uncleared. In that case, NMPolicy
|
|
|
|
|
* never learns to unconfigure the ip-config objects and does not remove them
|
|
|
|
|
* from DNS on shutdown (which is ugly, because we don't cleanup the memory
|
|
|
|
|
* properly).
|
|
|
|
|
*
|
|
|
|
|
* Control that by passing @unconfigure_ip_config. */
|
|
|
|
|
nm_device_removed (device, unconfigure_ip_config);
|
2016-04-04 16:58:33 +02:00
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
g_signal_emit (self, signals[DEVICE_REMOVED], 0, device);
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_DEVICES);
|
2014-10-06 11:21:54 -05:00
|
|
|
}
|
2016-03-02 11:38:26 +01:00
|
|
|
g_signal_emit (self, signals[INTERNAL_DEVICE_REMOVED], 0, device);
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_ALL_DEVICES);
|
2014-04-09 12:31:08 -05:00
|
|
|
|
2015-07-23 10:03:21 -05:00
|
|
|
nm_exported_object_clear_and_unexport (&device);
|
2009-05-20 12:02:18 -04:00
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
check_if_startup_complete (self);
|
2009-05-20 12:02:18 -04:00
|
|
|
}
|
|
|
|
|
|
2014-02-10 08:49:47 -06:00
|
|
|
static void
|
|
|
|
|
device_removed_cb (NMDevice *device, gpointer user_data)
|
|
|
|
|
{
|
2014-10-13 11:58:26 -05:00
|
|
|
remove_device (NM_MANAGER (user_data), device, FALSE, TRUE);
|
2014-02-10 08:49:47 -06:00
|
|
|
}
|
|
|
|
|
|
2007-09-25 16:47:53 +00:00
|
|
|
NMState
|
|
|
|
|
nm_manager_get_state (NMManager *manager)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->state;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
/***************************/
|
2009-06-11 00:39:12 -04:00
|
|
|
|
all: standardize on NMSettingWired:mac-address for all VLANs
Currently, ethernet-based VLANs can specify the hardware address of
the parent device (and, in theory, the cloned hardware address and MTU
of the VLAN device) by using an NMSettingWired in addition to the
NMSettingVlan.
The theory was that non-ethernet-based VLANs, when we eventually
supported them, would likewise use the setting type corresponding to
their parent device. However, this turns out to be both complicated
(the settings plugins and connection editor would have a
hard-to-impossible time figuring out which setting type to use in some
cases) and incorrect (for most L2 settings [eg, BSSID, bond mode,
etc], the VLAN can't have its own values separate from the parent
device).
What we should have done was just have :mac-address,
:cloned-mac-address, and :mtu properties on NMSettingVlan. However, at
this point, for backward-compatibility, we will just stick with using
a combination of NMSettingVlan and NMSettingWired, but we will use
NMSettingWired regardless of the underlying hardware type.
2013-09-09 09:40:40 -04:00
|
|
|
static NMDevice *
|
2016-02-17 15:18:37 +01:00
|
|
|
find_parent_device_for_connection (NMManager *self, NMConnection *connection, NMDeviceFactory *cached_factory)
|
2012-02-12 14:48:44 -06:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2014-09-18 17:50:47 -05:00
|
|
|
NMDeviceFactory *factory;
|
|
|
|
|
const char *parent_name = NULL;
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *parent_connection;
|
2014-09-18 17:50:47 -05:00
|
|
|
NMDevice *parent, *first_compatible = NULL;
|
2012-02-12 14:48:44 -06:00
|
|
|
GSList *iter;
|
|
|
|
|
|
2014-09-24 16:58:07 -05:00
|
|
|
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
|
|
|
|
|
2016-02-17 15:18:37 +01:00
|
|
|
if (!cached_factory) {
|
|
|
|
|
factory = nm_device_factory_manager_find_factory_for_connection (connection);
|
|
|
|
|
if (!factory)
|
|
|
|
|
return NULL;
|
|
|
|
|
} else
|
|
|
|
|
factory = cached_factory;
|
2012-02-12 14:48:44 -06:00
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
parent_name = nm_device_factory_get_connection_parent (factory, connection);
|
|
|
|
|
if (!parent_name)
|
|
|
|
|
return NULL;
|
2012-02-12 14:48:44 -06:00
|
|
|
|
2014-10-15 21:17:45 -05:00
|
|
|
/* Try as an interface name of a parent device */
|
|
|
|
|
parent = find_device_by_iface (self, parent_name, NULL, NULL);
|
2014-09-18 17:50:47 -05:00
|
|
|
if (parent)
|
|
|
|
|
return parent;
|
2012-02-12 14:48:44 -06:00
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
/* Maybe a hardware address */
|
2016-06-15 13:43:34 +02:00
|
|
|
parent = find_device_by_permanent_hw_addr (self, parent_name);
|
2014-09-18 17:50:47 -05:00
|
|
|
if (parent)
|
|
|
|
|
return parent;
|
|
|
|
|
|
|
|
|
|
/* Maybe a connection UUID */
|
2015-07-14 16:53:24 +02:00
|
|
|
parent_connection = nm_settings_get_connection_by_uuid (priv->settings, parent_name);
|
2014-09-18 17:50:47 -05:00
|
|
|
if (!parent_connection)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* Check if the parent connection is currently activated or is comaptible
|
|
|
|
|
* with some known device.
|
|
|
|
|
*/
|
|
|
|
|
for (iter = priv->devices; iter; iter = iter->next) {
|
|
|
|
|
NMDevice *candidate = iter->data;
|
2013-06-10 17:32:23 -03:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
if (nm_device_get_settings_connection (candidate) == parent_connection)
|
2014-09-18 17:50:47 -05:00
|
|
|
return candidate;
|
2013-06-10 17:32:23 -03:00
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
if ( !first_compatible
|
2015-07-14 16:53:24 +02:00
|
|
|
&& nm_device_check_connection_compatible (candidate, NM_CONNECTION (parent_connection)))
|
2014-09-18 17:50:47 -05:00
|
|
|
first_compatible = candidate;
|
2013-06-10 17:32:23 -03:00
|
|
|
}
|
|
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
return first_compatible;
|
2013-06-10 17:32:23 -03:00
|
|
|
}
|
|
|
|
|
|
2012-02-10 13:25:39 -06:00
|
|
|
/**
|
2016-02-16 15:07:49 +01:00
|
|
|
* nm_manager_get_connection_iface:
|
2012-02-10 13:25:39 -06:00
|
|
|
* @self: the #NMManager
|
2016-02-16 15:07:49 +01:00
|
|
|
* @connection: the #NMConnection to get the interface for
|
2012-02-22 23:59:50 -06:00
|
|
|
* @out_parent: on success, the parent device if any
|
2014-09-18 17:50:47 -05:00
|
|
|
* @error: an error if determining the virtual interface name failed
|
2012-02-10 13:25:39 -06:00
|
|
|
*
|
|
|
|
|
* Given @connection, returns the interface name that the connection
|
2016-02-16 15:07:49 +01:00
|
|
|
* would need to use when activated. %NULL is returned if the name
|
|
|
|
|
* is not specified in connection or a the name for a virtual device
|
|
|
|
|
* could not be generated.
|
2012-02-10 13:25:39 -06:00
|
|
|
*
|
|
|
|
|
* Returns: the expected interface name (caller takes ownership), or %NULL
|
|
|
|
|
*/
|
2016-02-16 15:07:49 +01:00
|
|
|
char *
|
|
|
|
|
nm_manager_get_connection_iface (NMManager *self,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
NMDevice **out_parent,
|
|
|
|
|
GError **error)
|
2012-02-10 13:25:39 -06:00
|
|
|
{
|
2014-09-18 17:50:47 -05:00
|
|
|
NMDeviceFactory *factory;
|
|
|
|
|
char *iface = NULL;
|
2012-02-22 23:59:50 -06:00
|
|
|
NMDevice *parent = NULL;
|
2012-02-12 14:48:44 -06:00
|
|
|
|
2012-02-22 23:59:50 -06:00
|
|
|
if (out_parent)
|
|
|
|
|
*out_parent = NULL;
|
2012-02-12 14:48:44 -06:00
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
factory = nm_device_factory_manager_find_factory_for_connection (connection);
|
|
|
|
|
if (!factory) {
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_FAILED,
|
|
|
|
|
"NetworkManager plugin for '%s' unavailable",
|
|
|
|
|
nm_connection_get_connection_type (connection));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2014-08-04 16:27:43 -04:00
|
|
|
|
2016-02-17 16:12:46 +01:00
|
|
|
if ( !out_parent
|
|
|
|
|
&& !NM_DEVICE_FACTORY_GET_INTERFACE (factory)->get_connection_iface) {
|
|
|
|
|
/* optimization. Shortcut lookup of the partent device. */
|
|
|
|
|
iface = g_strdup (nm_connection_get_interface_name (connection));
|
|
|
|
|
if (!iface) {
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_FAILED,
|
|
|
|
|
"failed to determine interface name: error determine name for %s",
|
|
|
|
|
nm_connection_get_connection_type (connection));
|
|
|
|
|
}
|
|
|
|
|
return iface;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-17 15:18:37 +01:00
|
|
|
parent = find_parent_device_for_connection (self, connection, factory);
|
2016-02-17 15:11:02 +01:00
|
|
|
iface = nm_device_factory_get_connection_iface (factory,
|
|
|
|
|
connection,
|
|
|
|
|
parent ? nm_device_get_ip_iface (parent) : NULL,
|
|
|
|
|
error);
|
2016-01-21 17:36:08 +01:00
|
|
|
if (!iface)
|
2014-09-18 17:50:47 -05:00
|
|
|
return NULL;
|
2013-06-10 17:32:23 -03:00
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
if (out_parent)
|
|
|
|
|
*out_parent = parent;
|
|
|
|
|
return iface;
|
2011-10-18 13:48:44 +02:00
|
|
|
}
|
|
|
|
|
|
2012-02-10 13:25:39 -06:00
|
|
|
/**
|
|
|
|
|
* system_create_virtual_device:
|
|
|
|
|
* @self: the #NMManager
|
|
|
|
|
* @connection: the connection which might require a virtual device
|
|
|
|
|
*
|
|
|
|
|
* If @connection requires a virtual device and one does not yet exist for it,
|
|
|
|
|
* creates that device.
|
2015-12-17 18:40:36 +01:00
|
|
|
*
|
|
|
|
|
* Returns: A #NMDevice that was just realized; %NULL if none
|
2012-02-10 13:25:39 -06:00
|
|
|
*/
|
2015-12-17 18:40:36 +01:00
|
|
|
static NMDevice *
|
2015-12-11 16:13:13 +01:00
|
|
|
system_create_virtual_device (NMManager *self, NMConnection *connection)
|
2012-02-10 13:25:39 -06:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2014-09-17 14:17:30 -05:00
|
|
|
NMDeviceFactory *factory;
|
2016-01-21 18:16:01 +01:00
|
|
|
gs_free_slist GSList *connections = NULL;
|
|
|
|
|
GSList *iter;
|
2014-09-24 16:58:07 -05:00
|
|
|
gs_free char *iface = NULL;
|
2012-02-22 23:59:50 -06:00
|
|
|
NMDevice *device = NULL, *parent = NULL;
|
2015-12-11 16:13:13 +01:00
|
|
|
GError *error = NULL;
|
2012-02-10 13:25:39 -06:00
|
|
|
|
2015-12-18 12:09:38 +01:00
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (self), NULL);
|
|
|
|
|
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
2015-01-19 13:11:29 +01:00
|
|
|
|
2016-02-16 15:07:49 +01:00
|
|
|
iface = nm_manager_get_connection_iface (self, connection, &parent, &error);
|
2015-12-11 16:13:13 +01:00
|
|
|
if (!iface) {
|
2016-03-29 15:39:05 +02:00
|
|
|
_LOGD (LOGD_DEVICE, "(%s) can't get a name of a virtual device: %s",
|
2016-03-02 11:38:26 +01:00
|
|
|
nm_connection_get_id (connection), error->message);
|
2015-12-11 16:13:13 +01:00
|
|
|
g_error_free (error);
|
2015-12-17 18:40:36 +01:00
|
|
|
return NULL;
|
2015-12-11 16:13:13 +01:00
|
|
|
}
|
2011-10-18 13:48:44 +02:00
|
|
|
|
2015-12-11 15:40:34 +01:00
|
|
|
/* See if there's a device that is already compatible with this connection */
|
2012-02-10 13:25:39 -06:00
|
|
|
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
NMDevice *candidate = iter->data;
|
|
|
|
|
|
2016-02-16 15:07:57 +01:00
|
|
|
if (nm_device_check_connection_compatible (candidate, connection)) {
|
2015-12-11 15:40:34 +01:00
|
|
|
if (nm_device_is_real (candidate)) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "(%s) already created virtual interface name %s",
|
|
|
|
|
nm_connection_get_id (connection), iface);
|
2015-12-17 18:40:36 +01:00
|
|
|
return NULL;
|
2015-12-11 15:40:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
device = candidate;
|
|
|
|
|
break;
|
2015-01-19 13:11:29 +01:00
|
|
|
}
|
2012-02-10 13:25:39 -06:00
|
|
|
}
|
|
|
|
|
|
2015-12-11 15:40:34 +01:00
|
|
|
if (!device) {
|
|
|
|
|
/* No matching device found. Proceed creating a new one. */
|
|
|
|
|
|
|
|
|
|
factory = nm_device_factory_manager_find_factory_for_connection (connection);
|
|
|
|
|
if (!factory) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGE (LOGD_DEVICE, "(%s:%s) NetworkManager plugin for '%s' unavailable",
|
|
|
|
|
nm_connection_get_id (connection), iface,
|
|
|
|
|
nm_connection_get_connection_type (connection));
|
2015-12-17 18:40:36 +01:00
|
|
|
return NULL;
|
2015-12-11 15:40:34 +01:00
|
|
|
}
|
2014-09-17 14:17:30 -05:00
|
|
|
|
2015-12-11 16:13:13 +01:00
|
|
|
device = nm_device_factory_create_device (factory, iface, NULL, connection, NULL, &error);
|
|
|
|
|
if (!device) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE, "(%s) factory can't create the device: %s",
|
|
|
|
|
nm_connection_get_id (connection), error->message);
|
2015-12-11 16:13:13 +01:00
|
|
|
g_error_free (error);
|
2015-12-17 18:40:36 +01:00
|
|
|
return NULL;
|
2015-12-11 16:13:13 +01:00
|
|
|
}
|
2011-10-18 13:48:44 +02:00
|
|
|
|
2016-03-29 15:39:05 +02:00
|
|
|
_LOGD (LOGD_DEVICE, "(%s) create virtual device %s",
|
|
|
|
|
nm_connection_get_id (connection),
|
|
|
|
|
nm_device_get_iface (device));
|
|
|
|
|
|
2015-12-11 16:13:13 +01:00
|
|
|
if (!add_device (self, device, &error)) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE, "(%s) can't register the device with manager: %s",
|
|
|
|
|
nm_connection_get_id (connection), error->message);
|
2015-12-11 16:13:13 +01:00
|
|
|
g_error_free (error);
|
2015-12-11 15:40:34 +01:00
|
|
|
g_object_unref (device);
|
2015-12-17 18:40:36 +01:00
|
|
|
return NULL;
|
2015-12-11 15:40:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add device takes a reference that NMManager still owns, so it's
|
|
|
|
|
* safe to unref here and still return @device.
|
|
|
|
|
*/
|
2015-12-08 14:51:56 +01:00
|
|
|
g_object_unref (device);
|
|
|
|
|
}
|
2011-10-18 13:48:44 +02:00
|
|
|
|
2014-09-24 16:58:07 -05:00
|
|
|
/* Create backing resources if the device has any autoconnect connections */
|
2016-05-16 19:24:23 +02:00
|
|
|
connections = nm_settings_get_connections_sorted (priv->settings);
|
2011-10-18 13:48:44 +02:00
|
|
|
for (iter = connections; iter; iter = g_slist_next (iter)) {
|
2014-09-24 16:58:07 -05:00
|
|
|
NMConnection *candidate = iter->data;
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
|
|
|
|
|
if (!nm_device_check_connection_compatible (device, candidate))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
s_con = nm_connection_get_setting_connection (candidate);
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
if (!nm_setting_connection_get_autoconnect (s_con))
|
|
|
|
|
continue;
|
2013-12-04 15:58:32 +01:00
|
|
|
|
2014-09-24 16:58:07 -05:00
|
|
|
/* Create any backing resources the device needs */
|
2015-12-11 16:13:13 +01:00
|
|
|
if (!nm_device_create_and_realize (device, connection, parent, &error)) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE, "(%s) couldn't create the device: %s",
|
|
|
|
|
nm_connection_get_id (connection), error->message);
|
2015-12-11 16:13:13 +01:00
|
|
|
g_error_free (error);
|
2014-09-24 16:58:07 -05:00
|
|
|
remove_device (self, device, FALSE, TRUE);
|
2015-12-17 18:40:36 +01:00
|
|
|
return NULL;
|
2014-09-24 16:58:07 -05:00
|
|
|
}
|
|
|
|
|
break;
|
2011-10-18 13:48:44 +02:00
|
|
|
}
|
|
|
|
|
|
2015-12-17 18:40:36 +01:00
|
|
|
return device;
|
2011-10-18 13:48:44 +02:00
|
|
|
}
|
|
|
|
|
|
2016-01-07 17:54:38 +01:00
|
|
|
static void
|
|
|
|
|
retry_connections_for_parent_device (NMManager *self, NMDevice *device)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
GSList *connections, *iter;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (device);
|
|
|
|
|
|
2016-05-16 19:24:23 +02:00
|
|
|
connections = nm_settings_get_connections_sorted (priv->settings);
|
2016-01-07 17:54:38 +01:00
|
|
|
for (iter = connections; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
NMConnection *candidate = iter->data;
|
2016-03-08 12:02:54 +01:00
|
|
|
gs_free_error GError *error = NULL;
|
|
|
|
|
gs_free char *ifname = NULL;
|
2016-01-07 17:54:38 +01:00
|
|
|
NMDevice *parent;
|
|
|
|
|
|
2016-02-17 15:18:37 +01:00
|
|
|
parent = find_parent_device_for_connection (self, candidate, NULL);
|
2016-03-08 12:02:54 +01:00
|
|
|
if (parent == device) {
|
|
|
|
|
/* Only try to activate devices that don't already exist */
|
|
|
|
|
ifname = nm_manager_get_connection_iface (self, candidate, &parent, &error);
|
|
|
|
|
if (ifname) {
|
|
|
|
|
if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, ifname))
|
2016-04-13 16:03:06 +02:00
|
|
|
connection_changed (self, candidate);
|
2016-03-08 12:02:54 +01:00
|
|
|
}
|
|
|
|
|
}
|
2016-01-07 17:54:38 +01:00
|
|
|
}
|
2016-01-21 18:16:01 +01:00
|
|
|
|
|
|
|
|
g_slist_free (connections);
|
2016-01-07 17:54:38 +01:00
|
|
|
}
|
|
|
|
|
|
2011-10-18 13:48:44 +02:00
|
|
|
static void
|
2016-04-13 16:03:06 +02:00
|
|
|
connection_changed (NMManager *self,
|
|
|
|
|
NMConnection *connection)
|
2008-04-29 Dan Williams <dcbw@redhat.com>
Handle HAL dropouts better; allow NM to start up even if HAL isn't up yet.
* marshallers/nm-marshal.list
- Add marshaller
* src/NetworkManager.c
- (main): let the NMManager handle the NMHalManager
* src/nm-hal-manager.c
src/nm-hal-manager.h
- convert to a GObject, and emit singals when stuff changes. Let the
NMManager handle the signals, instead of the NMHalManager calling
into the NMManager.
* src/nm-manager.c
src/nm-manager.h
- (remove_one_device): consolidate device removals here
- (dispose): use remove_one_device()
- (nm_manager_get_device_by_udi): make static
- (deferred_hal_manager_query_devices): idle handler to query the HAL
manager for devices at startup or wakeup time
- (nm_manager_new): create and monitor the HAL manager
- (hal_manager_udi_added_cb): new function; do what
nm_manager_add_device() used to do when signalled by the hal manager
- (hal_manager_udi_removed_cb): new function; do what
nm_manager_remove_device() used to do when signalled by the hal
manager
- (hal_manager_rfkill_changed_cb): handle rfkill changes from the
hal manager
- (hal_manager_hal_reappeared_cb): when HAL comes back, remove devices
in our device list that aren't known to HAL
- (impl_manager_sleep): on wakeup, re-add devices from an idle handler;
see comments on nm-hal-manager.c::nm_manager_state_changed() a few
commits ago
- (nm_manager_get_device_by_path, nm_manager_is_udi_managed,
nm_manager_activation_pending, nm_manager_wireless_enabled,
nm_manager_wireless_hardware_enabled,
nm_manager_set_wireless_hardware_enabled): remove, unused
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3619 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-29 23:03:00 +00:00
|
|
|
{
|
2015-12-17 18:40:36 +01:00
|
|
|
NMDevice *device;
|
|
|
|
|
|
|
|
|
|
if (!nm_connection_is_virtual (connection))
|
|
|
|
|
return;
|
|
|
|
|
|
2016-04-13 16:03:06 +02:00
|
|
|
device = system_create_virtual_device (self, connection);
|
2015-12-17 18:40:36 +01:00
|
|
|
if (!device)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Maybe the device that was created was needed by some other
|
|
|
|
|
* connection's device (parent of a VLAN). Let the connections
|
|
|
|
|
* can use the newly created device as a parent know. */
|
2016-04-13 16:03:06 +02:00
|
|
|
retry_connections_for_parent_device (self, device);
|
2011-10-18 13:48:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2016-04-13 16:03:06 +02:00
|
|
|
connection_added_cb (NMSettings *settings,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
NMManager *self)
|
2011-10-18 13:48:44 +02:00
|
|
|
{
|
2016-04-13 16:03:06 +02:00
|
|
|
connection_changed (self, connection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
connection_updated_cb (NMSettings *settings,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
gboolean by_user,
|
|
|
|
|
NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
if (by_user)
|
|
|
|
|
connection_changed (self, connection);
|
2008-05-22 14:22:31 +00:00
|
|
|
}
|
|
|
|
|
|
2008-04-07 Dan Williams <dcbw@redhat.com>
* include/NetworkManager.h
- Remove the DOWN and CANCELLED device states
- Add UNMANAGED and UNAVAILABLE device states
- Document the device states
* introspection/nm-device.xml
src/nm-device-interface.c
src/nm-device-interface.h
- Add the 'managed' property
* test/nm-tool.c
- (detail_device): print out device state
* src/NetworkManagerSystem.h
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerDebian.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerMandriva.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerSuSE.c
- (nm_system_device_get_system_config, nm_system_device_get_disabled
nm_system_device_free_system_config): remove; they were unused and
their functionality should be re-implemented in each distro's
system settings service plugin
* src/nm-gsm-device.c
src/nm-gsm-device.h
src/nm-cdma-device.c
src/nm-cdma-device.h
- (*_new): take the 'managed' argument
* src/nm-device.c
- (nm_device_set_address): remove, fold into nm_device_bring_up()
- (nm_device_init): start in unmanaged state, not disconnected
- (constructor): don't start device until the system settings service
has had a chance to figure out if the device is managed or not
- (nm_device_deactivate, nm_device_bring_up, nm_device_bring_down):
don't set device state here, let callers handle that as appropriate
- (nm_device_dispose): don't touch the device if it's not managed
- (set_property, get_property, nm_device_class_init): implement the
'managed' property
- (nm_device_state_changed): bring the device up if its now managed,
and deactivate it if it used to be active
- (nm_device_get_managed, nm_device_set_managed): do the right thing
with the managed state
* src/nm-hal-manager.c
- (wired_device_creator, wireless_device_creator, modem_device_creator):
take initial managed state and pass it along to device constructors
- (create_device_and_add_to_list): get managed state and pass to
type creators
* src/nm-device-802-11-wireless.c
- (real_can_activate): fold in most of
nm_device_802_11_wireless_can_activate()
- (can_scan): can't scan in UNAVAILABLE or UNMANAGED
- (link_timeout_cb): instead of deactivating, change device state and
let the device state handler to it
- (real_update_hw_address): clean up
- (state_changed_cb): when entering UNAVAILABLE state, schedule an idle
handler to transition to DISCONNECTED if the device isn't rfkilled
* src/nm-device-802-3-ethernet.c
- (set_carrier): move above callers and get rid of prototype
- (device_state_changed): when entering UNAVAILABLE state, schedule an
idle handler to transition to DISCONNECTED if the device has a
carrier
- (real_update_hw_address): clean up
- (link_timeout_cb, ppp_state_changed): change state instead of calling
deactivation directly as deactivation doesn't change state anymore
* src/NetworkManagerPolicy.c
- (schedule_activate_check): yay, remove wireless_enabled hack since
the NMManager and wireless devices work that out themselves now
- (device_state_changed): change to a switch and update for new device
states
- (device_carrier_changed): remove; device handles this now through
state changes
- (device_added): don't care about carrier any more; the initial
activation check will happen when the device transitions to
DISCONNECTED
* src/nm-manager.c
- (dispose): clear unmanaged devices
- (handle_unmanaged_devices): update unmanaged device list and toggle
the managed property on each device when needed
- (system_settings_properties_changed_cb): handle signals from the
system settings service
- (system_settings_get_unmanaged_devices_cb): handle callback from
getting the unmanaged device list method call
- (query_unmanaged_devices): ask the system settings service for its
list of unmanaged devices
- (nm_manager_name_owner_changed, initial_get_connections): get unmanaged
devices
- (manager_set_wireless_enabled): push rfkill state down to wireless
devices directly and let them handle the necessary state transitions
- (manager_device_state_changed): update for new device states
- (nm_manager_add_device): set initial rfkill state on wireless devices
- (nm_manager_remove_device): don't touch the device if it's unmanaged
- (nm_manager_activate_connection): return error if the device is
unmanaged
- (nm_manager_sleep): handle new device states correctly; don't change
the state of unavailable/unmanaged devices
* libnm-glib/nm-device-802-11-wireless.c
- (state_changed_cb): update for new device states
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3540 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 02:58:02 +00:00
|
|
|
static void
|
2010-10-27 20:05:23 -05:00
|
|
|
system_unmanaged_devices_changed_cb (NMSettings *settings,
|
2009-06-11 00:39:12 -04:00
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data)
|
2008-04-07 Dan Williams <dcbw@redhat.com>
* include/NetworkManager.h
- Remove the DOWN and CANCELLED device states
- Add UNMANAGED and UNAVAILABLE device states
- Document the device states
* introspection/nm-device.xml
src/nm-device-interface.c
src/nm-device-interface.h
- Add the 'managed' property
* test/nm-tool.c
- (detail_device): print out device state
* src/NetworkManagerSystem.h
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerDebian.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerMandriva.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerSuSE.c
- (nm_system_device_get_system_config, nm_system_device_get_disabled
nm_system_device_free_system_config): remove; they were unused and
their functionality should be re-implemented in each distro's
system settings service plugin
* src/nm-gsm-device.c
src/nm-gsm-device.h
src/nm-cdma-device.c
src/nm-cdma-device.h
- (*_new): take the 'managed' argument
* src/nm-device.c
- (nm_device_set_address): remove, fold into nm_device_bring_up()
- (nm_device_init): start in unmanaged state, not disconnected
- (constructor): don't start device until the system settings service
has had a chance to figure out if the device is managed or not
- (nm_device_deactivate, nm_device_bring_up, nm_device_bring_down):
don't set device state here, let callers handle that as appropriate
- (nm_device_dispose): don't touch the device if it's not managed
- (set_property, get_property, nm_device_class_init): implement the
'managed' property
- (nm_device_state_changed): bring the device up if its now managed,
and deactivate it if it used to be active
- (nm_device_get_managed, nm_device_set_managed): do the right thing
with the managed state
* src/nm-hal-manager.c
- (wired_device_creator, wireless_device_creator, modem_device_creator):
take initial managed state and pass it along to device constructors
- (create_device_and_add_to_list): get managed state and pass to
type creators
* src/nm-device-802-11-wireless.c
- (real_can_activate): fold in most of
nm_device_802_11_wireless_can_activate()
- (can_scan): can't scan in UNAVAILABLE or UNMANAGED
- (link_timeout_cb): instead of deactivating, change device state and
let the device state handler to it
- (real_update_hw_address): clean up
- (state_changed_cb): when entering UNAVAILABLE state, schedule an idle
handler to transition to DISCONNECTED if the device isn't rfkilled
* src/nm-device-802-3-ethernet.c
- (set_carrier): move above callers and get rid of prototype
- (device_state_changed): when entering UNAVAILABLE state, schedule an
idle handler to transition to DISCONNECTED if the device has a
carrier
- (real_update_hw_address): clean up
- (link_timeout_cb, ppp_state_changed): change state instead of calling
deactivation directly as deactivation doesn't change state anymore
* src/NetworkManagerPolicy.c
- (schedule_activate_check): yay, remove wireless_enabled hack since
the NMManager and wireless devices work that out themselves now
- (device_state_changed): change to a switch and update for new device
states
- (device_carrier_changed): remove; device handles this now through
state changes
- (device_added): don't care about carrier any more; the initial
activation check will happen when the device transitions to
DISCONNECTED
* src/nm-manager.c
- (dispose): clear unmanaged devices
- (handle_unmanaged_devices): update unmanaged device list and toggle
the managed property on each device when needed
- (system_settings_properties_changed_cb): handle signals from the
system settings service
- (system_settings_get_unmanaged_devices_cb): handle callback from
getting the unmanaged device list method call
- (query_unmanaged_devices): ask the system settings service for its
list of unmanaged devices
- (nm_manager_name_owner_changed, initial_get_connections): get unmanaged
devices
- (manager_set_wireless_enabled): push rfkill state down to wireless
devices directly and let them handle the necessary state transitions
- (manager_device_state_changed): update for new device states
- (nm_manager_add_device): set initial rfkill state on wireless devices
- (nm_manager_remove_device): don't touch the device if it's unmanaged
- (nm_manager_activate_connection): return error if the device is
unmanaged
- (nm_manager_sleep): handle new device states correctly; don't change
the state of unavailable/unmanaged devices
* libnm-glib/nm-device-802-11-wireless.c
- (state_changed_cb): update for new device states
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3540 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 02:58:02 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2009-06-11 00:39:12 -04:00
|
|
|
const GSList *unmanaged_specs, *iter;
|
2008-04-07 Dan Williams <dcbw@redhat.com>
* include/NetworkManager.h
- Remove the DOWN and CANCELLED device states
- Add UNMANAGED and UNAVAILABLE device states
- Document the device states
* introspection/nm-device.xml
src/nm-device-interface.c
src/nm-device-interface.h
- Add the 'managed' property
* test/nm-tool.c
- (detail_device): print out device state
* src/NetworkManagerSystem.h
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerDebian.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerMandriva.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerSuSE.c
- (nm_system_device_get_system_config, nm_system_device_get_disabled
nm_system_device_free_system_config): remove; they were unused and
their functionality should be re-implemented in each distro's
system settings service plugin
* src/nm-gsm-device.c
src/nm-gsm-device.h
src/nm-cdma-device.c
src/nm-cdma-device.h
- (*_new): take the 'managed' argument
* src/nm-device.c
- (nm_device_set_address): remove, fold into nm_device_bring_up()
- (nm_device_init): start in unmanaged state, not disconnected
- (constructor): don't start device until the system settings service
has had a chance to figure out if the device is managed or not
- (nm_device_deactivate, nm_device_bring_up, nm_device_bring_down):
don't set device state here, let callers handle that as appropriate
- (nm_device_dispose): don't touch the device if it's not managed
- (set_property, get_property, nm_device_class_init): implement the
'managed' property
- (nm_device_state_changed): bring the device up if its now managed,
and deactivate it if it used to be active
- (nm_device_get_managed, nm_device_set_managed): do the right thing
with the managed state
* src/nm-hal-manager.c
- (wired_device_creator, wireless_device_creator, modem_device_creator):
take initial managed state and pass it along to device constructors
- (create_device_and_add_to_list): get managed state and pass to
type creators
* src/nm-device-802-11-wireless.c
- (real_can_activate): fold in most of
nm_device_802_11_wireless_can_activate()
- (can_scan): can't scan in UNAVAILABLE or UNMANAGED
- (link_timeout_cb): instead of deactivating, change device state and
let the device state handler to it
- (real_update_hw_address): clean up
- (state_changed_cb): when entering UNAVAILABLE state, schedule an idle
handler to transition to DISCONNECTED if the device isn't rfkilled
* src/nm-device-802-3-ethernet.c
- (set_carrier): move above callers and get rid of prototype
- (device_state_changed): when entering UNAVAILABLE state, schedule an
idle handler to transition to DISCONNECTED if the device has a
carrier
- (real_update_hw_address): clean up
- (link_timeout_cb, ppp_state_changed): change state instead of calling
deactivation directly as deactivation doesn't change state anymore
* src/NetworkManagerPolicy.c
- (schedule_activate_check): yay, remove wireless_enabled hack since
the NMManager and wireless devices work that out themselves now
- (device_state_changed): change to a switch and update for new device
states
- (device_carrier_changed): remove; device handles this now through
state changes
- (device_added): don't care about carrier any more; the initial
activation check will happen when the device transitions to
DISCONNECTED
* src/nm-manager.c
- (dispose): clear unmanaged devices
- (handle_unmanaged_devices): update unmanaged device list and toggle
the managed property on each device when needed
- (system_settings_properties_changed_cb): handle signals from the
system settings service
- (system_settings_get_unmanaged_devices_cb): handle callback from
getting the unmanaged device list method call
- (query_unmanaged_devices): ask the system settings service for its
list of unmanaged devices
- (nm_manager_name_owner_changed, initial_get_connections): get unmanaged
devices
- (manager_set_wireless_enabled): push rfkill state down to wireless
devices directly and let them handle the necessary state transitions
- (manager_device_state_changed): update for new device states
- (nm_manager_add_device): set initial rfkill state on wireless devices
- (nm_manager_remove_device): don't touch the device if it's unmanaged
- (nm_manager_activate_connection): return error if the device is
unmanaged
- (nm_manager_sleep): handle new device states correctly; don't change
the state of unavailable/unmanaged devices
* libnm-glib/nm-device-802-11-wireless.c
- (state_changed_cb): update for new device states
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3540 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 02:58:02 +00:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
|
2015-09-15 23:53:46 +02:00
|
|
|
for (iter = priv->devices; iter; iter = g_slist_next (iter))
|
2016-05-17 12:12:50 +02:00
|
|
|
nm_device_set_unmanaged_by_user_settings (NM_DEVICE (iter->data), unmanaged_specs);
|
2008-09-18 Dan Williams <dcbw@redhat.com>
Implement support for honoring configured and automatic hostnames, and for
setting the configured hostname.
* introspection/nm-ip4-config.xml
src/nm-ip4-config.c
src/nm-ip4-config.h
src/dhcp-manager/nm-dhcp-manager.c
- Remove useless hostname property; it's not really part of the IPv4
config
* introspection/nm-settings-system.xml
libnm-glib/nm-dbus-settings-system.c
libnm-glib/nm-dbus-settings-system.h
- Add SetHostname() call to system settings D-Bus interface
- Add Hostname property to system settings D-Bus interface
- (nm_dbus_settings_system_save_hostname,
nm_dbus_settings_system_get_hostname): implement
* src/nm-device.c
src/nm-device.h
- (nm_device_get_dhcp4_config): implement
* src/nm-manager.c
src/nm-manager.h
- Fetch and track system settings service hostname changes, and proxy
the changes via a GObject property of the manager
* system-settings/src/nm-system-config-interface.c
system-settings/src/nm-system-config-interface.h
- Replace nm_system_config_interface_supports_add() with a capabilities
bitfield
* system-settings/src/nm-system-config-error.c
system-settings/src/nm-system-config-error.h
- Add additional errors
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (get_property, nm_sysconfig_settings_class_init): add hostname
property; first plugin returning a hostname wins
- (impl_settings_add_connection): use plugin capabilities instead of
nm_system_config_interface_supports_add()
- (impl_settings_save_hostname): implement hostname saving
* src/NetworkManagerPolicy.c
- (lookup_thread_run_cb, lookup_thread_worker, lookup_thread_new,
lookup_thread_die): implement an asynchronous hostname lookup thread
which given an IPv4 address tries to look up the hostname for that
address with reverse DNS
- (get_best_device): split out best device code from
update_routing_and_dns()
- (update_etc_hosts): update /etc/hosts with the machine's new hostname
to preserve the 127.0.0.1 reverse mapping that so many things require
- (set_system_hostname): set a given hostname
- (update_system_hostname): implement hostname policy; a configured
hostname (from the system settings service) is used if available,
otherwise an automatically determined hostname from DHCP, VPN, etc.
If there was no automatically determined hostname, reverse DNS of
the best device's IP address will be used, and as a last resort the
hostname 'localhost.localdomain' is set.
- (update_routing_and_dns): use get_best_device(); update the system
hostname when the network config changes
- (hostname_changed): update system hostname if the system settings
service signals a hostname change
- (nm_policy_new): list for system settings service hostname changes
- (nm_policy_destroy): ensure that an in-progress hostname lookup thread
gets told to die
* system-settings/plugins/keyfile/plugin.c
system-settings/plugins/ifcfg-suse/plugin.c
- (get_property, sc_plugin_ifcfg_class_init): implement hostname and
capabilities properties
* system-settings/plugins/ifcfg-fedora/shvar.c
- (svOpenFile): re-enable R/W access of ifcfg files since the plugin
writes out /etc/sysconfig/network now
* system-settings/plugins/ifcfg-fedora/plugin.c
- (plugin_get_hostname): get hostname from /etc/sysconfig/network
- (plugin_set_hostname): save hostname to /etc/sysconfig/network
- (sc_network_changed_cb): handle changes to /etc/sysconfig/network
- (sc_plugin_ifcfg_init): monitor /etc/sysconfig/network for changes
- (get_property, set_property, sc_plugin_ifcfg_class_init): implement
hostname get/set and capabilities get
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4077 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-09-18 15:16:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2010-10-27 20:05:23 -05:00
|
|
|
system_hostname_changed_cb (NMSettings *settings,
|
2009-06-11 00:39:12 -04:00
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data)
|
2008-09-18 Dan Williams <dcbw@redhat.com>
Implement support for honoring configured and automatic hostnames, and for
setting the configured hostname.
* introspection/nm-ip4-config.xml
src/nm-ip4-config.c
src/nm-ip4-config.h
src/dhcp-manager/nm-dhcp-manager.c
- Remove useless hostname property; it's not really part of the IPv4
config
* introspection/nm-settings-system.xml
libnm-glib/nm-dbus-settings-system.c
libnm-glib/nm-dbus-settings-system.h
- Add SetHostname() call to system settings D-Bus interface
- Add Hostname property to system settings D-Bus interface
- (nm_dbus_settings_system_save_hostname,
nm_dbus_settings_system_get_hostname): implement
* src/nm-device.c
src/nm-device.h
- (nm_device_get_dhcp4_config): implement
* src/nm-manager.c
src/nm-manager.h
- Fetch and track system settings service hostname changes, and proxy
the changes via a GObject property of the manager
* system-settings/src/nm-system-config-interface.c
system-settings/src/nm-system-config-interface.h
- Replace nm_system_config_interface_supports_add() with a capabilities
bitfield
* system-settings/src/nm-system-config-error.c
system-settings/src/nm-system-config-error.h
- Add additional errors
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (get_property, nm_sysconfig_settings_class_init): add hostname
property; first plugin returning a hostname wins
- (impl_settings_add_connection): use plugin capabilities instead of
nm_system_config_interface_supports_add()
- (impl_settings_save_hostname): implement hostname saving
* src/NetworkManagerPolicy.c
- (lookup_thread_run_cb, lookup_thread_worker, lookup_thread_new,
lookup_thread_die): implement an asynchronous hostname lookup thread
which given an IPv4 address tries to look up the hostname for that
address with reverse DNS
- (get_best_device): split out best device code from
update_routing_and_dns()
- (update_etc_hosts): update /etc/hosts with the machine's new hostname
to preserve the 127.0.0.1 reverse mapping that so many things require
- (set_system_hostname): set a given hostname
- (update_system_hostname): implement hostname policy; a configured
hostname (from the system settings service) is used if available,
otherwise an automatically determined hostname from DHCP, VPN, etc.
If there was no automatically determined hostname, reverse DNS of
the best device's IP address will be used, and as a last resort the
hostname 'localhost.localdomain' is set.
- (update_routing_and_dns): use get_best_device(); update the system
hostname when the network config changes
- (hostname_changed): update system hostname if the system settings
service signals a hostname change
- (nm_policy_new): list for system settings service hostname changes
- (nm_policy_destroy): ensure that an in-progress hostname lookup thread
gets told to die
* system-settings/plugins/keyfile/plugin.c
system-settings/plugins/ifcfg-suse/plugin.c
- (get_property, sc_plugin_ifcfg_class_init): implement hostname and
capabilities properties
* system-settings/plugins/ifcfg-fedora/shvar.c
- (svOpenFile): re-enable R/W access of ifcfg files since the plugin
writes out /etc/sysconfig/network now
* system-settings/plugins/ifcfg-fedora/plugin.c
- (plugin_get_hostname): get hostname from /etc/sysconfig/network
- (plugin_set_hostname): save hostname to /etc/sysconfig/network
- (sc_network_changed_cb): handle changes to /etc/sysconfig/network
- (sc_plugin_ifcfg_init): monitor /etc/sysconfig/network for changes
- (get_property, set_property, sc_plugin_ifcfg_class_init): implement
hostname get/set and capabilities get
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4077 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-09-18 15:16:44 +00:00
|
|
|
{
|
2010-10-27 20:05:23 -05:00
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2009-06-11 00:39:12 -04:00
|
|
|
char *hostname;
|
2008-09-18 Dan Williams <dcbw@redhat.com>
Implement support for honoring configured and automatic hostnames, and for
setting the configured hostname.
* introspection/nm-ip4-config.xml
src/nm-ip4-config.c
src/nm-ip4-config.h
src/dhcp-manager/nm-dhcp-manager.c
- Remove useless hostname property; it's not really part of the IPv4
config
* introspection/nm-settings-system.xml
libnm-glib/nm-dbus-settings-system.c
libnm-glib/nm-dbus-settings-system.h
- Add SetHostname() call to system settings D-Bus interface
- Add Hostname property to system settings D-Bus interface
- (nm_dbus_settings_system_save_hostname,
nm_dbus_settings_system_get_hostname): implement
* src/nm-device.c
src/nm-device.h
- (nm_device_get_dhcp4_config): implement
* src/nm-manager.c
src/nm-manager.h
- Fetch and track system settings service hostname changes, and proxy
the changes via a GObject property of the manager
* system-settings/src/nm-system-config-interface.c
system-settings/src/nm-system-config-interface.h
- Replace nm_system_config_interface_supports_add() with a capabilities
bitfield
* system-settings/src/nm-system-config-error.c
system-settings/src/nm-system-config-error.h
- Add additional errors
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (get_property, nm_sysconfig_settings_class_init): add hostname
property; first plugin returning a hostname wins
- (impl_settings_add_connection): use plugin capabilities instead of
nm_system_config_interface_supports_add()
- (impl_settings_save_hostname): implement hostname saving
* src/NetworkManagerPolicy.c
- (lookup_thread_run_cb, lookup_thread_worker, lookup_thread_new,
lookup_thread_die): implement an asynchronous hostname lookup thread
which given an IPv4 address tries to look up the hostname for that
address with reverse DNS
- (get_best_device): split out best device code from
update_routing_and_dns()
- (update_etc_hosts): update /etc/hosts with the machine's new hostname
to preserve the 127.0.0.1 reverse mapping that so many things require
- (set_system_hostname): set a given hostname
- (update_system_hostname): implement hostname policy; a configured
hostname (from the system settings service) is used if available,
otherwise an automatically determined hostname from DHCP, VPN, etc.
If there was no automatically determined hostname, reverse DNS of
the best device's IP address will be used, and as a last resort the
hostname 'localhost.localdomain' is set.
- (update_routing_and_dns): use get_best_device(); update the system
hostname when the network config changes
- (hostname_changed): update system hostname if the system settings
service signals a hostname change
- (nm_policy_new): list for system settings service hostname changes
- (nm_policy_destroy): ensure that an in-progress hostname lookup thread
gets told to die
* system-settings/plugins/keyfile/plugin.c
system-settings/plugins/ifcfg-suse/plugin.c
- (get_property, sc_plugin_ifcfg_class_init): implement hostname and
capabilities properties
* system-settings/plugins/ifcfg-fedora/shvar.c
- (svOpenFile): re-enable R/W access of ifcfg files since the plugin
writes out /etc/sysconfig/network now
* system-settings/plugins/ifcfg-fedora/plugin.c
- (plugin_get_hostname): get hostname from /etc/sysconfig/network
- (plugin_set_hostname): save hostname to /etc/sysconfig/network
- (sc_network_changed_cb): handle changes to /etc/sysconfig/network
- (sc_plugin_ifcfg_init): monitor /etc/sysconfig/network for changes
- (get_property, set_property, sc_plugin_ifcfg_class_init): implement
hostname get/set and capabilities get
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4077 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-09-18 15:16:44 +00:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
hostname = nm_settings_get_hostname (priv->settings);
|
2015-08-18 14:28:57 +02:00
|
|
|
|
|
|
|
|
/* nm_settings_get_hostname() does not return an empty hostname. */
|
|
|
|
|
nm_assert (!hostname || *hostname);
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
if (!hostname && !priv->hostname)
|
|
|
|
|
return;
|
2015-08-18 14:28:57 +02:00
|
|
|
if (hostname && priv->hostname && !strcmp (hostname, priv->hostname)) {
|
|
|
|
|
g_free (hostname);
|
2008-09-18 Dan Williams <dcbw@redhat.com>
Implement support for honoring configured and automatic hostnames, and for
setting the configured hostname.
* introspection/nm-ip4-config.xml
src/nm-ip4-config.c
src/nm-ip4-config.h
src/dhcp-manager/nm-dhcp-manager.c
- Remove useless hostname property; it's not really part of the IPv4
config
* introspection/nm-settings-system.xml
libnm-glib/nm-dbus-settings-system.c
libnm-glib/nm-dbus-settings-system.h
- Add SetHostname() call to system settings D-Bus interface
- Add Hostname property to system settings D-Bus interface
- (nm_dbus_settings_system_save_hostname,
nm_dbus_settings_system_get_hostname): implement
* src/nm-device.c
src/nm-device.h
- (nm_device_get_dhcp4_config): implement
* src/nm-manager.c
src/nm-manager.h
- Fetch and track system settings service hostname changes, and proxy
the changes via a GObject property of the manager
* system-settings/src/nm-system-config-interface.c
system-settings/src/nm-system-config-interface.h
- Replace nm_system_config_interface_supports_add() with a capabilities
bitfield
* system-settings/src/nm-system-config-error.c
system-settings/src/nm-system-config-error.h
- Add additional errors
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (get_property, nm_sysconfig_settings_class_init): add hostname
property; first plugin returning a hostname wins
- (impl_settings_add_connection): use plugin capabilities instead of
nm_system_config_interface_supports_add()
- (impl_settings_save_hostname): implement hostname saving
* src/NetworkManagerPolicy.c
- (lookup_thread_run_cb, lookup_thread_worker, lookup_thread_new,
lookup_thread_die): implement an asynchronous hostname lookup thread
which given an IPv4 address tries to look up the hostname for that
address with reverse DNS
- (get_best_device): split out best device code from
update_routing_and_dns()
- (update_etc_hosts): update /etc/hosts with the machine's new hostname
to preserve the 127.0.0.1 reverse mapping that so many things require
- (set_system_hostname): set a given hostname
- (update_system_hostname): implement hostname policy; a configured
hostname (from the system settings service) is used if available,
otherwise an automatically determined hostname from DHCP, VPN, etc.
If there was no automatically determined hostname, reverse DNS of
the best device's IP address will be used, and as a last resort the
hostname 'localhost.localdomain' is set.
- (update_routing_and_dns): use get_best_device(); update the system
hostname when the network config changes
- (hostname_changed): update system hostname if the system settings
service signals a hostname change
- (nm_policy_new): list for system settings service hostname changes
- (nm_policy_destroy): ensure that an in-progress hostname lookup thread
gets told to die
* system-settings/plugins/keyfile/plugin.c
system-settings/plugins/ifcfg-suse/plugin.c
- (get_property, sc_plugin_ifcfg_class_init): implement hostname and
capabilities properties
* system-settings/plugins/ifcfg-fedora/shvar.c
- (svOpenFile): re-enable R/W access of ifcfg files since the plugin
writes out /etc/sysconfig/network now
* system-settings/plugins/ifcfg-fedora/plugin.c
- (plugin_get_hostname): get hostname from /etc/sysconfig/network
- (plugin_set_hostname): save hostname to /etc/sysconfig/network
- (sc_network_changed_cb): handle changes to /etc/sysconfig/network
- (sc_plugin_ifcfg_init): monitor /etc/sysconfig/network for changes
- (get_property, set_property, sc_plugin_ifcfg_class_init): implement
hostname get/set and capabilities get
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4077 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-09-18 15:16:44 +00:00
|
|
|
return;
|
2015-08-18 14:28:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* realloc, to free possibly trailing data after NUL. */
|
|
|
|
|
if (hostname)
|
|
|
|
|
hostname = g_realloc (hostname, strlen (hostname) + 1);
|
2008-04-07 Dan Williams <dcbw@redhat.com>
* include/NetworkManager.h
- Remove the DOWN and CANCELLED device states
- Add UNMANAGED and UNAVAILABLE device states
- Document the device states
* introspection/nm-device.xml
src/nm-device-interface.c
src/nm-device-interface.h
- Add the 'managed' property
* test/nm-tool.c
- (detail_device): print out device state
* src/NetworkManagerSystem.h
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerDebian.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerMandriva.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerSuSE.c
- (nm_system_device_get_system_config, nm_system_device_get_disabled
nm_system_device_free_system_config): remove; they were unused and
their functionality should be re-implemented in each distro's
system settings service plugin
* src/nm-gsm-device.c
src/nm-gsm-device.h
src/nm-cdma-device.c
src/nm-cdma-device.h
- (*_new): take the 'managed' argument
* src/nm-device.c
- (nm_device_set_address): remove, fold into nm_device_bring_up()
- (nm_device_init): start in unmanaged state, not disconnected
- (constructor): don't start device until the system settings service
has had a chance to figure out if the device is managed or not
- (nm_device_deactivate, nm_device_bring_up, nm_device_bring_down):
don't set device state here, let callers handle that as appropriate
- (nm_device_dispose): don't touch the device if it's not managed
- (set_property, get_property, nm_device_class_init): implement the
'managed' property
- (nm_device_state_changed): bring the device up if its now managed,
and deactivate it if it used to be active
- (nm_device_get_managed, nm_device_set_managed): do the right thing
with the managed state
* src/nm-hal-manager.c
- (wired_device_creator, wireless_device_creator, modem_device_creator):
take initial managed state and pass it along to device constructors
- (create_device_and_add_to_list): get managed state and pass to
type creators
* src/nm-device-802-11-wireless.c
- (real_can_activate): fold in most of
nm_device_802_11_wireless_can_activate()
- (can_scan): can't scan in UNAVAILABLE or UNMANAGED
- (link_timeout_cb): instead of deactivating, change device state and
let the device state handler to it
- (real_update_hw_address): clean up
- (state_changed_cb): when entering UNAVAILABLE state, schedule an idle
handler to transition to DISCONNECTED if the device isn't rfkilled
* src/nm-device-802-3-ethernet.c
- (set_carrier): move above callers and get rid of prototype
- (device_state_changed): when entering UNAVAILABLE state, schedule an
idle handler to transition to DISCONNECTED if the device has a
carrier
- (real_update_hw_address): clean up
- (link_timeout_cb, ppp_state_changed): change state instead of calling
deactivation directly as deactivation doesn't change state anymore
* src/NetworkManagerPolicy.c
- (schedule_activate_check): yay, remove wireless_enabled hack since
the NMManager and wireless devices work that out themselves now
- (device_state_changed): change to a switch and update for new device
states
- (device_carrier_changed): remove; device handles this now through
state changes
- (device_added): don't care about carrier any more; the initial
activation check will happen when the device transitions to
DISCONNECTED
* src/nm-manager.c
- (dispose): clear unmanaged devices
- (handle_unmanaged_devices): update unmanaged device list and toggle
the managed property on each device when needed
- (system_settings_properties_changed_cb): handle signals from the
system settings service
- (system_settings_get_unmanaged_devices_cb): handle callback from
getting the unmanaged device list method call
- (query_unmanaged_devices): ask the system settings service for its
list of unmanaged devices
- (nm_manager_name_owner_changed, initial_get_connections): get unmanaged
devices
- (manager_set_wireless_enabled): push rfkill state down to wireless
devices directly and let them handle the necessary state transitions
- (manager_device_state_changed): update for new device states
- (nm_manager_add_device): set initial rfkill state on wireless devices
- (nm_manager_remove_device): don't touch the device if it's unmanaged
- (nm_manager_activate_connection): return error if the device is
unmanaged
- (nm_manager_sleep): handle new device states correctly; don't change
the state of unavailable/unmanaged devices
* libnm-glib/nm-device-802-11-wireless.c
- (state_changed_cb): update for new device states
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3540 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 02:58:02 +00:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
g_free (priv->hostname);
|
2015-08-18 14:28:57 +02:00
|
|
|
priv->hostname = hostname;
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_HOSTNAME);
|
2008-09-18 Dan Williams <dcbw@redhat.com>
Implement support for honoring configured and automatic hostnames, and for
setting the configured hostname.
* introspection/nm-ip4-config.xml
src/nm-ip4-config.c
src/nm-ip4-config.h
src/dhcp-manager/nm-dhcp-manager.c
- Remove useless hostname property; it's not really part of the IPv4
config
* introspection/nm-settings-system.xml
libnm-glib/nm-dbus-settings-system.c
libnm-glib/nm-dbus-settings-system.h
- Add SetHostname() call to system settings D-Bus interface
- Add Hostname property to system settings D-Bus interface
- (nm_dbus_settings_system_save_hostname,
nm_dbus_settings_system_get_hostname): implement
* src/nm-device.c
src/nm-device.h
- (nm_device_get_dhcp4_config): implement
* src/nm-manager.c
src/nm-manager.h
- Fetch and track system settings service hostname changes, and proxy
the changes via a GObject property of the manager
* system-settings/src/nm-system-config-interface.c
system-settings/src/nm-system-config-interface.h
- Replace nm_system_config_interface_supports_add() with a capabilities
bitfield
* system-settings/src/nm-system-config-error.c
system-settings/src/nm-system-config-error.h
- Add additional errors
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (get_property, nm_sysconfig_settings_class_init): add hostname
property; first plugin returning a hostname wins
- (impl_settings_add_connection): use plugin capabilities instead of
nm_system_config_interface_supports_add()
- (impl_settings_save_hostname): implement hostname saving
* src/NetworkManagerPolicy.c
- (lookup_thread_run_cb, lookup_thread_worker, lookup_thread_new,
lookup_thread_die): implement an asynchronous hostname lookup thread
which given an IPv4 address tries to look up the hostname for that
address with reverse DNS
- (get_best_device): split out best device code from
update_routing_and_dns()
- (update_etc_hosts): update /etc/hosts with the machine's new hostname
to preserve the 127.0.0.1 reverse mapping that so many things require
- (set_system_hostname): set a given hostname
- (update_system_hostname): implement hostname policy; a configured
hostname (from the system settings service) is used if available,
otherwise an automatically determined hostname from DHCP, VPN, etc.
If there was no automatically determined hostname, reverse DNS of
the best device's IP address will be used, and as a last resort the
hostname 'localhost.localdomain' is set.
- (update_routing_and_dns): use get_best_device(); update the system
hostname when the network config changes
- (hostname_changed): update system hostname if the system settings
service signals a hostname change
- (nm_policy_new): list for system settings service hostname changes
- (nm_policy_destroy): ensure that an in-progress hostname lookup thread
gets told to die
* system-settings/plugins/keyfile/plugin.c
system-settings/plugins/ifcfg-suse/plugin.c
- (get_property, sc_plugin_ifcfg_class_init): implement hostname and
capabilities properties
* system-settings/plugins/ifcfg-fedora/shvar.c
- (svOpenFile): re-enable R/W access of ifcfg files since the plugin
writes out /etc/sysconfig/network now
* system-settings/plugins/ifcfg-fedora/plugin.c
- (plugin_get_hostname): get hostname from /etc/sysconfig/network
- (plugin_set_hostname): save hostname to /etc/sysconfig/network
- (sc_network_changed_cb): handle changes to /etc/sysconfig/network
- (sc_plugin_ifcfg_init): monitor /etc/sysconfig/network for changes
- (get_property, set_property, sc_plugin_ifcfg_class_init): implement
hostname get/set and capabilities get
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4077 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-09-18 15:16:44 +00:00
|
|
|
|
2014-04-02 15:52:04 -05:00
|
|
|
nm_dhcp_manager_set_default_hostname (nm_dhcp_manager_get (), priv->hostname);
|
2008-04-07 Dan Williams <dcbw@redhat.com>
* include/NetworkManager.h
- Remove the DOWN and CANCELLED device states
- Add UNMANAGED and UNAVAILABLE device states
- Document the device states
* introspection/nm-device.xml
src/nm-device-interface.c
src/nm-device-interface.h
- Add the 'managed' property
* test/nm-tool.c
- (detail_device): print out device state
* src/NetworkManagerSystem.h
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerDebian.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerMandriva.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerSuSE.c
- (nm_system_device_get_system_config, nm_system_device_get_disabled
nm_system_device_free_system_config): remove; they were unused and
their functionality should be re-implemented in each distro's
system settings service plugin
* src/nm-gsm-device.c
src/nm-gsm-device.h
src/nm-cdma-device.c
src/nm-cdma-device.h
- (*_new): take the 'managed' argument
* src/nm-device.c
- (nm_device_set_address): remove, fold into nm_device_bring_up()
- (nm_device_init): start in unmanaged state, not disconnected
- (constructor): don't start device until the system settings service
has had a chance to figure out if the device is managed or not
- (nm_device_deactivate, nm_device_bring_up, nm_device_bring_down):
don't set device state here, let callers handle that as appropriate
- (nm_device_dispose): don't touch the device if it's not managed
- (set_property, get_property, nm_device_class_init): implement the
'managed' property
- (nm_device_state_changed): bring the device up if its now managed,
and deactivate it if it used to be active
- (nm_device_get_managed, nm_device_set_managed): do the right thing
with the managed state
* src/nm-hal-manager.c
- (wired_device_creator, wireless_device_creator, modem_device_creator):
take initial managed state and pass it along to device constructors
- (create_device_and_add_to_list): get managed state and pass to
type creators
* src/nm-device-802-11-wireless.c
- (real_can_activate): fold in most of
nm_device_802_11_wireless_can_activate()
- (can_scan): can't scan in UNAVAILABLE or UNMANAGED
- (link_timeout_cb): instead of deactivating, change device state and
let the device state handler to it
- (real_update_hw_address): clean up
- (state_changed_cb): when entering UNAVAILABLE state, schedule an idle
handler to transition to DISCONNECTED if the device isn't rfkilled
* src/nm-device-802-3-ethernet.c
- (set_carrier): move above callers and get rid of prototype
- (device_state_changed): when entering UNAVAILABLE state, schedule an
idle handler to transition to DISCONNECTED if the device has a
carrier
- (real_update_hw_address): clean up
- (link_timeout_cb, ppp_state_changed): change state instead of calling
deactivation directly as deactivation doesn't change state anymore
* src/NetworkManagerPolicy.c
- (schedule_activate_check): yay, remove wireless_enabled hack since
the NMManager and wireless devices work that out themselves now
- (device_state_changed): change to a switch and update for new device
states
- (device_carrier_changed): remove; device handles this now through
state changes
- (device_added): don't care about carrier any more; the initial
activation check will happen when the device transitions to
DISCONNECTED
* src/nm-manager.c
- (dispose): clear unmanaged devices
- (handle_unmanaged_devices): update unmanaged device list and toggle
the managed property on each device when needed
- (system_settings_properties_changed_cb): handle signals from the
system settings service
- (system_settings_get_unmanaged_devices_cb): handle callback from
getting the unmanaged device list method call
- (query_unmanaged_devices): ask the system settings service for its
list of unmanaged devices
- (nm_manager_name_owner_changed, initial_get_connections): get unmanaged
devices
- (manager_set_wireless_enabled): push rfkill state down to wireless
devices directly and let them handle the necessary state transitions
- (manager_device_state_changed): update for new device states
- (nm_manager_add_device): set initial rfkill state on wireless devices
- (nm_manager_remove_device): don't touch the device if it's unmanaged
- (nm_manager_activate_connection): return error if the device is
unmanaged
- (nm_manager_sleep): handle new device states correctly; don't change
the state of unavailable/unmanaged devices
* libnm-glib/nm-device-802-11-wireless.c
- (state_changed_cb): update for new device states
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3540 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 02:58:02 +00:00
|
|
|
}
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
/*******************************************************************/
|
|
|
|
|
/* General NMManager stuff */
|
|
|
|
|
/*******************************************************************/
|
|
|
|
|
|
2010-09-01 17:08:10 -05:00
|
|
|
static gboolean
|
2011-04-22 14:56:31 -05:00
|
|
|
radio_enabled_for_rstate (RadioState *rstate, gboolean check_changeable)
|
2010-09-01 17:08:10 -05:00
|
|
|
{
|
2011-04-13 21:58:25 -05:00
|
|
|
gboolean enabled;
|
|
|
|
|
|
2011-04-22 14:56:31 -05:00
|
|
|
enabled = rstate->user_enabled && rstate->hw_enabled;
|
2013-05-31 14:28:16 -05:00
|
|
|
if (check_changeable)
|
2011-04-22 14:56:31 -05:00
|
|
|
enabled &= rstate->sw_enabled;
|
2011-04-13 21:58:25 -05:00
|
|
|
return enabled;
|
2010-09-01 17:08:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2011-04-22 14:56:31 -05:00
|
|
|
radio_enabled_for_type (NMManager *self, RfKillType rtype, gboolean check_changeable)
|
2010-09-01 17:08:10 -05:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
2011-04-22 14:56:31 -05:00
|
|
|
return radio_enabled_for_rstate (&priv->radio_states[rtype], check_changeable);
|
2010-09-01 17:08:10 -05:00
|
|
|
}
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
static void
|
2011-04-13 21:58:25 -05:00
|
|
|
manager_update_radio_enabled (NMManager *self,
|
|
|
|
|
RadioState *rstate,
|
|
|
|
|
gboolean enabled)
|
2008-02-06 16:50:43 +00:00
|
|
|
{
|
2010-09-01 17:08:10 -05:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2009-06-11 00:39:12 -04:00
|
|
|
GSList *iter;
|
2008-02-06 16:50:43 +00:00
|
|
|
|
2009-12-23 00:03:45 -08:00
|
|
|
/* Do nothing for radio types not yet implemented */
|
|
|
|
|
if (!rstate->prop)
|
|
|
|
|
return;
|
|
|
|
|
|
2010-09-01 17:08:10 -05:00
|
|
|
g_object_notify (G_OBJECT (self), rstate->prop);
|
2009-11-02 17:29:53 -08:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
/* Don't touch devices if asleep/networking disabled */
|
2010-09-01 17:08:10 -05:00
|
|
|
if (manager_sleeping (self))
|
2009-06-11 00:39:12 -04:00
|
|
|
return;
|
2007-09-03 01:12:23 +00:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
/* enable/disable wireless devices as required */
|
|
|
|
|
for (iter = priv->devices; iter; iter = iter->next) {
|
2011-11-18 12:02:58 -06:00
|
|
|
NMDevice *device = NM_DEVICE (iter->data);
|
2010-03-25 11:36:19 -07:00
|
|
|
|
2011-11-18 12:02:58 -06:00
|
|
|
if (nm_device_get_rfkill_type (device) == rstate->rtype) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_RFKILL, "(%s): setting radio %s",
|
|
|
|
|
nm_device_get_iface (device),
|
|
|
|
|
enabled ? "enabled" : "disabled");
|
2011-11-18 12:02:58 -06:00
|
|
|
nm_device_set_enabled (device, enabled);
|
2010-04-07 14:55:43 -07:00
|
|
|
}
|
2008-02-06 16:50:43 +00:00
|
|
|
}
|
2007-09-03 01:12:23 +00:00
|
|
|
}
|
|
|
|
|
|
2010-09-01 17:08:10 -05:00
|
|
|
static void
|
2014-04-15 16:25:39 -05:00
|
|
|
update_rstate_from_rfkill (NMRfkillManager *rfkill_mgr, RadioState *rstate)
|
2010-09-01 17:08:10 -05:00
|
|
|
{
|
2014-04-15 16:25:39 -05:00
|
|
|
switch (nm_rfkill_manager_get_rfkill_state (rfkill_mgr, rstate->rtype)) {
|
|
|
|
|
case RFKILL_UNBLOCKED:
|
2010-09-01 17:08:10 -05:00
|
|
|
rstate->sw_enabled = TRUE;
|
|
|
|
|
rstate->hw_enabled = TRUE;
|
2014-04-15 16:25:39 -05:00
|
|
|
break;
|
|
|
|
|
case RFKILL_SOFT_BLOCKED:
|
2010-09-01 17:08:10 -05:00
|
|
|
rstate->sw_enabled = FALSE;
|
|
|
|
|
rstate->hw_enabled = TRUE;
|
2014-04-15 16:25:39 -05:00
|
|
|
break;
|
|
|
|
|
case RFKILL_HARD_BLOCKED:
|
2010-09-01 17:08:10 -05:00
|
|
|
rstate->sw_enabled = FALSE;
|
|
|
|
|
rstate->hw_enabled = FALSE;
|
2014-04-15 16:25:39 -05:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
g_warn_if_reached ();
|
|
|
|
|
break;
|
2010-09-01 17:08:10 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-24 10:43:43 -08:00
|
|
|
static void
|
2009-12-23 00:03:45 -08:00
|
|
|
manager_rfkill_update_one_type (NMManager *self,
|
|
|
|
|
RadioState *rstate,
|
|
|
|
|
RfKillType rtype)
|
2009-11-24 10:43:43 -08:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2013-05-31 14:28:16 -05:00
|
|
|
gboolean old_enabled, new_enabled, old_rfkilled, new_rfkilled, old_hwe;
|
2010-09-01 17:08:10 -05:00
|
|
|
|
2011-04-13 21:58:25 -05:00
|
|
|
old_enabled = radio_enabled_for_rstate (rstate, TRUE);
|
2010-09-01 17:08:10 -05:00
|
|
|
old_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
|
|
|
|
|
old_hwe = rstate->hw_enabled;
|
2009-11-24 10:43:43 -08:00
|
|
|
|
2014-04-15 16:25:39 -05:00
|
|
|
/* recheck kernel rfkill state */
|
|
|
|
|
update_rstate_from_rfkill (priv->rfkill_mgr, rstate);
|
2009-11-24 10:43:43 -08:00
|
|
|
|
2011-04-13 21:58:25 -05:00
|
|
|
/* Print out all states affecting device enablement */
|
2010-04-08 18:23:43 -07:00
|
|
|
if (rstate->desc) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d",
|
|
|
|
|
rstate->desc, rstate->hw_enabled, rstate->sw_enabled);
|
2010-04-08 18:23:43 -07:00
|
|
|
}
|
|
|
|
|
|
2010-09-01 17:08:10 -05:00
|
|
|
/* Log new killswitch state */
|
|
|
|
|
new_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
|
|
|
|
|
if (old_rfkilled != new_rfkilled) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_RFKILL, "%s now %s by radio killswitch",
|
|
|
|
|
rstate->desc,
|
|
|
|
|
new_rfkilled ? "enabled" : "disabled");
|
2010-09-01 17:08:10 -05:00
|
|
|
}
|
2009-12-23 00:03:45 -08:00
|
|
|
|
2010-09-01 17:08:10 -05:00
|
|
|
/* Send out property changed signal for HW enabled */
|
|
|
|
|
if (rstate->hw_enabled != old_hwe) {
|
2010-04-08 18:23:43 -07:00
|
|
|
if (rstate->hw_prop)
|
|
|
|
|
g_object_notify (G_OBJECT (self), rstate->hw_prop);
|
2009-11-24 10:43:43 -08:00
|
|
|
}
|
2010-09-01 17:08:10 -05:00
|
|
|
|
2011-04-13 21:58:25 -05:00
|
|
|
/* And finally update the actual device radio state itself; respect the
|
|
|
|
|
* daemon state here because this is never called from user-triggered
|
|
|
|
|
* radio changes and we only want to ignore the daemon enabled state when
|
|
|
|
|
* handling user radio change requests.
|
|
|
|
|
*/
|
|
|
|
|
new_enabled = radio_enabled_for_rstate (rstate, TRUE);
|
2010-09-01 17:08:10 -05:00
|
|
|
if (new_enabled != old_enabled)
|
2011-04-13 21:58:25 -05:00
|
|
|
manager_update_radio_enabled (self, rstate, new_enabled);
|
2009-12-23 00:03:45 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
nm_manager_rfkill_update (NMManager *self, RfKillType rtype)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
guint i;
|
|
|
|
|
|
2011-04-13 21:58:25 -05:00
|
|
|
if (rtype != RFKILL_TYPE_UNKNOWN)
|
2009-12-23 00:03:45 -08:00
|
|
|
manager_rfkill_update_one_type (self, &priv->radio_states[rtype], rtype);
|
2011-04-13 21:58:25 -05:00
|
|
|
else {
|
|
|
|
|
/* Otherwise sync all radio types */
|
|
|
|
|
for (i = 0; i < RFKILL_TYPE_MAX; i++)
|
|
|
|
|
manager_rfkill_update_one_type (self, &priv->radio_states[i], i);
|
2009-11-24 10:43:43 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-01 15:27:39 -05:00
|
|
|
static void
|
|
|
|
|
device_auth_done_cb (NMAuthChain *chain,
|
|
|
|
|
GError *auth_error,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2012-06-01 15:27:39 -05:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
NMAuthCallResult result;
|
|
|
|
|
NMDevice *device;
|
|
|
|
|
const char *permission;
|
|
|
|
|
NMDeviceAuthRequestFunc callback;
|
2015-07-14 10:19:19 +02:00
|
|
|
NMAuthSubject *subject;
|
2012-06-01 15:27:39 -05:00
|
|
|
|
2013-07-29 11:53:23 -05:00
|
|
|
g_assert (context);
|
|
|
|
|
|
2012-06-01 15:27:39 -05:00
|
|
|
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
|
|
|
|
|
|
|
|
|
|
permission = nm_auth_chain_get_data (chain, "requested-permission");
|
|
|
|
|
g_assert (permission);
|
|
|
|
|
callback = nm_auth_chain_get_data (chain, "callback");
|
|
|
|
|
g_assert (callback);
|
|
|
|
|
device = nm_auth_chain_get_data (chain, "device");
|
|
|
|
|
g_assert (device);
|
|
|
|
|
|
2012-10-08 12:52:15 -05:00
|
|
|
result = nm_auth_chain_get_result (chain, permission);
|
2015-07-14 10:19:19 +02:00
|
|
|
subject = nm_auth_chain_get_subject (chain);
|
2012-10-08 12:52:15 -05:00
|
|
|
|
2012-06-01 15:27:39 -05:00
|
|
|
if (auth_error) {
|
|
|
|
|
/* translate the auth error into a manager permission denied error */
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "%s request failed: %s", permission, auth_error->message);
|
2012-06-01 15:27:39 -05:00
|
|
|
error = g_error_new (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"%s request failed: %s",
|
|
|
|
|
permission, auth_error->message);
|
|
|
|
|
} else if (result != NM_AUTH_CALL_RESULT_YES) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "%s request failed: not authorized", permission);
|
2012-06-01 15:27:39 -05:00
|
|
|
error = g_error_new (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"%s request failed: not authorized",
|
|
|
|
|
permission);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_assert (error || (result == NM_AUTH_CALL_RESULT_YES));
|
|
|
|
|
|
|
|
|
|
callback (device,
|
|
|
|
|
context,
|
2015-07-14 10:19:19 +02:00
|
|
|
subject,
|
2012-06-01 15:27:39 -05:00
|
|
|
error,
|
|
|
|
|
nm_auth_chain_get_data (chain, "user-data"));
|
|
|
|
|
|
|
|
|
|
g_clear_error (&error);
|
|
|
|
|
nm_auth_chain_unref (chain);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
device_auth_request_cb (NMDevice *device,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2014-01-17 11:18:23 -06:00
|
|
|
NMConnection *connection,
|
2012-06-01 15:27:39 -05:00
|
|
|
const char *permission,
|
|
|
|
|
gboolean allow_interaction,
|
|
|
|
|
NMDeviceAuthRequestFunc callback,
|
|
|
|
|
gpointer user_data,
|
|
|
|
|
NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
GError *error = NULL;
|
2014-01-17 11:18:23 -06:00
|
|
|
NMAuthSubject *subject = NULL;
|
|
|
|
|
char *error_desc = NULL;
|
2012-06-01 15:27:39 -05:00
|
|
|
NMAuthChain *chain;
|
|
|
|
|
|
2014-01-17 11:18:23 -06:00
|
|
|
/* Validate the caller */
|
2014-08-14 13:34:57 +02:00
|
|
|
subject = nm_auth_subject_new_unix_process_from_context (context);
|
2014-01-17 11:18:23 -06:00
|
|
|
if (!subject) {
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Failed to get request UID.");
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Ensure the subject has permissions for this connection */
|
2014-08-14 13:34:57 +02:00
|
|
|
if (connection && !nm_auth_is_subject_in_acl (connection,
|
|
|
|
|
subject,
|
|
|
|
|
&error_desc)) {
|
2014-01-17 11:18:23 -06:00
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
error_desc);
|
|
|
|
|
g_free (error_desc);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-16 12:30:41 -06:00
|
|
|
/* Validate the request */
|
2014-01-17 11:18:23 -06:00
|
|
|
chain = nm_auth_chain_new_subject (subject, context, device_auth_done_cb, self);
|
2013-07-29 11:53:23 -05:00
|
|
|
if (!chain) {
|
2012-06-01 15:27:39 -05:00
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
2013-07-29 11:53:23 -05:00
|
|
|
"Unable to authenticate request.");
|
2014-01-17 11:18:23 -06:00
|
|
|
goto done;
|
2012-06-01 15:27:39 -05:00
|
|
|
}
|
2013-07-29 11:53:23 -05:00
|
|
|
|
|
|
|
|
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
|
|
|
|
nm_auth_chain_set_data (chain, "device", g_object_ref (device), g_object_unref);
|
|
|
|
|
nm_auth_chain_set_data (chain, "requested-permission", g_strdup (permission), g_free);
|
|
|
|
|
nm_auth_chain_set_data (chain, "callback", callback, NULL);
|
|
|
|
|
nm_auth_chain_set_data (chain, "user-data", user_data, NULL);
|
|
|
|
|
nm_auth_chain_add_call (chain, permission, allow_interaction);
|
2014-01-17 11:18:23 -06:00
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
if (error)
|
2015-07-14 10:19:19 +02:00
|
|
|
callback (device, context, subject, error, user_data);
|
|
|
|
|
|
|
|
|
|
g_clear_object (&subject);
|
2014-01-17 11:18:23 -06:00
|
|
|
g_clear_error (&error);
|
2012-06-01 15:27:39 -05:00
|
|
|
}
|
|
|
|
|
|
2013-11-15 13:09:12 -06:00
|
|
|
static gboolean
|
|
|
|
|
match_connection_filter (NMConnection *connection, gpointer user_data)
|
|
|
|
|
{
|
2015-02-19 18:46:57 +01:00
|
|
|
if (nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection)))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2014-05-30 13:44:53 -05:00
|
|
|
return nm_device_check_connection_compatible (NM_DEVICE (user_data), connection);
|
2013-11-15 13:09:12 -06:00
|
|
|
}
|
|
|
|
|
|
2013-06-27 14:39:13 +02:00
|
|
|
/**
|
2013-11-02 10:40:58 -05:00
|
|
|
* get_existing_connection:
|
2013-06-27 14:39:13 +02:00
|
|
|
* @manager: #NMManager instance
|
|
|
|
|
* @device: #NMDevice instance
|
2014-06-20 20:13:14 +02:00
|
|
|
* @out_generated: (allow-none): return TRUE, if the connection was generated.
|
2013-06-27 14:39:13 +02:00
|
|
|
*
|
2013-11-02 10:40:58 -05:00
|
|
|
* Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if
|
|
|
|
|
* the device does not support assuming existing connections.
|
2013-06-27 14:39:13 +02:00
|
|
|
*/
|
2015-07-14 16:53:24 +02:00
|
|
|
static NMSettingsConnection *
|
2016-03-02 11:38:26 +01:00
|
|
|
get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_generated)
|
2013-06-27 14:39:13 +02:00
|
|
|
{
|
2016-03-02 11:38:26 +01:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
gs_free_slist GSList *connections = nm_manager_get_activatable_connections (self);
|
2015-07-14 16:53:24 +02:00
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
NMSettingsConnection *matched;
|
2013-08-23 15:45:17 +02:00
|
|
|
NMSettingsConnection *added = NULL;
|
|
|
|
|
GError *error = NULL;
|
2014-06-18 20:17:57 +02:00
|
|
|
NMDevice *master = NULL;
|
|
|
|
|
int ifindex = nm_device_get_ifindex (device);
|
2013-06-27 14:39:13 +02:00
|
|
|
|
2014-06-20 20:13:14 +02:00
|
|
|
if (out_generated)
|
|
|
|
|
*out_generated = FALSE;
|
|
|
|
|
|
2013-11-02 10:38:23 -05:00
|
|
|
nm_device_capture_initial_config (device);
|
|
|
|
|
|
2014-06-18 20:17:57 +02:00
|
|
|
if (ifindex) {
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
int master_ifindex = nm_platform_link_get_master (NM_PLATFORM_GET, ifindex);
|
2014-06-18 20:17:57 +02:00
|
|
|
|
|
|
|
|
if (master_ifindex) {
|
2016-03-02 11:38:26 +01:00
|
|
|
master = nm_manager_get_device_by_ifindex (self, master_ifindex);
|
2014-06-18 20:17:57 +02:00
|
|
|
if (!master) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "(%s): cannot generate connection for slave before its master (%s/%d)",
|
|
|
|
|
nm_device_get_iface (device), nm_platform_link_get_name (NM_PLATFORM_GET, master_ifindex), master_ifindex);
|
2014-06-18 20:17:57 +02:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
if (!nm_device_get_act_request (master)) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "(%s): cannot generate connection for slave before master %s activates",
|
|
|
|
|
nm_device_get_iface (device), nm_device_get_iface (master));
|
2014-06-18 20:17:57 +02:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-27 14:39:13 +02:00
|
|
|
/* The core of the API is nm_device_generate_connection() function and
|
|
|
|
|
* update_connection() virtual method and the convenient connection_type
|
|
|
|
|
* class attribute. Subclasses supporting the new API must have
|
|
|
|
|
* update_connection() implemented, otherwise nm_device_generate_connection()
|
|
|
|
|
* returns NULL.
|
|
|
|
|
*/
|
2014-06-18 20:17:57 +02:00
|
|
|
connection = nm_device_generate_connection (device, master);
|
2013-11-06 22:18:02 -06:00
|
|
|
if (!connection)
|
2013-06-27 14:39:13 +02:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* Now we need to compare the generated connection to each configured
|
|
|
|
|
* connection. The comparison function is the heart of the connection
|
|
|
|
|
* assumption implementation and it must compare the connections very
|
|
|
|
|
* carefully to sort out various corner cases. Also, the comparison is
|
|
|
|
|
* not entirely symmetric.
|
|
|
|
|
*
|
|
|
|
|
* When no configured connection matches the generated connection, we keep
|
|
|
|
|
* the generated connection instead.
|
|
|
|
|
*/
|
2014-04-10 13:25:41 +02:00
|
|
|
connections = g_slist_reverse (g_slist_sort (connections, nm_settings_sort_connections));
|
2015-07-14 16:53:24 +02:00
|
|
|
matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections,
|
|
|
|
|
connection,
|
|
|
|
|
nm_device_has_carrier (device),
|
2016-02-01 14:16:30 +01:00
|
|
|
nm_device_get_ip4_route_metric (device),
|
|
|
|
|
nm_device_get_ip6_route_metric (device),
|
2015-07-14 16:53:24 +02:00
|
|
|
match_connection_filter,
|
|
|
|
|
device));
|
2013-11-15 13:09:12 -06:00
|
|
|
if (matched) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "(%s): found matching connection '%s'",
|
|
|
|
|
nm_device_get_iface (device),
|
|
|
|
|
nm_settings_connection_get_id (matched));
|
2013-11-14 10:00:35 -06:00
|
|
|
g_object_unref (connection);
|
2013-11-15 13:09:12 -06:00
|
|
|
return matched;
|
2013-06-27 14:39:13 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "(%s): generated connection '%s'",
|
|
|
|
|
nm_device_get_iface (device),
|
|
|
|
|
nm_connection_get_id (connection));
|
2013-08-23 15:45:17 +02:00
|
|
|
|
|
|
|
|
added = nm_settings_add_connection (priv->settings, connection, FALSE, &error);
|
2014-08-18 21:20:56 +02:00
|
|
|
if (added) {
|
|
|
|
|
nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added),
|
|
|
|
|
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED |
|
|
|
|
|
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED,
|
|
|
|
|
TRUE);
|
2014-06-20 20:13:14 +02:00
|
|
|
if (out_generated)
|
|
|
|
|
*out_generated = TRUE;
|
2014-08-18 21:20:56 +02:00
|
|
|
} else {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGW (LOGD_SETTINGS, "(%s) Couldn't save generated connection '%s': %s",
|
|
|
|
|
nm_device_get_iface (device),
|
|
|
|
|
nm_connection_get_id (connection),
|
2016-02-28 16:25:36 +01:00
|
|
|
error->message);
|
2013-08-23 15:45:17 +02:00
|
|
|
g_clear_error (&error);
|
|
|
|
|
}
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
return added ? added : NULL;
|
2013-06-27 14:39:13 +02:00
|
|
|
}
|
|
|
|
|
|
2014-05-28 10:18:34 -04:00
|
|
|
static gboolean
|
2015-07-14 16:53:24 +02:00
|
|
|
assume_connection (NMManager *self, NMDevice *device, NMSettingsConnection *connection)
|
2014-05-28 10:18:34 -04:00
|
|
|
{
|
|
|
|
|
NMActiveConnection *active, *master_ac;
|
|
|
|
|
NMAuthSubject *subject;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "(%s): will attempt to assume connection",
|
|
|
|
|
nm_device_get_iface (device));
|
2014-05-28 10:18:34 -04:00
|
|
|
|
|
|
|
|
/* Move device to DISCONNECTED to activate the connection */
|
|
|
|
|
if (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE) {
|
|
|
|
|
nm_device_state_changed (device,
|
|
|
|
|
NM_DEVICE_STATE_DISCONNECTED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
|
|
|
|
|
}
|
2014-06-06 16:34:57 +02:00
|
|
|
g_return_val_if_fail (nm_device_get_state (device) >= NM_DEVICE_STATE_DISCONNECTED, FALSE);
|
2014-05-28 10:18:34 -04:00
|
|
|
|
|
|
|
|
subject = nm_auth_subject_new_internal ();
|
2015-07-14 16:53:24 +02:00
|
|
|
active = _new_active_connection (self, NM_CONNECTION (connection), NULL, device, subject, &error);
|
2014-05-28 10:18:34 -04:00
|
|
|
g_object_unref (subject);
|
|
|
|
|
|
|
|
|
|
if (!active) {
|
2016-02-28 18:12:28 +01:00
|
|
|
_LOGW (LOGD_DEVICE, "assumed connection %s failed to activate: %s",
|
2016-03-02 11:38:26 +01:00
|
|
|
nm_connection_get_path (NM_CONNECTION (connection)),
|
2016-02-28 16:25:36 +01:00
|
|
|
error->message);
|
2014-05-28 10:18:34 -04:00
|
|
|
g_error_free (error);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If the device is a slave or VLAN, find the master ActiveConnection */
|
|
|
|
|
master_ac = NULL;
|
2015-07-14 16:53:24 +02:00
|
|
|
if (find_master (self, NM_CONNECTION (connection), device, NULL, NULL, &master_ac, NULL) && master_ac)
|
2014-05-28 10:18:34 -04:00
|
|
|
nm_active_connection_set_master (active, master_ac);
|
|
|
|
|
|
|
|
|
|
nm_active_connection_set_assumed (active, TRUE);
|
2015-04-03 10:08:52 -04:00
|
|
|
nm_exported_object_export (NM_EXPORTED_OBJECT (active));
|
2014-05-28 10:18:34 -04:00
|
|
|
active_connection_add (self, active);
|
|
|
|
|
nm_device_queue_activation (device, NM_ACT_REQUEST (active));
|
|
|
|
|
g_object_unref (active);
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-20 20:13:14 +02:00
|
|
|
static gboolean
|
2015-12-04 17:17:47 +01:00
|
|
|
recheck_assume_connection (NMManager *self, NMDevice *device)
|
2014-05-28 10:18:34 -04:00
|
|
|
{
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *connection;
|
2014-09-24 16:58:07 -05:00
|
|
|
gboolean was_unmanaged = FALSE, success, generated = FALSE;
|
2014-08-01 22:46:49 +02:00
|
|
|
NMDeviceState state;
|
2014-05-28 10:18:34 -04:00
|
|
|
|
2015-12-04 17:17:47 +01:00
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
|
|
|
|
|
|
|
|
|
|
if (nm_device_get_is_nm_owned (device))
|
|
|
|
|
return FALSE;
|
2014-09-24 16:58:07 -05:00
|
|
|
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
if (!nm_device_get_managed (device, FALSE))
|
2014-06-20 20:13:14 +02:00
|
|
|
return FALSE;
|
2014-05-28 10:18:34 -04:00
|
|
|
|
2014-12-03 14:24:18 -06:00
|
|
|
state = nm_device_get_state (device);
|
|
|
|
|
if (state > NM_DEVICE_STATE_DISCONNECTED)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2014-06-20 20:13:14 +02:00
|
|
|
connection = get_existing_connection (self, device, &generated);
|
2014-05-28 10:18:34 -04:00
|
|
|
if (!connection) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "(%s): can't assume; no connection",
|
|
|
|
|
nm_device_get_iface (device));
|
2014-06-20 20:13:14 +02:00
|
|
|
return FALSE;
|
2014-05-28 10:18:34 -04:00
|
|
|
}
|
|
|
|
|
|
2014-08-01 22:46:49 +02:00
|
|
|
if (state == NM_DEVICE_STATE_UNMANAGED) {
|
2014-05-28 10:18:34 -04:00
|
|
|
was_unmanaged = TRUE;
|
|
|
|
|
nm_device_state_changed (device,
|
|
|
|
|
NM_DEVICE_STATE_UNAVAILABLE,
|
|
|
|
|
NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-20 20:13:14 +02:00
|
|
|
success = assume_connection (self, device, connection);
|
|
|
|
|
if (!success) {
|
2014-05-28 10:18:34 -04:00
|
|
|
if (was_unmanaged) {
|
|
|
|
|
nm_device_state_changed (device,
|
|
|
|
|
NM_DEVICE_STATE_UNAVAILABLE,
|
|
|
|
|
NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
2014-06-20 20:13:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (generated) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "(%s): connection assumption failed. Deleting generated connection",
|
|
|
|
|
nm_device_get_iface (device));
|
2014-06-20 20:13:14 +02:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_settings_connection_delete (connection, NULL, NULL);
|
2014-05-28 10:18:34 -04:00
|
|
|
}
|
|
|
|
|
}
|
2014-06-20 20:13:14 +02:00
|
|
|
|
|
|
|
|
return success;
|
2014-05-28 10:18:34 -04:00
|
|
|
}
|
|
|
|
|
|
2015-12-04 17:17:47 +01:00
|
|
|
static void
|
|
|
|
|
recheck_assume_connection_cb (NMDevice *device, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
recheck_assume_connection (user_data, device);
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-12 13:27:14 -05:00
|
|
|
static void
|
|
|
|
|
device_ip_iface_changed (NMDevice *device,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
const char *ip_iface = nm_device_get_ip_iface (device);
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
|
|
/* Remove NMDevice objects that are actually child devices of others,
|
|
|
|
|
* when the other device finally knows its IP interface name. For example,
|
|
|
|
|
* remove the PPP interface that's a child of a WWAN device, since it's
|
|
|
|
|
* not really a standalone NMDevice.
|
|
|
|
|
*/
|
|
|
|
|
for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
|
|
|
|
|
NMDevice *candidate = NM_DEVICE (iter->data);
|
|
|
|
|
|
|
|
|
|
if ( candidate != device
|
2014-10-15 21:17:45 -05:00
|
|
|
&& g_strcmp0 (nm_device_get_iface (candidate), ip_iface) == 0
|
|
|
|
|
&& nm_device_is_real (candidate)) {
|
2014-10-13 11:58:26 -05:00
|
|
|
remove_device (self, candidate, FALSE, FALSE);
|
2014-06-12 13:27:14 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-07 17:54:38 +01:00
|
|
|
static void
|
|
|
|
|
device_iface_changed (NMDevice *device,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
/* Virtual connections may refer to the new device name as
|
|
|
|
|
* parent device, retry to activate them.
|
|
|
|
|
*/
|
|
|
|
|
retry_connections_for_parent_device (self, device);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-09-24 16:58:07 -05:00
|
|
|
static void
|
|
|
|
|
device_realized (NMDevice *device,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMManager *self)
|
|
|
|
|
{
|
2016-09-14 14:15:24 +02:00
|
|
|
gboolean real = nm_device_is_real (device);
|
|
|
|
|
|
2014-10-06 11:21:54 -05:00
|
|
|
/* Emit D-Bus signals */
|
2016-09-14 14:15:24 +02:00
|
|
|
g_signal_emit (self, signals[real ? DEVICE_ADDED : DEVICE_REMOVED], 0, device);
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_DEVICES);
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
}
|
2014-10-06 11:21:54 -05:00
|
|
|
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
static void
|
|
|
|
|
_device_realize_finish (NMManager *self, NMDevice *device, const NMPlatformLink *plink)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (self));
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE (device));
|
|
|
|
|
|
|
|
|
|
nm_device_realize_finish (device, plink);
|
|
|
|
|
|
|
|
|
|
if (!nm_device_get_managed (device, FALSE))
|
2014-09-24 16:58:07 -05:00
|
|
|
return;
|
|
|
|
|
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
if (recheck_assume_connection (self, device))
|
2014-09-24 16:58:07 -05:00
|
|
|
return;
|
|
|
|
|
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
/* if we failed to assume a connection for the managed device, but the device
|
|
|
|
|
* is still unavailable. Set UNAVAILABLE state again, this time with NOW_MANAGED. */
|
|
|
|
|
nm_device_state_changed (device,
|
|
|
|
|
NM_DEVICE_STATE_UNAVAILABLE,
|
|
|
|
|
NM_DEVICE_STATE_REASON_NOW_MANAGED);
|
|
|
|
|
nm_device_emit_recheck_auto_activate (device);
|
2014-09-24 16:58:07 -05:00
|
|
|
}
|
|
|
|
|
|
2014-02-09 10:22:19 -06:00
|
|
|
/**
|
|
|
|
|
* add_device:
|
|
|
|
|
* @self: the #NMManager
|
|
|
|
|
* @device: the #NMDevice to add
|
2015-12-08 14:51:56 +01:00
|
|
|
* @error: (out): the #GError
|
2014-02-09 10:22:19 -06:00
|
|
|
*
|
|
|
|
|
* If successful, this function will increase the references count of @device.
|
|
|
|
|
* Callers should decrease the reference count.
|
|
|
|
|
*/
|
2015-12-08 14:51:56 +01:00
|
|
|
static gboolean
|
|
|
|
|
add_device (NMManager *self, NMDevice *device, GError **error)
|
2007-02-08 15:34:26 +00:00
|
|
|
{
|
2008-04-29 Dan Williams <dcbw@redhat.com>
Handle HAL dropouts better; allow NM to start up even if HAL isn't up yet.
* marshallers/nm-marshal.list
- Add marshaller
* src/NetworkManager.c
- (main): let the NMManager handle the NMHalManager
* src/nm-hal-manager.c
src/nm-hal-manager.h
- convert to a GObject, and emit singals when stuff changes. Let the
NMManager handle the signals, instead of the NMHalManager calling
into the NMManager.
* src/nm-manager.c
src/nm-manager.h
- (remove_one_device): consolidate device removals here
- (dispose): use remove_one_device()
- (nm_manager_get_device_by_udi): make static
- (deferred_hal_manager_query_devices): idle handler to query the HAL
manager for devices at startup or wakeup time
- (nm_manager_new): create and monitor the HAL manager
- (hal_manager_udi_added_cb): new function; do what
nm_manager_add_device() used to do when signalled by the hal manager
- (hal_manager_udi_removed_cb): new function; do what
nm_manager_remove_device() used to do when signalled by the hal
manager
- (hal_manager_rfkill_changed_cb): handle rfkill changes from the
hal manager
- (hal_manager_hal_reappeared_cb): when HAL comes back, remove devices
in our device list that aren't known to HAL
- (impl_manager_sleep): on wakeup, re-add devices from an idle handler;
see comments on nm-hal-manager.c::nm_manager_state_changed() a few
commits ago
- (nm_manager_get_device_by_path, nm_manager_is_udi_managed,
nm_manager_activation_pending, nm_manager_wireless_enabled,
nm_manager_wireless_hardware_enabled,
nm_manager_set_wireless_hardware_enabled): remove, unused
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3619 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-29 23:03:00 +00:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2014-09-24 16:58:07 -05:00
|
|
|
const char *iface, *type_desc;
|
2011-11-18 12:02:58 -06:00
|
|
|
RfKillType rtype;
|
2014-02-09 10:22:19 -06:00
|
|
|
GSList *iter, *remove = NULL;
|
2014-09-24 14:57:14 -05:00
|
|
|
int ifindex;
|
2015-04-03 10:08:52 -04:00
|
|
|
const char *dbus_path;
|
2009-09-04 16:55:48 +02:00
|
|
|
|
2014-02-09 10:22:19 -06:00
|
|
|
/* No duplicates */
|
2014-09-24 14:57:14 -05:00
|
|
|
ifindex = nm_device_get_ifindex (device);
|
2015-12-08 14:51:56 +01:00
|
|
|
if (ifindex > 0 && nm_manager_get_device_by_ifindex (self, ifindex)) {
|
|
|
|
|
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
|
2016-02-16 16:21:52 +01:00
|
|
|
"A device with ifindex %d already exists", ifindex);
|
2015-12-08 14:51:56 +01:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
2014-02-09 10:22:19 -06:00
|
|
|
|
|
|
|
|
/* Remove existing devices owned by the new device; eg remove ethernet
|
|
|
|
|
* ports that are owned by a WWAN modem, since udev may announce them
|
|
|
|
|
* before the modem is fully discovered.
|
|
|
|
|
*
|
|
|
|
|
* FIXME: use parent/child device relationships instead of removing
|
|
|
|
|
* the child NMDevice entirely
|
|
|
|
|
*/
|
|
|
|
|
for (iter = priv->devices; iter; iter = iter->next) {
|
2014-10-15 21:17:45 -05:00
|
|
|
NMDevice *candidate = iter->data;
|
|
|
|
|
|
|
|
|
|
iface = nm_device_get_ip_iface (candidate);
|
|
|
|
|
if (nm_device_is_real (candidate) && nm_device_owns_iface (device, iface))
|
|
|
|
|
remove = g_slist_prepend (remove, candidate);
|
2009-09-04 16:55:48 +02:00
|
|
|
}
|
2014-02-09 10:22:19 -06:00
|
|
|
for (iter = remove; iter; iter = iter->next)
|
2014-10-13 11:58:26 -05:00
|
|
|
remove_device (self, NM_DEVICE (iter->data), FALSE, FALSE);
|
2014-02-09 10:22:19 -06:00
|
|
|
g_slist_free (remove);
|
2009-09-04 16:55:48 +02:00
|
|
|
|
2014-02-09 10:22:19 -06:00
|
|
|
priv->devices = g_slist_append (priv->devices, g_object_ref (device));
|
2009-10-04 23:36:06 -07:00
|
|
|
|
2015-12-07 19:42:59 +01:00
|
|
|
g_signal_connect (device, NM_DEVICE_STATE_CHANGED,
|
2014-02-10 11:13:55 +01:00
|
|
|
G_CALLBACK (manager_device_state_changed),
|
|
|
|
|
self);
|
2007-03-02 Tambet Ingo <tambet@ximian.com>
* libnm-glib/nm-device-802-11-wireless.c: Cache networks (bssids) list.
We get signalled when it changes.
* libnm-glib/nm-client.c: Cache NMState and device list, we get signalled
when it changes.
* libnm-glib/nm-device.c: Cache the device state property.
* libnm-glib/nm-access-point.c: Cache the strength property.
* src/nm-device-802-11-wireless.c: Fix wireless device scanning scheduler.
The new algorithm is to start from SCAN_INTERVAL_MIN (currently defined as 0)
and add a SCAN_INTERVAL_STEP (currently 20 seconds) with each successful scan
until SCAN_INTERVAL_MAX (currently 120 seconds) is reached. Do not scan while
the device is down, activating, or activated (in case of A/B/G cards).
Remove some old dead ifdef'ed out code that used to configure wireless devices,
it's all done through supplicant now.
* src/supplicant-manager/nm-supplicant-interface.c: Fix the reference
counting issues with pending calls which caused leaks and crashes when
interface was removed (now that the interface actually gets removed).
* src/nm-call-store.c: Make a copy of data before running a foreach
with user callback on it - The most common usage pattern is to cancel
(and thus remove) all pending calls with foreach which would modify
the hash table we're iterating over.
* src/nm-manager.c: When a device is added, make sure it is "up". When
it's removed or disabled due to disabling wireless or networking, bring
it down.
* include/NetworkManager.h: Add new device state NM_DEVICE_STATE_DOWN.
* src/nm-device-802-11-wireless.c:
* src/nm-device-802-3-ethernet.c:
* src/nm-device.c:
- Remove "init" virtual function, all gobjects have a place for that
already (constructor).
- Replace "start" virtual function with "bring_up", devices can be
brought up and down more than just on startup now.
- Add "is_up" virtual function.
- Implement one way to bring a device down instead of previous 4 different
ways, each of witch did something different.
* src/NetworkManagerUtils.c (nm_dev_sock_open): This doesn't need an NMDevice,
all it needs is the device interface.
Get rid of NMData.dev_list (3 members to go).
Get rif of NMData in a lot of places.
* gnome/libnm_glib/libnm_glib.c: Make it compile again.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2395 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2007-03-02 09:30:48 +00:00
|
|
|
|
2012-06-01 15:27:39 -05:00
|
|
|
g_signal_connect (device, NM_DEVICE_AUTH_REQUEST,
|
|
|
|
|
G_CALLBACK (device_auth_request_cb),
|
|
|
|
|
self);
|
|
|
|
|
|
2014-02-10 08:49:47 -06:00
|
|
|
g_signal_connect (device, NM_DEVICE_REMOVED,
|
|
|
|
|
G_CALLBACK (device_removed_cb),
|
|
|
|
|
self);
|
|
|
|
|
|
2015-12-04 17:17:47 +01:00
|
|
|
g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME,
|
|
|
|
|
G_CALLBACK (recheck_assume_connection_cb),
|
|
|
|
|
self);
|
|
|
|
|
|
2014-06-12 13:27:14 -05:00
|
|
|
g_signal_connect (device, "notify::" NM_DEVICE_IP_IFACE,
|
|
|
|
|
G_CALLBACK (device_ip_iface_changed),
|
|
|
|
|
self);
|
2016-01-07 17:54:38 +01:00
|
|
|
|
|
|
|
|
g_signal_connect (device, "notify::" NM_DEVICE_IFACE,
|
|
|
|
|
G_CALLBACK (device_iface_changed),
|
|
|
|
|
self);
|
|
|
|
|
|
2014-09-24 16:58:07 -05:00
|
|
|
g_signal_connect (device, "notify::" NM_DEVICE_REAL,
|
|
|
|
|
G_CALLBACK (device_realized),
|
|
|
|
|
self);
|
2014-06-12 13:27:14 -05:00
|
|
|
|
2013-08-13 17:45:34 -04:00
|
|
|
if (priv->startup) {
|
|
|
|
|
g_signal_connect (device, "notify::" NM_DEVICE_HAS_PENDING_ACTION,
|
|
|
|
|
G_CALLBACK (device_has_pending_action_changed),
|
|
|
|
|
self);
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-18 12:02:58 -06:00
|
|
|
/* Update global rfkill state for this device type with the device's
|
|
|
|
|
* rfkill state, and then set this device's rfkill state based on the
|
|
|
|
|
* global state.
|
|
|
|
|
*/
|
|
|
|
|
rtype = nm_device_get_rfkill_type (device);
|
2011-04-13 21:58:25 -05:00
|
|
|
if (rtype != RFKILL_TYPE_UNKNOWN) {
|
|
|
|
|
nm_manager_rfkill_update (self, rtype);
|
2014-09-24 16:58:07 -05:00
|
|
|
nm_device_set_enabled (device, radio_enabled_for_type (self, rtype, TRUE));
|
2011-04-13 21:58:25 -05:00
|
|
|
}
|
|
|
|
|
|
2014-02-09 10:22:19 -06:00
|
|
|
iface = nm_device_get_iface (device);
|
|
|
|
|
g_assert (iface);
|
2009-07-07 14:24:12 -04:00
|
|
|
type_desc = nm_device_get_type_desc (device);
|
|
|
|
|
g_assert (type_desc);
|
2008-04-07 Dan Williams <dcbw@redhat.com>
* include/NetworkManager.h
- Remove the DOWN and CANCELLED device states
- Add UNMANAGED and UNAVAILABLE device states
- Document the device states
* introspection/nm-device.xml
src/nm-device-interface.c
src/nm-device-interface.h
- Add the 'managed' property
* test/nm-tool.c
- (detail_device): print out device state
* src/NetworkManagerSystem.h
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerDebian.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerMandriva.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerSuSE.c
- (nm_system_device_get_system_config, nm_system_device_get_disabled
nm_system_device_free_system_config): remove; they were unused and
their functionality should be re-implemented in each distro's
system settings service plugin
* src/nm-gsm-device.c
src/nm-gsm-device.h
src/nm-cdma-device.c
src/nm-cdma-device.h
- (*_new): take the 'managed' argument
* src/nm-device.c
- (nm_device_set_address): remove, fold into nm_device_bring_up()
- (nm_device_init): start in unmanaged state, not disconnected
- (constructor): don't start device until the system settings service
has had a chance to figure out if the device is managed or not
- (nm_device_deactivate, nm_device_bring_up, nm_device_bring_down):
don't set device state here, let callers handle that as appropriate
- (nm_device_dispose): don't touch the device if it's not managed
- (set_property, get_property, nm_device_class_init): implement the
'managed' property
- (nm_device_state_changed): bring the device up if its now managed,
and deactivate it if it used to be active
- (nm_device_get_managed, nm_device_set_managed): do the right thing
with the managed state
* src/nm-hal-manager.c
- (wired_device_creator, wireless_device_creator, modem_device_creator):
take initial managed state and pass it along to device constructors
- (create_device_and_add_to_list): get managed state and pass to
type creators
* src/nm-device-802-11-wireless.c
- (real_can_activate): fold in most of
nm_device_802_11_wireless_can_activate()
- (can_scan): can't scan in UNAVAILABLE or UNMANAGED
- (link_timeout_cb): instead of deactivating, change device state and
let the device state handler to it
- (real_update_hw_address): clean up
- (state_changed_cb): when entering UNAVAILABLE state, schedule an idle
handler to transition to DISCONNECTED if the device isn't rfkilled
* src/nm-device-802-3-ethernet.c
- (set_carrier): move above callers and get rid of prototype
- (device_state_changed): when entering UNAVAILABLE state, schedule an
idle handler to transition to DISCONNECTED if the device has a
carrier
- (real_update_hw_address): clean up
- (link_timeout_cb, ppp_state_changed): change state instead of calling
deactivation directly as deactivation doesn't change state anymore
* src/NetworkManagerPolicy.c
- (schedule_activate_check): yay, remove wireless_enabled hack since
the NMManager and wireless devices work that out themselves now
- (device_state_changed): change to a switch and update for new device
states
- (device_carrier_changed): remove; device handles this now through
state changes
- (device_added): don't care about carrier any more; the initial
activation check will happen when the device transitions to
DISCONNECTED
* src/nm-manager.c
- (dispose): clear unmanaged devices
- (handle_unmanaged_devices): update unmanaged device list and toggle
the managed property on each device when needed
- (system_settings_properties_changed_cb): handle signals from the
system settings service
- (system_settings_get_unmanaged_devices_cb): handle callback from
getting the unmanaged device list method call
- (query_unmanaged_devices): ask the system settings service for its
list of unmanaged devices
- (nm_manager_name_owner_changed, initial_get_connections): get unmanaged
devices
- (manager_set_wireless_enabled): push rfkill state down to wireless
devices directly and let them handle the necessary state transitions
- (manager_device_state_changed): update for new device states
- (nm_manager_add_device): set initial rfkill state on wireless devices
- (nm_manager_remove_device): don't touch the device if it's unmanaged
- (nm_manager_activate_connection): return error if the device is
unmanaged
- (nm_manager_sleep): handle new device states correctly; don't change
the state of unavailable/unmanaged devices
* libnm-glib/nm-device-802-11-wireless.c
- (state_changed_cb): update for new device states
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3540 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 02:58:02 +00:00
|
|
|
|
2016-05-17 12:12:50 +02:00
|
|
|
nm_device_set_unmanaged_by_user_settings (device, nm_settings_get_unmanaged_specs (priv->settings));
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
|
|
|
|
|
nm_device_set_unmanaged_flags (device,
|
|
|
|
|
NM_UNMANAGED_SLEEPING,
|
|
|
|
|
manager_sleeping (self));
|
2014-03-31 21:45:54 -05:00
|
|
|
|
2015-04-03 10:08:52 -04:00
|
|
|
dbus_path = nm_exported_object_export (NM_EXPORTED_OBJECT (device));
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "(%s): new %s device (%s)", iface, type_desc, dbus_path);
|
2015-04-03 10:08:52 -04:00
|
|
|
|
2010-10-27 20:05:23 -05:00
|
|
|
nm_settings_device_added (priv->settings, device);
|
2014-10-06 11:21:54 -05:00
|
|
|
g_signal_emit (self, signals[INTERNAL_DEVICE_ADDED], 0, device);
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_ALL_DEVICES);
|
2009-08-05 18:03:09 -04:00
|
|
|
|
2015-11-24 16:43:18 +01:00
|
|
|
for (iter = priv->devices; iter; iter = iter->next) {
|
|
|
|
|
NMDevice *d = iter->data;
|
|
|
|
|
|
|
|
|
|
if (d != device)
|
|
|
|
|
nm_device_notify_new_device_added (d, device);
|
|
|
|
|
}
|
2015-12-08 14:51:56 +01:00
|
|
|
|
2016-01-07 17:54:38 +01:00
|
|
|
/* Virtual connections may refer to the new device as
|
|
|
|
|
* parent device, retry to activate them.
|
|
|
|
|
*/
|
|
|
|
|
retry_connections_for_parent_device (self, device);
|
|
|
|
|
|
2015-12-08 14:51:56 +01:00
|
|
|
return TRUE;
|
2007-02-08 15:34:26 +00:00
|
|
|
}
|
|
|
|
|
|
2014-09-05 13:15:44 -05:00
|
|
|
/*******************************************************************/
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-02-09 10:22:19 -06:00
|
|
|
static void
|
|
|
|
|
factory_device_added_cb (NMDeviceFactory *factory,
|
|
|
|
|
NMDevice *device,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
NMManager *self = user_data;
|
2014-09-05 08:50:02 -05:00
|
|
|
GError *error = NULL;
|
|
|
|
|
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
g_return_if_fail (NM_IS_MANAGER (self));
|
|
|
|
|
|
2016-01-10 14:56:05 +01:00
|
|
|
if (nm_device_realize_start (device, NULL, NULL, &error)) {
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
add_device (self, device, NULL);
|
|
|
|
|
_device_realize_finish (self, device, NULL);
|
2014-09-24 16:58:07 -05:00
|
|
|
} else {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE, "(%s): failed to realize device: %s",
|
|
|
|
|
nm_device_get_iface (device), error->message);
|
2014-09-05 08:50:02 -05:00
|
|
|
g_error_free (error);
|
|
|
|
|
}
|
2014-02-09 10:22:19 -06:00
|
|
|
}
|
2012-02-05 23:18:32 -06:00
|
|
|
|
2014-02-09 10:22:19 -06:00
|
|
|
static gboolean
|
|
|
|
|
factory_component_added_cb (NMDeviceFactory *factory,
|
|
|
|
|
GObject *component,
|
|
|
|
|
gpointer user_data)
|
2012-02-05 23:18:32 -06:00
|
|
|
{
|
2016-04-28 14:10:06 +02:00
|
|
|
NMManager *self = user_data;
|
2015-11-24 16:43:18 +01:00
|
|
|
GSList *iter;
|
|
|
|
|
|
2016-04-28 14:10:06 +02:00
|
|
|
g_return_val_if_fail (self, FALSE);
|
2015-11-24 16:43:18 +01:00
|
|
|
|
2016-04-28 14:10:06 +02:00
|
|
|
for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
|
2015-11-24 16:43:18 +01:00
|
|
|
if (nm_device_notify_component_added ((NMDevice *) iter->data, component))
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
2012-02-05 23:18:32 -06:00
|
|
|
}
|
|
|
|
|
|
2014-09-17 14:17:30 -05:00
|
|
|
static void
|
|
|
|
|
_register_device_factory (NMDeviceFactory *factory, gpointer user_data)
|
2014-09-05 15:05:40 -05:00
|
|
|
{
|
2014-09-17 14:17:30 -05:00
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
2014-09-05 15:05:40 -05:00
|
|
|
|
|
|
|
|
g_signal_connect (factory,
|
|
|
|
|
NM_DEVICE_FACTORY_DEVICE_ADDED,
|
|
|
|
|
G_CALLBACK (factory_device_added_cb),
|
|
|
|
|
self);
|
|
|
|
|
g_signal_connect (factory,
|
|
|
|
|
NM_DEVICE_FACTORY_COMPONENT_ADDED,
|
|
|
|
|
G_CALLBACK (factory_component_added_cb),
|
|
|
|
|
self);
|
2012-02-05 23:18:32 -06:00
|
|
|
}
|
|
|
|
|
|
2014-09-05 15:57:40 -05:00
|
|
|
/*******************************************************************/
|
|
|
|
|
|
2009-01-19 11:01:00 +02:00
|
|
|
static void
|
2014-03-07 19:04:38 +01:00
|
|
|
platform_link_added (NMManager *self,
|
|
|
|
|
int ifindex,
|
2016-01-10 15:13:20 +01:00
|
|
|
const NMPlatformLink *plink)
|
2009-01-19 11:01:00 +02:00
|
|
|
{
|
2014-09-17 14:17:30 -05:00
|
|
|
NMDeviceFactory *factory;
|
2012-02-10 12:21:10 -06:00
|
|
|
NMDevice *device = NULL;
|
2015-04-14 14:43:31 +02:00
|
|
|
gboolean nm_plugin_missing = FALSE;
|
2014-10-15 21:17:45 -05:00
|
|
|
GSList *iter;
|
2009-01-19 11:01:00 +02:00
|
|
|
|
2013-05-24 17:30:31 -03:00
|
|
|
g_return_if_fail (ifindex > 0);
|
2012-03-06 11:38:03 -06:00
|
|
|
|
2014-09-05 13:15:44 -05:00
|
|
|
if (nm_manager_get_device_by_ifindex (self, ifindex))
|
2013-05-24 17:30:31 -03:00
|
|
|
return;
|
2009-01-19 11:01:00 +02:00
|
|
|
|
2014-10-15 21:17:45 -05:00
|
|
|
/* Let unrealized devices try to realize themselves with the link */
|
|
|
|
|
for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
|
|
|
|
|
NMDevice *candidate = iter->data;
|
|
|
|
|
gboolean compatible = TRUE;
|
2016-04-04 19:42:04 +02:00
|
|
|
gs_free_error GError *error = NULL;
|
2014-10-09 12:42:29 -05:00
|
|
|
|
2014-10-15 21:17:45 -05:00
|
|
|
if (strcmp (nm_device_get_iface (candidate), plink->name))
|
|
|
|
|
continue;
|
2014-10-09 12:42:29 -05:00
|
|
|
|
2014-10-15 21:17:45 -05:00
|
|
|
if (nm_device_is_real (candidate)) {
|
|
|
|
|
/* Ignore the link added event since there's already a realized
|
|
|
|
|
* device with the link's name.
|
|
|
|
|
*/
|
|
|
|
|
return;
|
2016-01-10 14:56:05 +01:00
|
|
|
} else if (nm_device_realize_start (candidate, plink, &compatible, &error)) {
|
2014-10-09 12:42:29 -05:00
|
|
|
/* Success */
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
_device_realize_finish (self, candidate, plink);
|
2014-09-24 16:58:07 -05:00
|
|
|
return;
|
|
|
|
|
}
|
2014-10-09 12:42:29 -05:00
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "(%s): failed to realize from plink: '%s'",
|
|
|
|
|
plink->name, error->message);
|
2014-10-09 12:42:29 -05:00
|
|
|
|
2014-10-15 21:17:45 -05:00
|
|
|
/* Try next unrealized device */
|
2014-09-24 16:58:07 -05:00
|
|
|
}
|
|
|
|
|
|
2014-09-17 14:17:30 -05:00
|
|
|
/* Try registered device factories */
|
|
|
|
|
factory = nm_device_factory_manager_find_factory_for_link_type (plink->type);
|
|
|
|
|
if (factory) {
|
2015-05-06 09:53:44 -05:00
|
|
|
gboolean ignore = FALSE;
|
2016-04-04 19:42:04 +02:00
|
|
|
gs_free_error GError *error = NULL;
|
2015-05-06 09:53:44 -05:00
|
|
|
|
2014-09-05 08:50:02 -05:00
|
|
|
device = nm_device_factory_create_device (factory, plink->name, plink, NULL, &ignore, &error);
|
2014-09-17 14:17:30 -05:00
|
|
|
if (!device) {
|
2015-05-06 09:53:44 -05:00
|
|
|
if (!ignore) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGW (LOGD_HW, "%s: factory failed to create device: %s",
|
|
|
|
|
plink->name, error->message);
|
2016-04-12 10:19:21 +02:00
|
|
|
} else {
|
|
|
|
|
_LOGD (LOGD_HW, "%s: factory failed to create device: %s",
|
|
|
|
|
plink->name, error->message);
|
2015-05-06 09:53:44 -05:00
|
|
|
}
|
2012-02-05 23:18:32 -06:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (device == NULL) {
|
2013-10-22 17:11:24 +02:00
|
|
|
switch (plink->type) {
|
2016-06-14 11:19:15 -05:00
|
|
|
case NM_LINK_TYPE_WWAN_NET:
|
2015-05-06 09:53:44 -05:00
|
|
|
case NM_LINK_TYPE_BNEP:
|
2014-05-09 10:30:04 -05:00
|
|
|
case NM_LINK_TYPE_OLPC_MESH:
|
2014-06-27 17:02:23 +02:00
|
|
|
case NM_LINK_TYPE_TEAM:
|
2014-05-09 10:30:04 -05:00
|
|
|
case NM_LINK_TYPE_WIFI:
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_HW, "(%s): '%s' plugin not available; creating generic device",
|
|
|
|
|
plink->name, nm_link_type_to_string (plink->type));
|
2015-04-14 14:43:31 +02:00
|
|
|
nm_plugin_missing = TRUE;
|
2014-05-09 10:30:04 -05:00
|
|
|
/* fall through */
|
2013-04-25 15:46:39 -04:00
|
|
|
default:
|
2013-10-22 17:11:24 +02:00
|
|
|
device = nm_device_generic_new (plink);
|
2013-04-25 15:46:39 -04:00
|
|
|
break;
|
2013-04-17 10:41:15 -04:00
|
|
|
}
|
2012-02-05 23:18:32 -06:00
|
|
|
}
|
|
|
|
|
|
2014-02-09 10:22:19 -06:00
|
|
|
if (device) {
|
2016-04-04 19:42:04 +02:00
|
|
|
gs_free_error GError *error = NULL;
|
|
|
|
|
|
2015-04-14 14:43:31 +02:00
|
|
|
if (nm_plugin_missing)
|
|
|
|
|
nm_device_set_nm_plugin_missing (device, TRUE);
|
2016-01-10 14:56:05 +01:00
|
|
|
if (nm_device_realize_start (device, plink, NULL, &error)) {
|
2015-12-08 14:51:56 +01:00
|
|
|
add_device (self, device, NULL);
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
_device_realize_finish (self, device, plink);
|
2014-09-24 16:58:07 -05:00
|
|
|
} else {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE, "%s: failed to realize device: %s",
|
|
|
|
|
plink->name, error->message);
|
2015-08-25 16:10:40 +02:00
|
|
|
}
|
2014-02-09 10:22:19 -06:00
|
|
|
g_object_unref (device);
|
|
|
|
|
}
|
2009-01-19 11:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
core: delay handling of link-changed platform event in manager
Backtrace:
NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global
NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond
NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1)
NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged
NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
#0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0
#1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0
#2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0
#3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040
#4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801
#5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6
#6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6
#7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0
#8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry=
NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425
#13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704
#14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0)
at platform/nm-linux-platform.c:1951
#15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491
#16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573
#17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588
#18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1)
at platform/nm-linux-platform.c:1954
#19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753
#20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141
#21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437
#22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:1049
#23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781
#24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752
#25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128
#26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:8319
#27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343
#28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0
#30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0
#31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
2015-06-24 13:42:16 +02:00
|
|
|
typedef struct {
|
|
|
|
|
NMManager *self;
|
|
|
|
|
int ifindex;
|
|
|
|
|
} PlatformLinkCbData;
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
_platform_link_cb_idle (PlatformLinkCbData *data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = data->self;
|
2015-12-04 14:11:00 +01:00
|
|
|
const NMPlatformLink *l;
|
core: delay handling of link-changed platform event in manager
Backtrace:
NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global
NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond
NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1)
NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged
NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
#0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0
#1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0
#2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0
#3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040
#4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801
#5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6
#6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6
#7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0
#8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry=
NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425
#13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704
#14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0)
at platform/nm-linux-platform.c:1951
#15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491
#16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573
#17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588
#18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1)
at platform/nm-linux-platform.c:1954
#19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753
#20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141
#21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437
#22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:1049
#23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781
#24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752
#25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128
#26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:8319
#27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343
#28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0
#30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0
#31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
2015-06-24 13:42:16 +02:00
|
|
|
|
2015-12-04 14:11:00 +01:00
|
|
|
if (!self)
|
|
|
|
|
goto out;
|
core: delay handling of link-changed platform event in manager
Backtrace:
NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global
NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond
NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1)
NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged
NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
#0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0
#1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0
#2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0
#3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040
#4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801
#5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6
#6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6
#7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0
#8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry=
NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425
#13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704
#14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0)
at platform/nm-linux-platform.c:1951
#15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491
#16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573
#17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588
#18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1)
at platform/nm-linux-platform.c:1954
#19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753
#20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141
#21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437
#22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:1049
#23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781
#24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752
#25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128
#26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:8319
#27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343
#28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0
#30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0
#31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
2015-06-24 13:42:16 +02:00
|
|
|
|
2015-12-04 14:11:00 +01:00
|
|
|
g_object_remove_weak_pointer (G_OBJECT (self), (gpointer *) &data->self);
|
core: delay handling of link-changed platform event in manager
Backtrace:
NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global
NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond
NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1)
NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged
NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
#0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0
#1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0
#2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0
#3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040
#4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801
#5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6
#6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6
#7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0
#8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry=
NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425
#13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704
#14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0)
at platform/nm-linux-platform.c:1951
#15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491
#16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573
#17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588
#18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1)
at platform/nm-linux-platform.c:1954
#19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753
#20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141
#21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437
#22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:1049
#23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781
#24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752
#25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128
#26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:8319
#27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343
#28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0
#30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0
#31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
2015-06-24 13:42:16 +02:00
|
|
|
|
2015-12-04 14:11:00 +01:00
|
|
|
l = nm_platform_link_get (NM_PLATFORM_GET, data->ifindex);
|
|
|
|
|
if (l) {
|
|
|
|
|
NMPlatformLink pllink;
|
|
|
|
|
|
|
|
|
|
pllink = *l; /* make a copy of the link instance */
|
|
|
|
|
platform_link_added (self, data->ifindex, &pllink);
|
|
|
|
|
} else {
|
|
|
|
|
NMDevice *device;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
device = nm_manager_get_device_by_ifindex (self, data->ifindex);
|
|
|
|
|
if (device) {
|
2016-01-14 17:24:25 +01:00
|
|
|
if (nm_device_is_software (device)) {
|
2015-12-09 15:41:39 +01:00
|
|
|
/* Our software devices stick around until their connection is removed */
|
2015-12-04 14:11:00 +01:00
|
|
|
if (!nm_device_unrealize (device, FALSE, &error)) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE, "(%s): failed to unrealize: %s",
|
|
|
|
|
nm_device_get_iface (device),
|
|
|
|
|
error->message);
|
2015-12-04 14:11:00 +01:00
|
|
|
g_clear_error (&error);
|
2014-09-24 16:58:07 -05:00
|
|
|
remove_device (self, device, FALSE, TRUE);
|
2014-09-24 15:13:19 -05:00
|
|
|
}
|
2015-12-04 14:11:00 +01:00
|
|
|
} else {
|
2015-12-09 15:41:39 +01:00
|
|
|
/* Hardware and external devices always get removed when their kernel link is gone */
|
2015-12-04 14:11:00 +01:00
|
|
|
remove_device (self, device, FALSE, TRUE);
|
2014-09-24 15:13:19 -05:00
|
|
|
}
|
core: delay handling of link-changed platform event in manager
Backtrace:
NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global
NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond
NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1)
NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged
NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
#0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0
#1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0
#2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0
#3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040
#4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801
#5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6
#6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6
#7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0
#8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry=
NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425
#13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704
#14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0)
at platform/nm-linux-platform.c:1951
#15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491
#16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573
#17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588
#18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1)
at platform/nm-linux-platform.c:1954
#19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753
#20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141
#21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437
#22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:1049
#23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781
#24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752
#25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128
#26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:8319
#27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343
#28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0
#30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0
#31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
2015-06-24 13:42:16 +02:00
|
|
|
}
|
|
|
|
|
}
|
2015-12-04 14:11:00 +01:00
|
|
|
|
|
|
|
|
out:
|
core: delay handling of link-changed platform event in manager
Backtrace:
NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global
NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond
NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1)
NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged
NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
#0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0
#1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0
#2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0
#3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040
#4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801
#5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6
#6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6
#7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0
#8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry=
NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425
#13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704
#14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0)
at platform/nm-linux-platform.c:1951
#15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491
#16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573
#17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588
#18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1)
at platform/nm-linux-platform.c:1954
#19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753
#20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141
#21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437
#22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:1049
#23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781
#24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752
#25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128
#26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:8319
#27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343
#28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0
#30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0
#31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
2015-06-24 13:42:16 +02:00
|
|
|
g_slice_free (PlatformLinkCbData, data);
|
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-04-29 Dan Williams <dcbw@redhat.com>
Handle HAL dropouts better; allow NM to start up even if HAL isn't up yet.
* marshallers/nm-marshal.list
- Add marshaller
* src/NetworkManager.c
- (main): let the NMManager handle the NMHalManager
* src/nm-hal-manager.c
src/nm-hal-manager.h
- convert to a GObject, and emit singals when stuff changes. Let the
NMManager handle the signals, instead of the NMHalManager calling
into the NMManager.
* src/nm-manager.c
src/nm-manager.h
- (remove_one_device): consolidate device removals here
- (dispose): use remove_one_device()
- (nm_manager_get_device_by_udi): make static
- (deferred_hal_manager_query_devices): idle handler to query the HAL
manager for devices at startup or wakeup time
- (nm_manager_new): create and monitor the HAL manager
- (hal_manager_udi_added_cb): new function; do what
nm_manager_add_device() used to do when signalled by the hal manager
- (hal_manager_udi_removed_cb): new function; do what
nm_manager_remove_device() used to do when signalled by the hal
manager
- (hal_manager_rfkill_changed_cb): handle rfkill changes from the
hal manager
- (hal_manager_hal_reappeared_cb): when HAL comes back, remove devices
in our device list that aren't known to HAL
- (impl_manager_sleep): on wakeup, re-add devices from an idle handler;
see comments on nm-hal-manager.c::nm_manager_state_changed() a few
commits ago
- (nm_manager_get_device_by_path, nm_manager_is_udi_managed,
nm_manager_activation_pending, nm_manager_wireless_enabled,
nm_manager_wireless_hardware_enabled,
nm_manager_set_wireless_hardware_enabled): remove, unused
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3619 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-29 23:03:00 +00:00
|
|
|
static void
|
2014-03-07 19:04:38 +01:00
|
|
|
platform_link_cb (NMPlatform *platform,
|
2015-06-24 15:22:46 +02:00
|
|
|
NMPObjectType obj_type,
|
2014-03-07 19:04:38 +01:00
|
|
|
int ifindex,
|
|
|
|
|
NMPlatformLink *plink,
|
|
|
|
|
NMPlatformSignalChangeType change_type,
|
|
|
|
|
gpointer user_data)
|
2007-02-08 15:34:26 +00:00
|
|
|
{
|
core: delay handling of link-changed platform event in manager
Backtrace:
NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global
NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond
NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1)
NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged
NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
#0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0
#1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0
#2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0
#3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040
#4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801
#5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6
#6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6
#7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0
#8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry=
NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425
#13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704
#14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0)
at platform/nm-linux-platform.c:1951
#15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491
#16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573
#17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588
#18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1)
at platform/nm-linux-platform.c:1954
#19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753
#20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141
#21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437
#22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:1049
#23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781
#24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752
#25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128
#26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:8319
#27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343
#28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0
#30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0
#31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
2015-06-24 13:42:16 +02:00
|
|
|
PlatformLinkCbData *data;
|
|
|
|
|
|
2014-03-07 19:04:38 +01:00
|
|
|
switch (change_type) {
|
|
|
|
|
case NM_PLATFORM_SIGNAL_ADDED:
|
core: delay handling of link-changed platform event in manager
Backtrace:
NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global
NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond
NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1)
NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged
NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
#0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0
#1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0
#2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0
#3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040
#4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801
#5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6
#6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6
#7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0
#8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry=
NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425
#13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704
#14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0)
at platform/nm-linux-platform.c:1951
#15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491
#16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573
#17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588
#18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1)
at platform/nm-linux-platform.c:1954
#19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753
#20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141
#21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437
#22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:1049
#23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781
#24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752
#25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128
#26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:8319
#27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343
#28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0
#30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0
#31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
2015-06-24 13:42:16 +02:00
|
|
|
case NM_PLATFORM_SIGNAL_REMOVED:
|
|
|
|
|
data = g_slice_new (PlatformLinkCbData);
|
|
|
|
|
data->self = NM_MANAGER (user_data);
|
|
|
|
|
data->ifindex = ifindex;
|
|
|
|
|
g_object_add_weak_pointer (G_OBJECT (data->self), (gpointer *) &data->self);
|
|
|
|
|
g_idle_add ((GSourceFunc) _platform_link_cb_idle, data);
|
2014-03-07 19:04:38 +01:00
|
|
|
break;
|
core: delay handling of link-changed platform event in manager
Backtrace:
NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global
NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond
NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1)
NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged
NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
#0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0
#1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0
#2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0
#3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040
#4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801
#5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6
#6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6
#7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0
#8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry=
NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425
#13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704
#14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0)
at platform/nm-linux-platform.c:1951
#15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491
#16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573
#17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588
#18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1)
at platform/nm-linux-platform.c:1954
#19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753
#20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141
#21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437
#22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:1049
#23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781
#24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752
#25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128
#26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:8319
#27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343
#28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0
#30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0
#31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
2015-06-24 13:42:16 +02:00
|
|
|
default:
|
2014-03-07 19:04:38 +01:00
|
|
|
break;
|
core: delay handling of link-changed platform event in manager
Backtrace:
NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global
NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond
NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1)
NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged
NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
#0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0
#1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0
#2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0
#3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040
#4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801
#5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6
#6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6
#7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0
#8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry=
NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425
#13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704
#14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0)
at platform/nm-linux-platform.c:1951
#15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491
#16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573
#17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588
#18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1)
at platform/nm-linux-platform.c:1954
#19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753
#20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141
#21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437
#22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:1049
#23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781
#24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752
#25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128
#26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:8319
#27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343
#28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0
#30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0
#31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
2015-06-24 13:42:16 +02:00
|
|
|
}
|
2007-02-08 15:34:26 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-04 16:54:51 +02:00
|
|
|
static void
|
|
|
|
|
platform_query_devices (NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
GArray *links_array;
|
|
|
|
|
NMPlatformLink *links;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
links_array = nm_platform_link_get_all (NM_PLATFORM_GET);
|
|
|
|
|
links = (NMPlatformLink *) links_array->data;
|
|
|
|
|
for (i = 0; i < links_array->len; i++)
|
core: delay handling of link-changed platform event in manager
Backtrace:
NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global
NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond
NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1)
NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged
NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
#0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0
#1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0
#2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0
#3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040
#4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801
#5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6
#6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6
#7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0
#8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry=
NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425
#13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704
#14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0)
at platform/nm-linux-platform.c:1951
#15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491
#16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573
#17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588
#18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1)
at platform/nm-linux-platform.c:1954
#19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753
#20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141
#21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437
#22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:1049
#23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781
#24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752
#25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128
#26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:8319
#27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343
#28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0
#30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0
#31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
2015-06-24 13:42:16 +02:00
|
|
|
platform_link_added (self, links[i].ifindex, &links[i]);
|
2015-05-04 16:54:51 +02:00
|
|
|
|
|
|
|
|
g_array_unref (links_array);
|
|
|
|
|
}
|
|
|
|
|
|
2008-04-29 Dan Williams <dcbw@redhat.com>
Handle HAL dropouts better; allow NM to start up even if HAL isn't up yet.
* marshallers/nm-marshal.list
- Add marshaller
* src/NetworkManager.c
- (main): let the NMManager handle the NMHalManager
* src/nm-hal-manager.c
src/nm-hal-manager.h
- convert to a GObject, and emit singals when stuff changes. Let the
NMManager handle the signals, instead of the NMHalManager calling
into the NMManager.
* src/nm-manager.c
src/nm-manager.h
- (remove_one_device): consolidate device removals here
- (dispose): use remove_one_device()
- (nm_manager_get_device_by_udi): make static
- (deferred_hal_manager_query_devices): idle handler to query the HAL
manager for devices at startup or wakeup time
- (nm_manager_new): create and monitor the HAL manager
- (hal_manager_udi_added_cb): new function; do what
nm_manager_add_device() used to do when signalled by the hal manager
- (hal_manager_udi_removed_cb): new function; do what
nm_manager_remove_device() used to do when signalled by the hal
manager
- (hal_manager_rfkill_changed_cb): handle rfkill changes from the
hal manager
- (hal_manager_hal_reappeared_cb): when HAL comes back, remove devices
in our device list that aren't known to HAL
- (impl_manager_sleep): on wakeup, re-add devices from an idle handler;
see comments on nm-hal-manager.c::nm_manager_state_changed() a few
commits ago
- (nm_manager_get_device_by_path, nm_manager_is_udi_managed,
nm_manager_activation_pending, nm_manager_wireless_enabled,
nm_manager_wireless_hardware_enabled,
nm_manager_set_wireless_hardware_enabled): remove, unused
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3619 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-29 23:03:00 +00:00
|
|
|
static void
|
2013-05-09 10:24:08 -04:00
|
|
|
rfkill_manager_rfkill_changed_cb (NMRfkillManager *rfkill_mgr,
|
|
|
|
|
RfKillType rtype,
|
|
|
|
|
RfKillState udev_state,
|
|
|
|
|
gpointer user_data)
|
2007-02-08 15:34:26 +00:00
|
|
|
{
|
2009-12-23 00:03:45 -08:00
|
|
|
nm_manager_rfkill_update (NM_MANAGER (user_data), rtype);
|
2007-02-08 15:34:26 +00:00
|
|
|
}
|
|
|
|
|
|
2014-04-29 16:12:25 +02:00
|
|
|
const GSList *
|
2008-04-29 Dan Williams <dcbw@redhat.com>
Handle HAL dropouts better; allow NM to start up even if HAL isn't up yet.
* marshallers/nm-marshal.list
- Add marshaller
* src/NetworkManager.c
- (main): let the NMManager handle the NMHalManager
* src/nm-hal-manager.c
src/nm-hal-manager.h
- convert to a GObject, and emit singals when stuff changes. Let the
NMManager handle the signals, instead of the NMHalManager calling
into the NMManager.
* src/nm-manager.c
src/nm-manager.h
- (remove_one_device): consolidate device removals here
- (dispose): use remove_one_device()
- (nm_manager_get_device_by_udi): make static
- (deferred_hal_manager_query_devices): idle handler to query the HAL
manager for devices at startup or wakeup time
- (nm_manager_new): create and monitor the HAL manager
- (hal_manager_udi_added_cb): new function; do what
nm_manager_add_device() used to do when signalled by the hal manager
- (hal_manager_udi_removed_cb): new function; do what
nm_manager_remove_device() used to do when signalled by the hal
manager
- (hal_manager_rfkill_changed_cb): handle rfkill changes from the
hal manager
- (hal_manager_hal_reappeared_cb): when HAL comes back, remove devices
in our device list that aren't known to HAL
- (impl_manager_sleep): on wakeup, re-add devices from an idle handler;
see comments on nm-hal-manager.c::nm_manager_state_changed() a few
commits ago
- (nm_manager_get_device_by_path, nm_manager_is_udi_managed,
nm_manager_activation_pending, nm_manager_wireless_enabled,
nm_manager_wireless_hardware_enabled,
nm_manager_set_wireless_hardware_enabled): remove, unused
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3619 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-29 23:03:00 +00:00
|
|
|
nm_manager_get_devices (NMManager *manager)
|
2007-02-08 15:34:26 +00:00
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
|
|
|
|
|
2008-04-29 Dan Williams <dcbw@redhat.com>
Handle HAL dropouts better; allow NM to start up even if HAL isn't up yet.
* marshallers/nm-marshal.list
- Add marshaller
* src/NetworkManager.c
- (main): let the NMManager handle the NMHalManager
* src/nm-hal-manager.c
src/nm-hal-manager.h
- convert to a GObject, and emit singals when stuff changes. Let the
NMManager handle the signals, instead of the NMHalManager calling
into the NMManager.
* src/nm-manager.c
src/nm-manager.h
- (remove_one_device): consolidate device removals here
- (dispose): use remove_one_device()
- (nm_manager_get_device_by_udi): make static
- (deferred_hal_manager_query_devices): idle handler to query the HAL
manager for devices at startup or wakeup time
- (nm_manager_new): create and monitor the HAL manager
- (hal_manager_udi_added_cb): new function; do what
nm_manager_add_device() used to do when signalled by the hal manager
- (hal_manager_udi_removed_cb): new function; do what
nm_manager_remove_device() used to do when signalled by the hal
manager
- (hal_manager_rfkill_changed_cb): handle rfkill changes from the
hal manager
- (hal_manager_hal_reappeared_cb): when HAL comes back, remove devices
in our device list that aren't known to HAL
- (impl_manager_sleep): on wakeup, re-add devices from an idle handler;
see comments on nm-hal-manager.c::nm_manager_state_changed() a few
commits ago
- (nm_manager_get_device_by_path, nm_manager_is_udi_managed,
nm_manager_activation_pending, nm_manager_wireless_enabled,
nm_manager_wireless_hardware_enabled,
nm_manager_set_wireless_hardware_enabled): remove, unused
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3619 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-29 23:03:00 +00:00
|
|
|
return NM_MANAGER_GET_PRIVATE (manager)->devices;
|
2007-02-08 15:34:26 +00:00
|
|
|
}
|
|
|
|
|
|
2015-02-03 16:15:37 +01:00
|
|
|
static NMDevice *
|
|
|
|
|
nm_manager_get_connection_device (NMManager *self,
|
|
|
|
|
NMConnection *connection)
|
|
|
|
|
{
|
|
|
|
|
NMActiveConnection *ac = find_ac_for_connection (self, connection);
|
|
|
|
|
if (ac == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
return nm_active_connection_get_device (ac);
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-03 16:15:37 +01:00
|
|
|
static NMDevice *
|
|
|
|
|
nm_manager_get_best_device_for_connection (NMManager *self,
|
2015-10-19 14:14:17 +02:00
|
|
|
NMConnection *connection,
|
|
|
|
|
gboolean for_user_request)
|
2015-02-03 16:15:37 +01:00
|
|
|
{
|
|
|
|
|
const GSList *devices, *iter;
|
|
|
|
|
NMDevice *act_device = nm_manager_get_connection_device (self, connection);
|
2015-10-19 14:14:17 +02:00
|
|
|
NMDeviceCheckConAvailableFlags flags;
|
2015-02-03 16:15:37 +01:00
|
|
|
|
|
|
|
|
if (act_device)
|
|
|
|
|
return act_device;
|
|
|
|
|
|
2015-10-19 14:14:17 +02:00
|
|
|
flags = for_user_request ? NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST : NM_DEVICE_CHECK_CON_AVAILABLE_NONE;
|
|
|
|
|
|
2015-02-03 16:15:37 +01:00
|
|
|
/* Pick the first device that's compatible with the connection. */
|
|
|
|
|
devices = nm_manager_get_devices (self);
|
|
|
|
|
for (iter = devices; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
NMDevice *device = NM_DEVICE (iter->data);
|
|
|
|
|
|
2015-10-19 14:14:17 +02:00
|
|
|
if (nm_device_check_connection_available (device, connection, flags, NULL))
|
2015-02-03 16:15:37 +01:00
|
|
|
return device;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* No luck. :( */
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
static void
|
2014-10-06 11:21:54 -05:00
|
|
|
_get_devices (NMManager *self,
|
|
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
gboolean all_devices)
|
2007-08-26 15:55:27 +00:00
|
|
|
{
|
2015-04-15 14:53:30 -04:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2015-08-18 13:42:20 +02:00
|
|
|
gs_free const char **paths = NULL;
|
|
|
|
|
guint i;
|
2007-08-26 15:55:27 +00:00
|
|
|
GSList *iter;
|
|
|
|
|
|
2015-08-18 13:42:20 +02:00
|
|
|
paths = g_new (const char *, g_slist_length (priv->devices) + 1);
|
|
|
|
|
|
|
|
|
|
for (i = 0, iter = priv->devices; iter; iter = iter->next) {
|
|
|
|
|
const char *path;
|
2007-08-26 15:55:27 +00:00
|
|
|
|
2015-08-18 13:42:20 +02:00
|
|
|
path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data));
|
2014-09-24 16:58:07 -05:00
|
|
|
if ( path
|
2014-10-06 11:21:54 -05:00
|
|
|
&& (all_devices || nm_device_is_real (iter->data)))
|
2015-08-18 13:42:20 +02:00
|
|
|
paths[i++] = path;
|
|
|
|
|
}
|
|
|
|
|
paths[i++] = NULL;
|
2015-04-15 14:53:30 -04:00
|
|
|
|
|
|
|
|
g_dbus_method_invocation_return_value (context,
|
2015-08-18 13:42:20 +02:00
|
|
|
g_variant_new ("(^ao)", (char **) paths));
|
2007-08-26 15:55:27 +00:00
|
|
|
}
|
|
|
|
|
|
2014-10-06 11:21:54 -05:00
|
|
|
static void
|
|
|
|
|
impl_manager_get_devices (NMManager *self,
|
|
|
|
|
GDBusMethodInvocation *context)
|
|
|
|
|
{
|
|
|
|
|
_get_devices (self, context, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
impl_manager_get_all_devices (NMManager *self,
|
|
|
|
|
GDBusMethodInvocation *context)
|
|
|
|
|
{
|
|
|
|
|
_get_devices (self, context, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
static void
|
2011-04-22 12:27:55 -05:00
|
|
|
impl_manager_get_device_by_ip_iface (NMManager *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
const char *iface)
|
2011-04-22 12:27:55 -05:00
|
|
|
{
|
|
|
|
|
NMDevice *device;
|
|
|
|
|
const char *path = NULL;
|
|
|
|
|
|
|
|
|
|
device = find_device_by_ip_iface (self, iface);
|
2015-04-15 14:53:30 -04:00
|
|
|
if (device)
|
2015-04-03 10:08:52 -04:00
|
|
|
path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (device));
|
2011-04-22 12:27:55 -05:00
|
|
|
|
|
|
|
|
if (path == NULL) {
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_error (context,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
|
|
|
|
"No device found for the requested iface.");
|
|
|
|
|
} else {
|
|
|
|
|
g_dbus_method_invocation_return_value (context,
|
|
|
|
|
g_variant_new ("(o)", path));
|
2011-04-22 12:27:55 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-29 13:22:53 -05:00
|
|
|
static gboolean
|
|
|
|
|
is_compatible_with_slave (NMConnection *master, NMConnection *slave)
|
|
|
|
|
{
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (master, FALSE);
|
|
|
|
|
g_return_val_if_fail (slave, FALSE);
|
|
|
|
|
|
|
|
|
|
s_con = nm_connection_get_setting_connection (slave);
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
|
|
|
|
|
return nm_connection_is_type (master, nm_setting_connection_get_slave_type (s_con));
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-26 17:27:42 -06:00
|
|
|
/**
|
|
|
|
|
* find_master:
|
|
|
|
|
* @self: #NMManager object
|
|
|
|
|
* @connection: the #NMConnection to find the master connection and device for
|
|
|
|
|
* @device: the #NMDevice, if any, which will activate @connection
|
|
|
|
|
* @out_master_connection: on success, the master connection of @connection if
|
|
|
|
|
* that master connection was found
|
|
|
|
|
* @out_master_device: on success, the master device of @connection if that
|
|
|
|
|
* master device was found
|
2014-01-28 17:24:26 -05:00
|
|
|
* @out_master_ac: on success, the master ActiveConnection of @connection if
|
|
|
|
|
* there already is one
|
2014-01-29 11:48:03 -05:00
|
|
|
* @error: the error, if an error occurred
|
2012-02-26 17:27:42 -06:00
|
|
|
*
|
2014-01-29 13:22:53 -05:00
|
|
|
* Given an #NMConnection, attempts to find its master. If @connection has
|
|
|
|
|
* no master, this will return %TRUE and @out_master_connection and
|
|
|
|
|
* @out_master_device will be untouched.
|
|
|
|
|
*
|
|
|
|
|
* If @connection does have a master, then the outputs depend on what is in its
|
|
|
|
|
* #NMSettingConnection:master property:
|
|
|
|
|
*
|
2014-01-28 17:24:26 -05:00
|
|
|
* If "master" is the ifname of an existing #NMDevice, and that device has a
|
|
|
|
|
* compatible master connection activated or activating on it, then
|
|
|
|
|
* @out_master_device, @out_master_connection, and @out_master_ac will all be
|
|
|
|
|
* set. If the device exists and is idle, only @out_master_device will be set.
|
|
|
|
|
* If the device exists and has an incompatible connection on it, an error
|
|
|
|
|
* will be returned.
|
2014-01-29 13:22:53 -05:00
|
|
|
*
|
|
|
|
|
* If "master" is the ifname of a non-existent device, then @out_master_device
|
|
|
|
|
* will be %NULL, and @out_master_connection will be a connection whose
|
2014-01-28 17:24:26 -05:00
|
|
|
* activation would cause the creation of that device. @out_master_ac MAY be
|
|
|
|
|
* set in this case as well (if the connection has started activating, but has
|
|
|
|
|
* not yet created its device).
|
2014-01-29 13:22:53 -05:00
|
|
|
*
|
2014-01-29 13:22:53 -05:00
|
|
|
* If "master" is the UUID of a compatible master connection, then
|
|
|
|
|
* @out_master_connection will be the identified connection, and @out_master_device
|
2014-01-28 17:24:26 -05:00
|
|
|
* and/or @out_master_ac will be set if the connection is currently activating.
|
|
|
|
|
* (@out_master_device will not be set if the device exists but does not have
|
|
|
|
|
* @out_master_connection active/activating on it.)
|
2012-02-26 17:27:42 -06:00
|
|
|
*
|
|
|
|
|
* Returns: %TRUE if the master device and/or connection could be found or if
|
|
|
|
|
* the connection did not require a master, %FALSE otherwise
|
|
|
|
|
**/
|
|
|
|
|
static gboolean
|
|
|
|
|
find_master (NMManager *self,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
NMDevice *device,
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection **out_master_connection,
|
2014-01-29 11:48:03 -05:00
|
|
|
NMDevice **out_master_device,
|
2014-01-28 17:24:26 -05:00
|
|
|
NMActiveConnection **out_master_ac,
|
2014-01-29 11:48:03 -05:00
|
|
|
GError **error)
|
2012-02-26 17:27:42 -06:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
const char *master;
|
|
|
|
|
NMDevice *master_device = NULL;
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *master_connection = NULL;
|
2014-09-24 16:58:07 -05:00
|
|
|
GSList *iter;
|
2012-02-26 17:27:42 -06:00
|
|
|
|
|
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
master = nm_setting_connection_get_master (s_con);
|
|
|
|
|
|
|
|
|
|
if (master == NULL)
|
|
|
|
|
return TRUE; /* success, but no master */
|
|
|
|
|
|
|
|
|
|
/* Try as an interface name first */
|
2014-10-15 21:17:45 -05:00
|
|
|
master_device = find_device_by_iface (self, master, NULL, connection);
|
2012-02-26 17:27:42 -06:00
|
|
|
if (master_device) {
|
2014-01-29 11:48:03 -05:00
|
|
|
if (master_device == device) {
|
|
|
|
|
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
|
|
|
|
|
"Device cannot be its own master");
|
2012-02-26 17:27:42 -06:00
|
|
|
return FALSE;
|
2014-01-29 11:48:03 -05:00
|
|
|
}
|
2014-01-29 13:22:53 -05:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
master_connection = nm_device_get_settings_connection (master_device);
|
|
|
|
|
if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), connection)) {
|
2014-01-29 13:22:53 -05:00
|
|
|
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
|
2016-03-30 09:00:06 +02:00
|
|
|
"The active connection on %s is not compatible",
|
|
|
|
|
nm_device_get_iface (master_device));
|
2014-01-29 13:22:53 -05:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
2012-02-26 17:27:42 -06:00
|
|
|
} else {
|
|
|
|
|
/* Try master as a connection UUID */
|
2015-07-14 16:53:24 +02:00
|
|
|
master_connection = nm_settings_get_connection_by_uuid (priv->settings, master);
|
2012-02-26 17:27:42 -06:00
|
|
|
if (master_connection) {
|
|
|
|
|
/* Check if the master connection is activated on some device already */
|
|
|
|
|
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
NMDevice *candidate = NM_DEVICE (iter->data);
|
|
|
|
|
|
|
|
|
|
if (candidate == device)
|
|
|
|
|
continue;
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
if (nm_device_get_settings_connection (candidate) == master_connection) {
|
2012-02-26 17:27:42 -06:00
|
|
|
master_device = candidate;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (out_master_connection)
|
|
|
|
|
*out_master_connection = master_connection;
|
|
|
|
|
if (out_master_device)
|
|
|
|
|
*out_master_device = master_device;
|
2014-01-28 17:24:26 -05:00
|
|
|
if (out_master_ac && master_connection)
|
2015-07-14 16:53:24 +02:00
|
|
|
*out_master_ac = find_ac_for_connection (self, NM_CONNECTION (master_connection));
|
2012-02-26 17:27:42 -06:00
|
|
|
|
2014-01-29 11:48:03 -05:00
|
|
|
if (master_device || master_connection)
|
|
|
|
|
return TRUE;
|
|
|
|
|
else {
|
|
|
|
|
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
|
|
|
|
"Master connection not found or invalid");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2012-02-26 17:27:42 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* ensure_master_active_connection:
|
|
|
|
|
* @self: the #NMManager
|
2013-07-29 13:11:47 -05:00
|
|
|
* @subject: the #NMAuthSubject representing the requestor of this activation
|
2012-02-26 17:27:42 -06:00
|
|
|
* @connection: the connection that should depend on @master_connection
|
|
|
|
|
* @device: the #NMDevice, if any, which will activate @connection
|
2014-01-29 13:22:53 -05:00
|
|
|
* @master_connection: the master connection, or %NULL
|
|
|
|
|
* @master_device: the master device, or %NULL
|
2012-02-26 17:27:42 -06:00
|
|
|
* @error: the error, if an error occurred
|
|
|
|
|
*
|
|
|
|
|
* Determines whether a given #NMConnection depends on another connection to
|
|
|
|
|
* be activated, and if so, finds that master connection or creates it.
|
|
|
|
|
*
|
2014-01-29 13:22:53 -05:00
|
|
|
* If @master_device and @master_connection are both set then @master_connection
|
2014-01-29 13:22:53 -05:00
|
|
|
* MUST already be activated or activating on @master_device, and the function will
|
|
|
|
|
* return the existing #NMActiveConnection.
|
2014-01-29 13:22:53 -05:00
|
|
|
*
|
2014-01-29 13:22:53 -05:00
|
|
|
* If only @master_device is set, and it has an #NMActiveConnection, then the
|
|
|
|
|
* function will return it if it is a compatible master, or an error if not. If it
|
|
|
|
|
* doesn't have an AC, then the function will create one if a compatible master
|
|
|
|
|
* connection exists, or return an error if not.
|
2014-01-29 13:22:53 -05:00
|
|
|
*
|
|
|
|
|
* If only @master_connection is set, then this will try to find or create a compatible
|
|
|
|
|
* #NMDevice, and either activate @master_connection on that device or return an error.
|
|
|
|
|
*
|
2012-02-26 17:27:42 -06:00
|
|
|
* Returns: the master #NMActiveConnection that the caller should depend on, or
|
|
|
|
|
* %NULL if an error occurred
|
|
|
|
|
*/
|
|
|
|
|
static NMActiveConnection *
|
|
|
|
|
ensure_master_active_connection (NMManager *self,
|
2013-07-29 13:11:47 -05:00
|
|
|
NMAuthSubject *subject,
|
2012-02-26 17:27:42 -06:00
|
|
|
NMConnection *connection,
|
|
|
|
|
NMDevice *device,
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *master_connection,
|
2012-02-26 17:27:42 -06:00
|
|
|
NMDevice *master_device,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
NMActiveConnection *master_ac = NULL;
|
|
|
|
|
NMDeviceState master_state;
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
|
|
g_assert (connection);
|
|
|
|
|
g_assert (master_connection || master_device);
|
|
|
|
|
|
|
|
|
|
/* If the master device isn't activated then we need to activate it using
|
|
|
|
|
* compatible connection. If it's already activating we can just proceed.
|
|
|
|
|
*/
|
|
|
|
|
if (master_device) {
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *device_connection = nm_device_get_settings_connection (master_device);
|
2014-01-29 13:22:53 -05:00
|
|
|
|
2012-02-26 17:27:42 -06:00
|
|
|
/* If we're passed a connection and a device, we require that connection
|
|
|
|
|
* be already activated on the device, eg returned from find_master().
|
|
|
|
|
*/
|
core: fix activation of slave when master is not active, but device exists
NM fails to activate a slave if the master device already exists
but has not active connection.
One way to reproduce, create a bond master/slave configuration and
ensure that the master device exists (e.g. by activating the bond, and
killing NM without taking down the device, or externally via `ip link add`).
If you try to activate the slave it will fail with the following message
(in nmcli):
"Error: Connection activation failed: The active connection on MASTER is not a valid master for 'SLAVE'"
although MASTER is not active.
This also triggers the following assertion:
#0 0x0000003370c504e9 in g_logv () from /lib64/libglib-2.0.so.0
#1 0x0000003370c5063f in g_log () from /lib64/libglib-2.0.so.0
#2 0x000000000047646a in is_compatible_with_slave (master=0x0, slave=slave@entry=0xc4aa60) at nm-manager.c:2193
#3 0x000000000047e289 in ensure_master_active_connection (self=self@entry=0xc8d150, subject=0x7f23b80059e0, connection=connection@entry=0xc4aa60, device=device@entry=0xcac380, master_connection=master_connection@entry=0x0,
master_device=master_device@entry=0xc9e800, error=error@entry=0x7fffa5cc4958) at nm-manager.c:2395
#4 0x000000000047eb4a in _internal_activate_device (self=self@entry=0xc8d150, active=active@entry=0xcc33b0, error=error@entry=0x7fffa5cc4958) at nm-manager.c:2665
#5 0x000000000047ecf2 in _internal_activate_generic (self=self@entry=0xc8d150, active=active@entry=0xcc33b0, error=error@entry=0x7fffa5cc4958) at nm-manager.c:2712
#6 0x000000000047ef2b in _internal_activation_auth_done (active=0xcc33b0, success=<optimized out>, error_desc=0x0, user_data1=0xc8d150, user_data2=<optimized out>) at nm-manager.c:2848
#7 0x0000000000466fa1 in auth_done (chain=0xcef020, error=0x0, unused=<optimized out>, user_data=<optimized out>) at nm-active-connection.c:603
#8 0x00000000004753da in auth_chain_finish (user_data=0xcef020) at nm-manager-auth.c:88
#9 0x0000003370c492a6 in g_main_context_dispatch () from /lib64/libglib-2.0.so.0
#10 0x0000003370c49628 in g_main_context_iterate.isra () from /lib64/libglib-2.0.so.0
#11 0x0000003370c49a3a in g_main_loop_run () from /lib64/libglib-2.0.so.0
#12 0x0000000000429e65 in main (argc=1, argv=0x7fffa5cc4e48) at main.c:678
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-11 20:35:08 +02:00
|
|
|
g_assert (!master_connection || master_connection == device_connection);
|
2015-07-14 16:53:24 +02:00
|
|
|
if (device_connection && !is_compatible_with_slave (NM_CONNECTION (device_connection), connection)) {
|
2014-01-29 13:22:53 -05:00
|
|
|
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
|
2016-03-30 09:00:06 +02:00
|
|
|
"The active connection %s is not compatible",
|
2014-01-29 13:22:53 -05:00
|
|
|
nm_connection_get_id (connection));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2012-02-26 17:27:42 -06:00
|
|
|
|
|
|
|
|
master_state = nm_device_get_state (master_device);
|
|
|
|
|
if ( (master_state == NM_DEVICE_STATE_ACTIVATED)
|
|
|
|
|
|| nm_device_is_activating (master_device)) {
|
|
|
|
|
/* Device already using master_connection */
|
core: fix activation of slave when master is not active, but device exists
NM fails to activate a slave if the master device already exists
but has not active connection.
One way to reproduce, create a bond master/slave configuration and
ensure that the master device exists (e.g. by activating the bond, and
killing NM without taking down the device, or externally via `ip link add`).
If you try to activate the slave it will fail with the following message
(in nmcli):
"Error: Connection activation failed: The active connection on MASTER is not a valid master for 'SLAVE'"
although MASTER is not active.
This also triggers the following assertion:
#0 0x0000003370c504e9 in g_logv () from /lib64/libglib-2.0.so.0
#1 0x0000003370c5063f in g_log () from /lib64/libglib-2.0.so.0
#2 0x000000000047646a in is_compatible_with_slave (master=0x0, slave=slave@entry=0xc4aa60) at nm-manager.c:2193
#3 0x000000000047e289 in ensure_master_active_connection (self=self@entry=0xc8d150, subject=0x7f23b80059e0, connection=connection@entry=0xc4aa60, device=device@entry=0xcac380, master_connection=master_connection@entry=0x0,
master_device=master_device@entry=0xc9e800, error=error@entry=0x7fffa5cc4958) at nm-manager.c:2395
#4 0x000000000047eb4a in _internal_activate_device (self=self@entry=0xc8d150, active=active@entry=0xcc33b0, error=error@entry=0x7fffa5cc4958) at nm-manager.c:2665
#5 0x000000000047ecf2 in _internal_activate_generic (self=self@entry=0xc8d150, active=active@entry=0xcc33b0, error=error@entry=0x7fffa5cc4958) at nm-manager.c:2712
#6 0x000000000047ef2b in _internal_activation_auth_done (active=0xcc33b0, success=<optimized out>, error_desc=0x0, user_data1=0xc8d150, user_data2=<optimized out>) at nm-manager.c:2848
#7 0x0000000000466fa1 in auth_done (chain=0xcef020, error=0x0, unused=<optimized out>, user_data=<optimized out>) at nm-active-connection.c:603
#8 0x00000000004753da in auth_chain_finish (user_data=0xcef020) at nm-manager-auth.c:88
#9 0x0000003370c492a6 in g_main_context_dispatch () from /lib64/libglib-2.0.so.0
#10 0x0000003370c49628 in g_main_context_iterate.isra () from /lib64/libglib-2.0.so.0
#11 0x0000003370c49a3a in g_main_loop_run () from /lib64/libglib-2.0.so.0
#12 0x0000000000429e65 in main (argc=1, argv=0x7fffa5cc4e48) at main.c:678
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-11 20:35:08 +02:00
|
|
|
g_assert (device_connection);
|
2012-02-26 17:27:42 -06:00
|
|
|
return NM_ACTIVE_CONNECTION (nm_device_get_act_request (master_device));
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-29 13:22:53 -05:00
|
|
|
/* If the device is disconnected, find a compatible connection and
|
2012-02-26 17:27:42 -06:00
|
|
|
* activate it on the device.
|
|
|
|
|
*/
|
2014-09-24 16:58:07 -05:00
|
|
|
if (master_state == NM_DEVICE_STATE_DISCONNECTED || !nm_device_is_real (master_device)) {
|
2012-02-26 17:27:42 -06:00
|
|
|
GSList *connections;
|
|
|
|
|
|
|
|
|
|
g_assert (master_connection == NULL);
|
|
|
|
|
|
|
|
|
|
/* Find a compatible connection and activate this device using it */
|
2013-09-12 10:28:21 -04:00
|
|
|
connections = nm_manager_get_activatable_connections (self);
|
2012-02-26 17:27:42 -06:00
|
|
|
for (iter = connections; iter; iter = g_slist_next (iter)) {
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (iter->data);
|
2012-02-26 17:27:42 -06:00
|
|
|
|
2013-07-25 15:36:45 +02:00
|
|
|
/* Ensure eg bond/team slave and the candidate master is a
|
|
|
|
|
* bond/team master
|
|
|
|
|
*/
|
2015-07-14 16:53:24 +02:00
|
|
|
if (!is_compatible_with_slave (NM_CONNECTION (candidate), connection))
|
2012-02-26 17:27:42 -06:00
|
|
|
continue;
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
if (nm_device_check_connection_available (master_device, NM_CONNECTION (candidate), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) {
|
2012-02-26 17:27:42 -06:00
|
|
|
master_ac = nm_manager_activate_connection (self,
|
|
|
|
|
candidate,
|
|
|
|
|
NULL,
|
2012-09-13 15:57:36 -05:00
|
|
|
master_device,
|
2013-07-29 13:11:47 -05:00
|
|
|
subject,
|
2012-02-26 17:27:42 -06:00
|
|
|
error);
|
|
|
|
|
g_slist_free (connections);
|
|
|
|
|
return master_ac;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_slist_free (connections);
|
|
|
|
|
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
|
2016-03-30 09:00:06 +02:00
|
|
|
"No compatible connection found.");
|
2012-02-26 17:27:42 -06:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Otherwise, the device is unmanaged, unavailable, or disconnecting */
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
2014-10-15 15:27:25 -04:00
|
|
|
NM_MANAGER_ERROR_DEPENDENCY_FAILED,
|
2016-03-30 09:00:06 +02:00
|
|
|
"Device unmanaged or not available for activation");
|
2012-02-26 17:27:42 -06:00
|
|
|
} else if (master_connection) {
|
|
|
|
|
gboolean found_device = FALSE;
|
|
|
|
|
|
|
|
|
|
/* Find a compatible device and activate it using this connection */
|
|
|
|
|
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
NMDevice *candidate = NM_DEVICE (iter->data);
|
|
|
|
|
|
|
|
|
|
if (candidate == device) {
|
|
|
|
|
/* A device obviously can't be its own master */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
if (!nm_device_check_connection_available (candidate, NM_CONNECTION (master_connection), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL))
|
2012-02-26 17:27:42 -06:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
found_device = TRUE;
|
2014-09-24 16:58:07 -05:00
|
|
|
if (!nm_device_is_software (candidate)) {
|
|
|
|
|
master_state = nm_device_get_state (candidate);
|
|
|
|
|
if (nm_device_is_real (candidate) && master_state != NM_DEVICE_STATE_DISCONNECTED)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2012-02-26 17:27:42 -06:00
|
|
|
|
2013-01-30 12:52:42 -06:00
|
|
|
master_ac = nm_manager_activate_connection (self,
|
|
|
|
|
master_connection,
|
|
|
|
|
NULL,
|
2012-09-13 15:57:36 -05:00
|
|
|
candidate,
|
2013-07-29 13:11:47 -05:00
|
|
|
subject,
|
2013-01-30 12:52:42 -06:00
|
|
|
error);
|
|
|
|
|
return master_ac;
|
2012-02-26 17:27:42 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
2016-03-30 09:00:06 +02:00
|
|
|
"No device available");
|
2012-02-26 17:27:42 -06:00
|
|
|
} else
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-06 14:38:55 +02:00
|
|
|
/**
|
|
|
|
|
* find_slaves:
|
|
|
|
|
* @manager: #NMManager object
|
2015-07-14 16:53:24 +02:00
|
|
|
* @connection: the master #NMSettingsConnection to find slave connections for
|
2015-05-06 14:38:55 +02:00
|
|
|
* @device: the master #NMDevice for the @connection
|
|
|
|
|
*
|
2015-07-14 16:53:24 +02:00
|
|
|
* Given an #NMSettingsConnection, attempts to find its slaves. If @connection is not
|
2015-05-06 14:38:55 +02:00
|
|
|
* master, or has not any slaves, this will return %NULL.
|
|
|
|
|
*
|
|
|
|
|
* Returns: list of slave connections for given master @connection, or %NULL
|
|
|
|
|
**/
|
|
|
|
|
static GSList *
|
|
|
|
|
find_slaves (NMManager *manager,
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *connection,
|
2015-05-06 14:38:55 +02:00
|
|
|
NMDevice *device)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
|
|
|
|
GSList *all_connections, *iter;
|
|
|
|
|
GSList *slaves = NULL;
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
const char *master;
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
|
2015-05-06 14:38:55 +02:00
|
|
|
g_assert (s_con);
|
|
|
|
|
master = nm_setting_connection_get_master (s_con);
|
|
|
|
|
|
|
|
|
|
if (master != NULL)
|
|
|
|
|
return NULL; /* connection is not master */
|
|
|
|
|
|
|
|
|
|
/* Search through all connections, not only inactive ones, because
|
|
|
|
|
* even if a slave was already active, it might be deactivated during
|
|
|
|
|
* master reactivation.
|
|
|
|
|
*/
|
2016-05-16 19:24:23 +02:00
|
|
|
all_connections = nm_settings_get_connections_sorted (priv->settings);
|
2015-05-06 14:38:55 +02:00
|
|
|
for (iter = all_connections; iter; iter = iter->next) {
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *master_connection = NULL;
|
2015-05-06 14:38:55 +02:00
|
|
|
NMDevice *master_device = NULL;
|
|
|
|
|
NMConnection *candidate = iter->data;
|
|
|
|
|
|
|
|
|
|
find_master (manager, candidate, NULL, &master_connection, &master_device, NULL, NULL);
|
|
|
|
|
if ( (master_connection && master_connection == connection)
|
|
|
|
|
|| (master_device && master_device == device)) {
|
|
|
|
|
slaves = g_slist_prepend (slaves, candidate);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_slist_free (all_connections);
|
|
|
|
|
|
|
|
|
|
return g_slist_reverse (slaves);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
should_connect_slaves (NMConnection *connection, NMDevice *device)
|
|
|
|
|
{
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
NMSettingConnectionAutoconnectSlaves autoconnect_slaves;
|
|
|
|
|
gs_free char *value = NULL;
|
|
|
|
|
|
|
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
|
|
|
|
|
/* Check configuration default for autoconnect-slaves property */
|
2015-06-09 08:47:41 +02:00
|
|
|
value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
|
2015-05-06 14:38:55 +02:00
|
|
|
"connection.autoconnect-slaves", device);
|
|
|
|
|
if (value)
|
|
|
|
|
autoconnect_slaves = _nm_utils_ascii_str_to_int64 (value, 10, 0, 1, -1);
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO)
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES)
|
|
|
|
|
return TRUE;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2016-03-02 11:38:26 +01:00
|
|
|
autoconnect_slaves (NMManager *self,
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *master_connection,
|
2015-05-06 14:38:55 +02:00
|
|
|
NMDevice *master_device,
|
|
|
|
|
NMAuthSubject *subject)
|
|
|
|
|
{
|
|
|
|
|
GError *local_err = NULL;
|
|
|
|
|
gboolean ret = FALSE;
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
if (should_connect_slaves (NM_CONNECTION (master_connection), master_device)) {
|
2015-05-06 14:38:55 +02:00
|
|
|
GSList *slaves, *iter;
|
|
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
iter = slaves = find_slaves (self, master_connection, master_device);
|
2015-05-06 14:38:55 +02:00
|
|
|
ret = slaves != NULL;
|
|
|
|
|
|
|
|
|
|
while (iter) {
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *slave_connection = iter->data;
|
2015-05-06 14:38:55 +02:00
|
|
|
|
|
|
|
|
iter = iter->next;
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "will activate slave connection '%s' (%s) as a dependency for master '%s' (%s)",
|
|
|
|
|
nm_settings_connection_get_id (slave_connection),
|
|
|
|
|
nm_settings_connection_get_uuid (slave_connection),
|
|
|
|
|
nm_settings_connection_get_id (master_connection),
|
|
|
|
|
nm_settings_connection_get_uuid (master_connection));
|
2015-05-06 14:38:55 +02:00
|
|
|
|
|
|
|
|
/* Schedule slave activation */
|
2016-03-02 11:38:26 +01:00
|
|
|
nm_manager_activate_connection (self,
|
2015-05-06 14:38:55 +02:00
|
|
|
slave_connection,
|
|
|
|
|
NULL,
|
2016-03-02 11:38:26 +01:00
|
|
|
nm_manager_get_best_device_for_connection (self, NM_CONNECTION (slave_connection), FALSE),
|
2015-05-06 14:38:55 +02:00
|
|
|
subject,
|
|
|
|
|
&local_err);
|
|
|
|
|
if (local_err) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGW (LOGD_CORE, "Slave connection activation failed: %s", local_err->message);
|
2015-05-06 14:38:55 +02:00
|
|
|
g_error_free (local_err);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_slist_free (slaves);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
static gboolean
|
|
|
|
|
_internal_activate_vpn (NMManager *self, NMActiveConnection *active, GError **error)
|
2012-02-23 10:04:41 -06:00
|
|
|
{
|
2013-08-28 16:19:20 -05:00
|
|
|
g_assert (NM_IS_VPN_CONNECTION (active));
|
2012-09-14 15:21:29 -05:00
|
|
|
|
2015-10-14 19:48:59 +02:00
|
|
|
nm_exported_object_export (NM_EXPORTED_OBJECT (active));
|
2016-03-21 16:09:30 -05:00
|
|
|
return nm_vpn_manager_activate_connection (NM_MANAGER_GET_PRIVATE (self)->vpn_manager,
|
|
|
|
|
NM_VPN_CONNECTION (active),
|
|
|
|
|
error);
|
2012-02-23 10:04:41 -06:00
|
|
|
}
|
|
|
|
|
|
2016-03-24 15:20:44 +01:00
|
|
|
/* Traverse the device to disconnected state. This means that the device is ready
|
|
|
|
|
* for connection and will proceed activating if there's an activation request
|
|
|
|
|
* enqueued.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
unmanaged_to_disconnected (NMDevice *device)
|
|
|
|
|
{
|
|
|
|
|
/* when creating the software device, it can happen that the device is
|
|
|
|
|
* still unmanaged by NM_UNMANAGED_PLATFORM_INIT because we didn't yet
|
|
|
|
|
* get the udev event. At this point, we can no longer delay the activation
|
|
|
|
|
* and force the device to be managed. */
|
|
|
|
|
nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_PLATFORM_INIT, FALSE, NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
|
|
|
|
|
|
|
|
|
nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_USER_EXPLICIT, FALSE, NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (nm_device_get_managed (device, FALSE));
|
|
|
|
|
|
|
|
|
|
if (nm_device_get_state (device) == NM_DEVICE_STATE_UNMANAGED) {
|
|
|
|
|
nm_device_state_changed (device,
|
|
|
|
|
NM_DEVICE_STATE_UNAVAILABLE,
|
|
|
|
|
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST)
|
|
|
|
|
&& (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE)) {
|
|
|
|
|
nm_device_state_changed (device,
|
|
|
|
|
NM_DEVICE_STATE_DISCONNECTED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-24 15:20:44 +01:00
|
|
|
/* The parent connection is ready; we can proceed realizing the device and
|
|
|
|
|
* progressing the device to disconencted state.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
active_connection_parent_active (NMActiveConnection *active,
|
|
|
|
|
NMActiveConnection *parent_ac,
|
|
|
|
|
NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *device = nm_active_connection_get_device (active);
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
g_signal_handlers_disconnect_by_func (active,
|
|
|
|
|
(GCallback) active_connection_parent_active,
|
|
|
|
|
self);
|
|
|
|
|
|
|
|
|
|
if (parent_ac) {
|
|
|
|
|
NMSettingsConnection *connection = nm_active_connection_get_settings_connection (active);
|
|
|
|
|
NMDevice *parent = nm_active_connection_get_device (parent_ac);
|
|
|
|
|
|
|
|
|
|
if (nm_device_create_and_realize (device, (NMConnection *) connection, parent, &error)) {
|
|
|
|
|
/* We can now proceed to disconnected state so that activation proceeds. */
|
|
|
|
|
unmanaged_to_disconnected (device);
|
|
|
|
|
} else {
|
2016-04-27 18:26:39 +02:00
|
|
|
_LOGW (LOGD_CORE, "Could not realize device '%s': %s",
|
|
|
|
|
nm_device_get_iface (device), error->message);
|
2016-03-24 15:20:44 +01:00
|
|
|
nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2016-04-27 18:26:39 +02:00
|
|
|
_LOGW (LOGD_CORE, "The parent connection device '%s' depended on disappeared.",
|
|
|
|
|
nm_device_get_iface (device));
|
2016-03-24 15:20:44 +01:00
|
|
|
nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
static gboolean
|
|
|
|
|
_internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error)
|
2008-03-26 13:43:01 +00:00
|
|
|
{
|
2015-02-03 16:15:37 +01:00
|
|
|
NMDevice *device, *existing, *master_device = NULL;
|
2015-07-14 16:53:24 +02:00
|
|
|
NMConnection *applied;
|
|
|
|
|
NMSettingsConnection *connection;
|
|
|
|
|
NMSettingsConnection *master_connection = NULL;
|
2014-10-15 21:17:45 -05:00
|
|
|
NMConnection *existing_connection = NULL;
|
2014-01-28 17:24:26 -05:00
|
|
|
NMActiveConnection *master_ac = NULL;
|
2014-10-15 21:17:45 -05:00
|
|
|
NMAuthSubject *subject;
|
|
|
|
|
char *error_desc = NULL;
|
2008-03-26 13:43:01 +00:00
|
|
|
|
2013-10-31 14:13:33 +01:00
|
|
|
g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
|
|
|
|
|
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE);
|
|
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
g_assert (NM_IS_VPN_CONNECTION (active) == FALSE);
|
2008-03-26 13:43:01 +00:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
connection = nm_active_connection_get_settings_connection (active);
|
2013-08-28 16:19:20 -05:00
|
|
|
g_assert (connection);
|
2009-10-16 11:52:27 -07:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
applied = nm_active_connection_get_applied_connection (active);
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
device = nm_active_connection_get_device (active);
|
2014-10-15 21:17:45 -05:00
|
|
|
g_return_val_if_fail (device != NULL, FALSE);
|
2014-02-26 13:18:16 -06:00
|
|
|
|
2014-10-15 21:17:45 -05:00
|
|
|
/* If the device is active and its connection is not visible to the
|
|
|
|
|
* user that's requesting this new activation, fail, since other users
|
|
|
|
|
* should not be allowed to implicitly deactivate private connections
|
|
|
|
|
* by activating a connection of their own.
|
|
|
|
|
*/
|
|
|
|
|
existing_connection = nm_device_get_applied_connection (device);
|
|
|
|
|
subject = nm_active_connection_get_subject (active);
|
|
|
|
|
if (existing_connection &&
|
|
|
|
|
!nm_auth_is_subject_in_acl (existing_connection,
|
|
|
|
|
subject,
|
|
|
|
|
&error_desc)) {
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Private connection already active on the device: %s",
|
|
|
|
|
error_desc);
|
|
|
|
|
g_free (error_desc);
|
|
|
|
|
return FALSE;
|
2012-02-26 17:27:42 -06:00
|
|
|
}
|
|
|
|
|
|
2013-11-04 19:51:28 -06:00
|
|
|
/* Final connection must be available on device */
|
2015-07-14 16:53:24 +02:00
|
|
|
if (!nm_device_check_connection_available (device, applied, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) {
|
2013-11-04 19:51:28 -06:00
|
|
|
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
|
|
|
|
|
"Connection '%s' is not available on the device %s at this time.",
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_settings_connection_get_id (connection), nm_device_get_iface (device));
|
2013-08-28 16:19:20 -05:00
|
|
|
return FALSE;
|
2012-02-26 17:27:42 -06:00
|
|
|
}
|
|
|
|
|
|
2014-09-24 16:58:07 -05:00
|
|
|
/* Create any backing resources the device needs */
|
|
|
|
|
if (!nm_device_is_real (device)) {
|
|
|
|
|
NMDevice *parent;
|
|
|
|
|
|
2016-02-17 15:18:37 +01:00
|
|
|
parent = find_parent_device_for_connection (self, (NMConnection *) connection, NULL);
|
2016-03-24 15:20:44 +01:00
|
|
|
|
|
|
|
|
if (parent && !nm_device_is_real (parent)) {
|
|
|
|
|
NMSettingsConnection *parent_con;
|
|
|
|
|
NMActiveConnection *parent_ac;
|
|
|
|
|
|
|
|
|
|
parent_con = nm_device_get_best_connection (parent, NULL, error);
|
|
|
|
|
if (!parent_con) {
|
|
|
|
|
g_prefix_error (error, "%s failed to create parent: ", nm_device_get_iface (device));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
parent_ac = nm_manager_activate_connection (self, parent_con, NULL, parent, subject, error);
|
|
|
|
|
if (!parent_ac) {
|
|
|
|
|
g_prefix_error (error, "%s failed to activate parent: ", nm_device_get_iface (device));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* We can't realize now; defer until the parent device is ready. */
|
|
|
|
|
g_signal_connect (active,
|
|
|
|
|
NM_ACTIVE_CONNECTION_PARENT_ACTIVE,
|
|
|
|
|
(GCallback) active_connection_parent_active,
|
|
|
|
|
self);
|
|
|
|
|
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, (NMConnection *) connection, parent, error)) {
|
|
|
|
|
g_prefix_error (error, "%s failed to create resources: ", nm_device_get_iface (device));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2014-09-24 16:58:07 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-26 17:27:42 -06:00
|
|
|
/* Try to find the master connection/device if the connection has a dependency */
|
2015-07-14 16:53:24 +02:00
|
|
|
if (!find_master (self, applied, device,
|
2014-01-28 17:24:26 -05:00
|
|
|
&master_connection, &master_device, &master_ac,
|
2016-03-30 09:00:06 +02:00
|
|
|
error)) {
|
|
|
|
|
g_prefix_error (error, "Can not find a master for %s: ",
|
|
|
|
|
nm_settings_connection_get_id (connection));
|
2013-08-28 16:19:20 -05:00
|
|
|
return FALSE;
|
2016-03-30 09:00:06 +02:00
|
|
|
}
|
2012-02-26 17:27:42 -06:00
|
|
|
|
|
|
|
|
/* Ensure there's a master active connection the new connection we're
|
|
|
|
|
* activating can depend on.
|
|
|
|
|
*/
|
|
|
|
|
if (master_connection || master_device) {
|
|
|
|
|
if (master_connection) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "Activation of '%s' requires master connection '%s'",
|
|
|
|
|
nm_settings_connection_get_id (connection),
|
|
|
|
|
nm_settings_connection_get_id (master_connection));
|
2012-02-26 17:27:42 -06:00
|
|
|
}
|
|
|
|
|
if (master_device) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "Activation of '%s' requires master device '%s'",
|
|
|
|
|
nm_settings_connection_get_id (connection),
|
|
|
|
|
nm_device_get_ip_iface (master_device));
|
2012-02-26 17:27:42 -06:00
|
|
|
}
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
/* Ensure eg bond slave and the candidate master is a bond master */
|
2015-07-14 16:53:24 +02:00
|
|
|
if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), applied)) {
|
2016-03-30 09:00:06 +02:00
|
|
|
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 (connection));
|
2013-08-28 16:19:20 -05:00
|
|
|
return FALSE;
|
2012-02-26 17:27:42 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!master_ac) {
|
2014-01-28 17:24:26 -05:00
|
|
|
master_ac = ensure_master_active_connection (self,
|
|
|
|
|
nm_active_connection_get_subject (active),
|
2015-07-14 16:53:24 +02:00
|
|
|
applied,
|
2014-01-28 17:24:26 -05:00
|
|
|
device,
|
|
|
|
|
master_connection,
|
|
|
|
|
master_device,
|
|
|
|
|
error);
|
|
|
|
|
if (!master_ac) {
|
2016-03-30 09:00:06 +02:00
|
|
|
if (master_device) {
|
|
|
|
|
g_prefix_error (error, "Master device '%s' can't be activated: ",
|
|
|
|
|
nm_device_get_ip_iface (device));
|
|
|
|
|
} else {
|
|
|
|
|
g_prefix_error (error, "Master connection '%s' can't be activated: ",
|
|
|
|
|
nm_settings_connection_get_id (connection));
|
|
|
|
|
}
|
2014-01-28 17:24:26 -05:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-04-07 Dan Williams <dcbw@redhat.com>
* include/NetworkManager.h
- Remove the DOWN and CANCELLED device states
- Add UNMANAGED and UNAVAILABLE device states
- Document the device states
* introspection/nm-device.xml
src/nm-device-interface.c
src/nm-device-interface.h
- Add the 'managed' property
* test/nm-tool.c
- (detail_device): print out device state
* src/NetworkManagerSystem.h
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerDebian.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerMandriva.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerSuSE.c
- (nm_system_device_get_system_config, nm_system_device_get_disabled
nm_system_device_free_system_config): remove; they were unused and
their functionality should be re-implemented in each distro's
system settings service plugin
* src/nm-gsm-device.c
src/nm-gsm-device.h
src/nm-cdma-device.c
src/nm-cdma-device.h
- (*_new): take the 'managed' argument
* src/nm-device.c
- (nm_device_set_address): remove, fold into nm_device_bring_up()
- (nm_device_init): start in unmanaged state, not disconnected
- (constructor): don't start device until the system settings service
has had a chance to figure out if the device is managed or not
- (nm_device_deactivate, nm_device_bring_up, nm_device_bring_down):
don't set device state here, let callers handle that as appropriate
- (nm_device_dispose): don't touch the device if it's not managed
- (set_property, get_property, nm_device_class_init): implement the
'managed' property
- (nm_device_state_changed): bring the device up if its now managed,
and deactivate it if it used to be active
- (nm_device_get_managed, nm_device_set_managed): do the right thing
with the managed state
* src/nm-hal-manager.c
- (wired_device_creator, wireless_device_creator, modem_device_creator):
take initial managed state and pass it along to device constructors
- (create_device_and_add_to_list): get managed state and pass to
type creators
* src/nm-device-802-11-wireless.c
- (real_can_activate): fold in most of
nm_device_802_11_wireless_can_activate()
- (can_scan): can't scan in UNAVAILABLE or UNMANAGED
- (link_timeout_cb): instead of deactivating, change device state and
let the device state handler to it
- (real_update_hw_address): clean up
- (state_changed_cb): when entering UNAVAILABLE state, schedule an idle
handler to transition to DISCONNECTED if the device isn't rfkilled
* src/nm-device-802-3-ethernet.c
- (set_carrier): move above callers and get rid of prototype
- (device_state_changed): when entering UNAVAILABLE state, schedule an
idle handler to transition to DISCONNECTED if the device has a
carrier
- (real_update_hw_address): clean up
- (link_timeout_cb, ppp_state_changed): change state instead of calling
deactivation directly as deactivation doesn't change state anymore
* src/NetworkManagerPolicy.c
- (schedule_activate_check): yay, remove wireless_enabled hack since
the NMManager and wireless devices work that out themselves now
- (device_state_changed): change to a switch and update for new device
states
- (device_carrier_changed): remove; device handles this now through
state changes
- (device_added): don't care about carrier any more; the initial
activation check will happen when the device transitions to
DISCONNECTED
* src/nm-manager.c
- (dispose): clear unmanaged devices
- (handle_unmanaged_devices): update unmanaged device list and toggle
the managed property on each device when needed
- (system_settings_properties_changed_cb): handle signals from the
system settings service
- (system_settings_get_unmanaged_devices_cb): handle callback from
getting the unmanaged device list method call
- (query_unmanaged_devices): ask the system settings service for its
list of unmanaged devices
- (nm_manager_name_owner_changed, initial_get_connections): get unmanaged
devices
- (manager_set_wireless_enabled): push rfkill state down to wireless
devices directly and let them handle the necessary state transitions
- (manager_device_state_changed): update for new device states
- (nm_manager_add_device): set initial rfkill state on wireless devices
- (nm_manager_remove_device): don't touch the device if it's unmanaged
- (nm_manager_activate_connection): return error if the device is
unmanaged
- (nm_manager_sleep): handle new device states correctly; don't change
the state of unavailable/unmanaged devices
* libnm-glib/nm-device-802-11-wireless.c
- (state_changed_cb): update for new device states
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3540 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 02:58:02 +00:00
|
|
|
}
|
2012-02-26 17:27:42 -06:00
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
nm_active_connection_set_master (active, master_ac);
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "Activation of '%s' depends on active connection %p %s",
|
|
|
|
|
nm_settings_connection_get_id (connection),
|
|
|
|
|
master_ac,
|
2016-03-08 17:41:31 +01:00
|
|
|
nm_exported_object_get_path (NM_EXPORTED_OBJECT (master_ac)) ?: "");
|
2008-03-26 13:43:01 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-06 14:38:55 +02:00
|
|
|
/* Check slaves for master connection and possibly activate them */
|
|
|
|
|
autoconnect_slaves (self, connection, device, nm_active_connection_get_subject (active));
|
|
|
|
|
|
2015-02-03 16:15:37 +01:00
|
|
|
/* Disconnect the connection if connected or queued on another device */
|
2015-07-14 16:53:24 +02:00
|
|
|
existing = nm_manager_get_connection_device (self, NM_CONNECTION (connection));
|
2015-02-03 16:15:37 +01:00
|
|
|
if (existing)
|
|
|
|
|
nm_device_steal_connection (existing, connection);
|
|
|
|
|
|
2016-03-24 15:20:44 +01:00
|
|
|
/* If the device is there, we can ready it for the activation. */
|
|
|
|
|
if (nm_device_is_real (device))
|
|
|
|
|
unmanaged_to_disconnected (device);
|
2014-10-15 21:17:45 -05:00
|
|
|
|
2014-03-20 11:22:19 -05:00
|
|
|
/* Export the new ActiveConnection to clients and start it on the device */
|
2015-04-03 10:08:52 -04:00
|
|
|
nm_exported_object_export (NM_EXPORTED_OBJECT (active));
|
core: queue re-activations to allow DEACTIVATING state
If a device is already activated, queue the new activation to allow
the transition through the DEACTIVATING state.
---
Also remove the "HACK" bits in nm_device_deactivate(). This hack was
added on 2007-09-25 in commit 9c2848d. At the time, with user settings
services, if a client created a connection and requested that NM
activate it, NM may not have read the connection from the client over
D-Bus yet. So NM created a "deferred" activation request which waited
until the connection was read from the client, and then began activation.
The Policy watched for device state changes and other events (like
it does now) and activated a new device if the old one was no longer
valid. It specifically checked for deferred activations and then
did nothing. However, when the client's connection was read, then
nm-device.c cleared the deferred activation bit, leading to a short
period of time where the device was in DISCONNECTED state but there
was no deferred activation, because the device only changes state to
PREPARE from the idle handler for stage1. If other events happened
during this time, the policy would tear down the device that was
about to be activated. This early state transition to PREPARE
worked around that.
We need to remove it now though, because (a) the reason for its
existence is no longer valid, and (b) _device_activate() may now
be called from inside nm_device_state_changed() and thus it cannot
change to a new state inside the function.
2014-02-17 17:16:08 -06:00
|
|
|
nm_device_queue_activation (device, NM_ACT_REQUEST (active));
|
2013-08-28 16:19:20 -05:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
_internal_activate_generic (NMManager *self, NMActiveConnection *active, GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
gboolean success = FALSE;
|
|
|
|
|
|
2014-02-26 13:18:16 -06:00
|
|
|
/* Ensure activation request is still valid, eg that its device hasn't gone
|
|
|
|
|
* away or that some other dependency has not failed.
|
|
|
|
|
*/
|
|
|
|
|
if (nm_active_connection_get_state (active) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
|
|
|
|
|
g_set_error_literal (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_DEPENDENCY_FAILED,
|
|
|
|
|
"Activation failed because dependencies failed.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
if (NM_IS_VPN_CONNECTION (active))
|
|
|
|
|
success = _internal_activate_vpn (self, active, error);
|
|
|
|
|
else
|
|
|
|
|
success = _internal_activate_device (self, active, error);
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
/* Force an update of the Manager's activating-connection property.
|
|
|
|
|
* The device changes state before the AC gets exported, which causes
|
|
|
|
|
* the manager's 'activating-connection' property to be NULL since the
|
|
|
|
|
* AC only gets a D-Bus path when it's exported. So now that the AC
|
|
|
|
|
* is exported, make sure the manager's activating-connection property
|
|
|
|
|
* is up-to-date.
|
|
|
|
|
*/
|
2015-02-03 16:15:37 +01:00
|
|
|
active_connection_add (self, active);
|
2013-08-28 16:19:20 -05:00
|
|
|
policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self);
|
2013-04-22 13:29:36 -05:00
|
|
|
}
|
2012-08-22 17:11:31 -05:00
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
return success;
|
2008-03-26 13:43:01 +00:00
|
|
|
}
|
|
|
|
|
|
2012-09-13 16:51:58 -05:00
|
|
|
static NMActiveConnection *
|
2015-07-14 16:53:24 +02:00
|
|
|
_new_vpn_active_connection (NMManager *self,
|
|
|
|
|
NMSettingsConnection *settings_connection,
|
2013-08-28 16:19:20 -05:00
|
|
|
const char *specific_object,
|
|
|
|
|
NMAuthSubject *subject,
|
|
|
|
|
GError **error)
|
2007-10-01 15:38:39 +00:00
|
|
|
{
|
2013-08-28 16:19:20 -05:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
NMActiveConnection *parent = NULL;
|
|
|
|
|
NMDevice *device = NULL;
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
if (specific_object) {
|
2014-02-10 11:13:55 +01:00
|
|
|
/* Find the specific connection the client requested we use */
|
2013-08-28 16:19:20 -05:00
|
|
|
parent = active_connection_get_by_path (self, specific_object);
|
|
|
|
|
if (!parent) {
|
|
|
|
|
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
|
|
|
|
|
"Base connection for VPN connection not active.");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
parent = priv->primary_connection;
|
|
|
|
|
|
|
|
|
|
if (!parent) {
|
|
|
|
|
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
|
|
|
|
|
"Could not find source connection.");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
device = nm_active_connection_get_device (parent);
|
|
|
|
|
if (!device) {
|
|
|
|
|
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
|
|
|
|
"Source connection had no active device.");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
return (NMActiveConnection *) nm_vpn_connection_new (settings_connection,
|
2013-08-28 16:19:20 -05:00
|
|
|
device,
|
2015-04-03 10:08:52 -04:00
|
|
|
nm_exported_object_get_path (NM_EXPORTED_OBJECT (parent)),
|
2013-08-28 16:19:20 -05:00
|
|
|
subject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMActiveConnection *
|
|
|
|
|
_new_active_connection (NMManager *self,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
const char *specific_object,
|
|
|
|
|
NMDevice *device,
|
|
|
|
|
NMAuthSubject *subject,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *settings_connection = NULL;
|
2013-09-12 10:28:21 -04:00
|
|
|
NMActiveConnection *existing_ac;
|
2015-07-14 16:53:24 +02:00
|
|
|
gboolean is_vpn;
|
2013-09-12 10:28:21 -04:00
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
|
|
|
|
g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
|
|
|
|
|
|
2013-09-12 10:28:21 -04:00
|
|
|
/* Can't create new AC for already-active connection */
|
|
|
|
|
existing_ac = find_ac_for_connection (self, connection);
|
2013-11-12 14:18:44 -05:00
|
|
|
if (NM_IS_VPN_CONNECTION (existing_ac)) {
|
|
|
|
|
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE,
|
|
|
|
|
"Connection '%s' is already active",
|
|
|
|
|
nm_connection_get_id (connection));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
/* Normalize the specific object */
|
|
|
|
|
if (specific_object && g_strcmp0 (specific_object, "/") == 0)
|
|
|
|
|
specific_object = NULL;
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
is_vpn = nm_connection_is_type (NM_CONNECTION (connection), NM_SETTING_VPN_SETTING_NAME);
|
|
|
|
|
|
|
|
|
|
if (NM_IS_SETTINGS_CONNECTION (connection))
|
|
|
|
|
settings_connection = (NMSettingsConnection *) connection;
|
|
|
|
|
|
|
|
|
|
if (is_vpn) {
|
2013-08-28 16:19:20 -05:00
|
|
|
return _new_vpn_active_connection (self,
|
2015-07-14 16:53:24 +02:00
|
|
|
settings_connection,
|
2013-08-28 16:19:20 -05:00
|
|
|
specific_object,
|
|
|
|
|
subject,
|
|
|
|
|
error);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
return (NMActiveConnection *) nm_act_request_new (settings_connection,
|
2013-08-28 16:19:20 -05:00
|
|
|
specific_object,
|
|
|
|
|
subject,
|
|
|
|
|
device);
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-17 15:33:18 -05:00
|
|
|
static void
|
|
|
|
|
_internal_activation_failed (NMManager *self,
|
|
|
|
|
NMActiveConnection *active,
|
|
|
|
|
const char *error_desc)
|
|
|
|
|
{
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "Failed to activate '%s': %s",
|
|
|
|
|
nm_active_connection_get_settings_connection_id (active),
|
|
|
|
|
error_desc);
|
2014-01-17 15:33:18 -05:00
|
|
|
|
|
|
|
|
if (nm_active_connection_get_state (active) <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
|
|
|
|
|
nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
|
|
|
|
|
nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
static void
|
|
|
|
|
_internal_activation_auth_done (NMActiveConnection *active,
|
|
|
|
|
gboolean success,
|
|
|
|
|
const char *error_desc,
|
|
|
|
|
gpointer user_data1,
|
|
|
|
|
gpointer user_data2)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = user_data1;
|
2015-06-23 20:52:04 +02:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2013-08-28 16:19:20 -05:00
|
|
|
GError *error = NULL;
|
2012-09-13 16:51:58 -05:00
|
|
|
|
2015-06-23 20:52:04 +02:00
|
|
|
priv->authorizing_connections = g_slist_remove (priv->authorizing_connections, active);
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
if (success) {
|
2014-02-26 16:04:45 -06:00
|
|
|
if (_internal_activate_generic (self, active, &error)) {
|
|
|
|
|
g_object_unref (active);
|
2013-08-28 16:19:20 -05:00
|
|
|
return;
|
2014-02-26 16:04:45 -06:00
|
|
|
}
|
2012-02-23 10:00:08 -06:00
|
|
|
}
|
2007-02-08 15:34:26 +00:00
|
|
|
|
2014-01-17 15:33:18 -05:00
|
|
|
g_assert (error_desc || error);
|
|
|
|
|
_internal_activation_failed (self, active, error_desc ? error_desc : error->message);
|
2014-02-26 16:04:45 -06:00
|
|
|
g_object_unref (active);
|
2013-08-28 16:19:20 -05:00
|
|
|
g_clear_error (&error);
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-26 16:04:45 -06:00
|
|
|
/**
|
|
|
|
|
* nm_manager_activate_connection():
|
|
|
|
|
* @self: the #NMManager
|
2015-07-14 16:53:24 +02:00
|
|
|
* @connection: the #NMSettingsConnection to activate on @device
|
2014-02-26 16:04:45 -06:00
|
|
|
* @specific_object: the specific object path, if any, for the activation
|
|
|
|
|
* @device: the #NMDevice to activate @connection on
|
|
|
|
|
* @subject: the subject which requested activation
|
|
|
|
|
* @error: return location for an error
|
|
|
|
|
*
|
|
|
|
|
* 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
|
|
|
|
|
* referenced by the caller if the caller continues to use it.
|
|
|
|
|
*
|
|
|
|
|
* Returns: (transfer none): the new #NMActiveConnection that tracks
|
|
|
|
|
* activation of @connection on @device
|
|
|
|
|
*/
|
2013-08-28 16:19:20 -05:00
|
|
|
NMActiveConnection *
|
|
|
|
|
nm_manager_activate_connection (NMManager *self,
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *connection,
|
2013-08-28 16:19:20 -05:00
|
|
|
const char *specific_object,
|
|
|
|
|
NMDevice *device,
|
|
|
|
|
NMAuthSubject *subject,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
2015-06-23 20:52:04 +02:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2013-08-28 16:19:20 -05:00
|
|
|
NMActiveConnection *active;
|
2014-01-21 13:41:18 -06:00
|
|
|
char *error_desc = NULL;
|
2015-06-23 20:52:04 +02:00
|
|
|
GSList *iter;
|
2013-08-28 16:19:20 -05:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (connection != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (error != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (*error == NULL, NULL);
|
|
|
|
|
|
2014-01-21 13:41:18 -06:00
|
|
|
/* Ensure the subject has permissions for this connection */
|
2015-07-14 16:53:24 +02:00
|
|
|
if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection),
|
2014-08-14 13:34:57 +02:00
|
|
|
subject,
|
|
|
|
|
&error_desc)) {
|
2014-01-21 13:41:18 -06:00
|
|
|
g_set_error_literal (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
error_desc);
|
|
|
|
|
g_free (error_desc);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-23 20:52:04 +02:00
|
|
|
/* Look for a active connection that's equivalent and is already pending authorization
|
|
|
|
|
* and eventual activation. This is used to de-duplicate concurrent activations which would
|
|
|
|
|
* otherwise race and cause the device to disconnect and reconnect repeatedly.
|
|
|
|
|
* In particular, this allows the master and multiple slaves to concurrently auto-activate
|
|
|
|
|
* while all the slaves would use the same active-connection. */
|
|
|
|
|
for (iter = priv->authorizing_connections; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
active = iter->data;
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
if ( connection == nm_active_connection_get_settings_connection (active)
|
2015-06-23 20:52:04 +02:00
|
|
|
&& g_strcmp0 (nm_active_connection_get_specific_object (active), specific_object) == 0
|
|
|
|
|
&& nm_active_connection_get_device (active) == device
|
|
|
|
|
&& nm_auth_subject_is_internal (nm_active_connection_get_subject (active))
|
|
|
|
|
&& nm_auth_subject_is_internal (subject))
|
|
|
|
|
return active;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
active = _new_active_connection (self,
|
2015-07-14 16:53:24 +02:00
|
|
|
NM_CONNECTION (connection),
|
2013-08-28 16:19:20 -05:00
|
|
|
specific_object,
|
|
|
|
|
device,
|
|
|
|
|
subject,
|
|
|
|
|
error);
|
2015-06-23 20:52:04 +02:00
|
|
|
if (active) {
|
|
|
|
|
priv->authorizing_connections = g_slist_prepend (priv->authorizing_connections, active);
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_active_connection_authorize (active, NULL, _internal_activation_auth_done, self, NULL);
|
2015-06-23 20:52:04 +02:00
|
|
|
}
|
2013-08-28 16:19:20 -05:00
|
|
|
return active;
|
2007-10-01 15:38:39 +00:00
|
|
|
}
|
|
|
|
|
|
2014-10-15 21:17:45 -05:00
|
|
|
/**
|
|
|
|
|
* validate_activation_request:
|
|
|
|
|
* @self: the #NMManager
|
|
|
|
|
* @context: the D-Bus context of the requestor
|
|
|
|
|
* @connection: the partial or complete #NMConnection to be activated
|
|
|
|
|
* @device_path: the object path of the device to be activated, or "/"
|
|
|
|
|
* @out_device: on successful reutrn, the #NMDevice to be activated with @connection
|
|
|
|
|
* @out_vpn: on successful return, %TRUE if @connection is a VPN connection
|
|
|
|
|
* @error: location to store an error on failure
|
|
|
|
|
*
|
|
|
|
|
* Performs basic validation on an activation request, including ensuring that
|
|
|
|
|
* the requestor is a valid Unix process, is not disallowed in @connection
|
|
|
|
|
* permissions, and that a device exists that can activate @connection.
|
|
|
|
|
*
|
|
|
|
|
* Returns: on success, the #NMAuthSubject representing the requestor, or
|
|
|
|
|
* %NULL on error
|
|
|
|
|
*/
|
2013-07-29 12:42:16 -05:00
|
|
|
static NMAuthSubject *
|
2012-09-13 13:17:46 -05:00
|
|
|
validate_activation_request (NMManager *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2012-09-13 13:17:46 -05:00
|
|
|
NMConnection *connection,
|
|
|
|
|
const char *device_path,
|
|
|
|
|
NMDevice **out_device,
|
|
|
|
|
gboolean *out_vpn,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *device = NULL;
|
|
|
|
|
gboolean vpn = FALSE;
|
2013-07-29 12:42:16 -05:00
|
|
|
NMAuthSubject *subject = NULL;
|
2014-01-17 11:18:23 -06:00
|
|
|
char *error_desc = NULL;
|
2012-09-13 13:17:46 -05:00
|
|
|
|
|
|
|
|
g_assert (connection);
|
2013-08-28 16:19:20 -05:00
|
|
|
g_assert (out_device);
|
|
|
|
|
g_assert (out_vpn);
|
2012-09-13 13:17:46 -05:00
|
|
|
|
2013-07-29 12:42:16 -05:00
|
|
|
/* Validate the caller */
|
2014-08-14 13:34:57 +02:00
|
|
|
subject = nm_auth_subject_new_unix_process_from_context (context);
|
2013-07-29 12:42:16 -05:00
|
|
|
if (!subject) {
|
2012-09-13 16:51:58 -05:00
|
|
|
g_set_error_literal (error,
|
2013-07-29 12:42:16 -05:00
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
2012-09-13 16:51:58 -05:00
|
|
|
"Failed to get request UID.");
|
2013-07-29 12:42:16 -05:00
|
|
|
return NULL;
|
2012-09-13 16:51:58 -05:00
|
|
|
}
|
|
|
|
|
|
2014-01-17 11:18:23 -06:00
|
|
|
/* Ensure the subject has permissions for this connection */
|
2014-08-14 13:34:57 +02:00
|
|
|
if (!nm_auth_is_subject_in_acl (connection,
|
|
|
|
|
subject,
|
|
|
|
|
&error_desc)) {
|
2014-01-17 11:18:23 -06:00
|
|
|
g_set_error_literal (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
error_desc);
|
|
|
|
|
g_free (error_desc);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-19 15:18:17 +01:00
|
|
|
/* Not implemented yet, we want to fail early */
|
manager: fix impl_manager_add_and_activate_connection()
Note also the comment "Just make sure we don't expect specific data being
in the connection till then (especially in validate_activation_request())."
in impl_manager_add_and_activate_connection().
Creating a connection caused a failed assertion:
#0 0x00007ff8da3aa4e9 in g_logv (log_domain=0x7ff8ddf41036 "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7ffff5a0a090) at gmessages.c:989
#1 0x00007ff8da3aa63f in g_log (log_domain=<optimized out>, log_level=<optimized out>, format=<optimized out>) at gmessages.c:1025
#2 0x00007ff8dde8c47a in nm_utils_get_ip_config_method (connection=0x7ff8def21d20, ip_setting_type=140706868598912) at NetworkManagerUtils.c:1252
#3 0x00007ff8dde7d654 in validate_activation_request (self=0x7ff8def62150, context=0x7ff8deff5a00, connection=0x7ff8def21d20, device_path=0x7ff8def3f770 "/org/freedesktop/NetworkManager/Devices/2", out_device=0x7ffff5a0a370,
out_vpn=0x7ffff5a0a36c, error=0x7ffff5a0a378) at nm-manager.c:3061
#4 0x00007ff8dde7b7a2 in impl_manager_add_and_activate_connection (self=0x7ff8def62150, settings=0x7ff8def95460, device_path=0x7ff8def3f770 "/org/freedesktop/NetworkManager/Devices/2",
specific_object_path=0x7ff8deeeced0 "/org/freedesktop/NetworkManager/AccessPoint/227", context=0x7ff8deff5a00) at nm-manager.c:3386
#5 0x00007ff8dde6bd9c in dbus_glib_marshal_nm_manager_VOID__BOXED_BOXED_BOXED_POINTER (closure=0x7ffff5a0a5f0, return_value=0x0, n_param_values=5, param_values=0x7ff8defb9d30, invocation_hint=0x0,
marshal_data=0x7ff8dde7b660 <impl_manager_add_and_activate_connection>) at ./nm-manager-glue.h:189
#6 0x00007ff8dc506885 in invoke_object_method (message=0x7ff8def99a00, connection=0x7ff8deeec940, method=0x7ff8de1a6878 <dbus_glib_nm_manager_methods+72>, object_info=0x7ff8de1a2e70 <dbus_glib_nm_manager_object_info>,
object=0x7ff8def62150) at dbus-gobject.c:1899
#7 object_registration_message (connection=0x7ff8deeec940, message=message@entry=0x7ff8def99a00, user_data=user_data@entry=0x7ff8def16da0) at dbus-gobject.c:2161
#8 0x00007ff8dc2cef86 in _dbus_object_tree_dispatch_and_unlock (tree=0x7ff8deeec5e0, message=message@entry=0x7ff8def99a00, found_object=found_object@entry=0x7ffff5a0a814) at dbus-object-tree.c:862
#9 0x00007ff8dc2c10d9 in dbus_connection_dispatch (connection=connection@entry=0x7ff8deeec940) at dbus-connection.c:4699
#10 0x00007ff8dc503d65 in message_queue_dispatch (source=source@entry=0x7ff8deeee720, callback=<optimized out>, user_data=<optimized out>) at dbus-gmain.c:90
#11 0x00007ff8da3a32a6 in g_main_dispatch (context=0x7ff8deebd320) at gmain.c:3066
#12 g_main_context_dispatch (context=context@entry=0x7ff8deebd320) at gmain.c:3642
#13 0x00007ff8da3a3628 in g_main_context_iterate (context=0x7ff8deebd320, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3713
#14 0x00007ff8da3a3a3a in g_main_loop_run (loop=0x7ff8deebd3e0) at gmain.c:3907
#15 0x00007ff8dddc0979 in main (argc=1, argv=0x7ffff5a0afd8) at main.c:442
Fixes: 477033b9eff9a6ba168805eafe68272c62cb1cb4
2015-01-30 21:56:34 +01:00
|
|
|
if ( nm_connection_get_setting_connection (connection)
|
|
|
|
|
&& nm_connection_get_setting_ip6_config (connection)
|
|
|
|
|
&& !strcmp (nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG),
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
|
2015-01-19 15:18:17 +01:00
|
|
|
g_set_error_literal (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE,
|
|
|
|
|
"Sharing IPv6 connections is not supported yet.");
|
2016-05-31 17:04:03 +02:00
|
|
|
goto error;
|
2015-01-19 15:18:17 +01:00
|
|
|
}
|
|
|
|
|
|
2012-09-13 13:17:46 -05:00
|
|
|
/* Check whether it's a VPN or not */
|
|
|
|
|
if ( nm_connection_get_setting_vpn (connection)
|
|
|
|
|
|| nm_connection_is_type (connection, NM_SETTING_VPN_SETTING_NAME))
|
|
|
|
|
vpn = TRUE;
|
|
|
|
|
|
2012-09-13 15:57:36 -05:00
|
|
|
/* Normalize device path */
|
|
|
|
|
if (device_path && g_strcmp0 (device_path, "/") == 0)
|
|
|
|
|
device_path = NULL;
|
|
|
|
|
|
|
|
|
|
/* And validate it */
|
2013-08-28 16:19:20 -05:00
|
|
|
if (device_path) {
|
2012-09-13 13:17:46 -05:00
|
|
|
device = nm_manager_get_device_by_path (self, device_path);
|
2013-08-28 16:19:20 -05:00
|
|
|
if (!device) {
|
|
|
|
|
g_set_error_literal (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
|
|
|
|
"Device not found");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
2015-02-03 16:15:37 +01:00
|
|
|
} else
|
2015-10-19 14:14:17 +02:00
|
|
|
device = nm_manager_get_best_device_for_connection (self, connection, TRUE);
|
2015-02-03 16:15:37 +01:00
|
|
|
|
2014-10-15 21:17:45 -05:00
|
|
|
if (!device && !vpn) {
|
2014-08-04 16:27:43 -04:00
|
|
|
gboolean is_software = nm_connection_is_virtual (connection);
|
2012-09-13 13:17:46 -05:00
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
/* VPN and software-device connections don't need a device yet */
|
2014-10-15 21:17:45 -05:00
|
|
|
if (!is_software) {
|
2013-08-28 16:19:20 -05:00
|
|
|
g_set_error_literal (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
2015-06-25 09:34:39 +02:00
|
|
|
"No suitable device found for this connection.");
|
2013-08-28 16:19:20 -05:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_software) {
|
|
|
|
|
char *iface;
|
|
|
|
|
|
2014-09-18 17:50:47 -05:00
|
|
|
/* Look for an existing device with the connection's interface name */
|
2016-02-16 15:07:49 +01:00
|
|
|
iface = nm_manager_get_connection_iface (self, connection, NULL, error);
|
2014-09-18 17:50:47 -05:00
|
|
|
if (!iface)
|
2013-08-28 16:19:20 -05:00
|
|
|
goto error;
|
|
|
|
|
|
2014-10-15 21:17:45 -05:00
|
|
|
device = find_device_by_iface (self, iface, connection, NULL);
|
2013-08-28 16:19:20 -05:00
|
|
|
g_free (iface);
|
|
|
|
|
}
|
2012-09-13 13:17:46 -05:00
|
|
|
}
|
|
|
|
|
|
2014-10-15 21:17:45 -05:00
|
|
|
if ((!vpn || device_path) && !device) {
|
|
|
|
|
g_set_error_literal (error,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
|
|
|
|
"Failed to find a compatible device for this connection");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
*out_device = device;
|
|
|
|
|
*out_vpn = vpn;
|
2013-07-29 12:42:16 -05:00
|
|
|
return subject;
|
2013-08-28 16:19:20 -05:00
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
g_object_unref (subject);
|
|
|
|
|
return NULL;
|
2012-09-13 13:17:46 -05:00
|
|
|
}
|
|
|
|
|
|
2012-09-13 16:51:58 -05:00
|
|
|
/***********************************************************************/
|
|
|
|
|
|
2010-06-03 23:20:11 -07:00
|
|
|
static void
|
2014-02-26 16:04:45 -06:00
|
|
|
_activation_auth_done (NMActiveConnection *active,
|
|
|
|
|
gboolean success,
|
|
|
|
|
const char *error_desc,
|
|
|
|
|
gpointer user_data1,
|
|
|
|
|
gpointer user_data2)
|
2013-08-28 16:19:20 -05:00
|
|
|
{
|
|
|
|
|
NMManager *self = user_data1;
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context = user_data2;
|
2013-08-28 16:19:20 -05:00
|
|
|
GError *error = NULL;
|
2015-07-14 10:26:54 +02:00
|
|
|
NMAuthSubject *subject;
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *connection;
|
2015-07-14 10:26:54 +02:00
|
|
|
|
|
|
|
|
subject = nm_active_connection_get_subject (active);
|
2015-07-14 16:53:24 +02:00
|
|
|
connection = nm_active_connection_get_settings_connection (active);
|
2012-09-13 16:51:58 -05:00
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
if (success) {
|
|
|
|
|
if (_internal_activate_generic (self, active, &error)) {
|
2016-01-12 09:46:28 +01:00
|
|
|
g_dbus_method_invocation_return_value (context,
|
|
|
|
|
g_variant_new ("(o)",
|
|
|
|
|
nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))));
|
2016-04-20 12:10:55 +02:00
|
|
|
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, TRUE, NULL,
|
2015-07-14 10:26:54 +02:00
|
|
|
subject, NULL);
|
2014-02-26 16:04:45 -06:00
|
|
|
g_object_unref (active);
|
2013-08-28 16:19:20 -05:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
2016-01-12 09:46:28 +01:00
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
error_desc);
|
2012-09-13 16:51:58 -05:00
|
|
|
}
|
|
|
|
|
|
2014-03-04 18:27:31 -05:00
|
|
|
g_assert (error);
|
2016-04-20 12:10:55 +02:00
|
|
|
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, NULL,
|
2015-07-14 10:26:54 +02:00
|
|
|
subject, error->message);
|
2014-01-17 15:33:18 -05:00
|
|
|
_internal_activation_failed (self, active, error->message);
|
2015-07-14 10:26:54 +02:00
|
|
|
|
2014-02-26 16:04:45 -06:00
|
|
|
g_object_unref (active);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2008-11-21 18:11:15 +00:00
|
|
|
}
|
|
|
|
|
|
2007-10-01 15:38:39 +00:00
|
|
|
static void
|
2010-06-03 23:20:11 -07:00
|
|
|
impl_manager_activate_connection (NMManager *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2008-11-21 18:11:15 +00:00
|
|
|
const char *connection_path,
|
|
|
|
|
const char *device_path,
|
2015-04-15 14:53:30 -04:00
|
|
|
const char *specific_object_path)
|
2007-10-01 15:38:39 +00:00
|
|
|
{
|
2012-09-13 13:17:46 -05:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2013-08-28 16:19:20 -05:00
|
|
|
NMActiveConnection *active = NULL;
|
2013-07-29 12:42:16 -05:00
|
|
|
NMAuthSubject *subject = NULL;
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *connection = NULL;
|
2012-09-13 15:57:36 -05:00
|
|
|
NMDevice *device = NULL;
|
2013-08-28 16:19:20 -05:00
|
|
|
gboolean is_vpn = FALSE;
|
2011-01-10 23:39:12 -06:00
|
|
|
GError *error = NULL;
|
2007-10-16 18:59:36 +00:00
|
|
|
|
2013-07-24 10:41:39 -05:00
|
|
|
/* Normalize object paths */
|
|
|
|
|
if (g_strcmp0 (connection_path, "/") == 0)
|
|
|
|
|
connection_path = NULL;
|
|
|
|
|
if (g_strcmp0 (specific_object_path, "/") == 0)
|
|
|
|
|
specific_object_path = NULL;
|
|
|
|
|
if (g_strcmp0 (device_path, "/") == 0)
|
|
|
|
|
device_path = NULL;
|
|
|
|
|
|
|
|
|
|
/* If the connection path is given and valid, that connection is activated.
|
|
|
|
|
* Otherwise the "best" connection for the device is chosen and activated,
|
|
|
|
|
* regardless of whether that connection is autoconnect-enabled or not
|
|
|
|
|
* (since this is an explicit request, not an auto-activation request).
|
|
|
|
|
*/
|
2016-03-23 10:35:55 +01:00
|
|
|
if (connection_path) {
|
|
|
|
|
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.");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2013-07-24 10:41:39 -05:00
|
|
|
/* If no connection is given, find a suitable connection for the given device path */
|
|
|
|
|
if (!device_path) {
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
|
|
|
|
"Only devices may be activated without a specifying a connection");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
device = nm_manager_get_device_by_path (self, device_path);
|
|
|
|
|
if (!device) {
|
|
|
|
|
error = g_error_new (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
2016-03-30 09:00:06 +02:00
|
|
|
"Can not activate an unknown device '%s'", device_path);
|
2013-07-24 10:41:39 -05:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-23 10:35:55 +01:00
|
|
|
connection = nm_device_get_best_connection (device, specific_object_path, &error);
|
|
|
|
|
if (!connection)
|
2013-07-24 10:41:39 -05:00
|
|
|
goto error;
|
2012-09-13 13:17:46 -05:00
|
|
|
}
|
|
|
|
|
|
2013-07-29 12:42:16 -05:00
|
|
|
subject = validate_activation_request (self,
|
|
|
|
|
context,
|
2015-07-14 16:53:24 +02:00
|
|
|
NM_CONNECTION (connection),
|
2013-07-29 12:42:16 -05:00
|
|
|
device_path,
|
|
|
|
|
&device,
|
2013-08-28 16:19:20 -05:00
|
|
|
&is_vpn,
|
2013-07-29 12:42:16 -05:00
|
|
|
&error);
|
|
|
|
|
if (!subject)
|
2012-09-13 13:17:46 -05:00
|
|
|
goto error;
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
active = _new_active_connection (self,
|
2015-07-14 16:53:24 +02:00
|
|
|
NM_CONNECTION (connection),
|
2013-08-28 16:19:20 -05:00
|
|
|
specific_object_path,
|
|
|
|
|
device,
|
|
|
|
|
subject,
|
|
|
|
|
&error);
|
|
|
|
|
if (!active)
|
2013-07-29 12:42:16 -05:00
|
|
|
goto error;
|
2012-09-13 13:17:46 -05:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_active_connection_authorize (active, NULL, _activation_auth_done, self, context);
|
2013-08-28 16:19:20 -05:00
|
|
|
g_clear_object (&subject);
|
2013-07-29 12:42:16 -05:00
|
|
|
return;
|
|
|
|
|
|
2012-09-13 13:17:46 -05:00
|
|
|
error:
|
2015-07-14 10:26:54 +02:00
|
|
|
if (connection) {
|
2016-04-20 12:10:55 +02:00
|
|
|
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, NULL,
|
2015-07-14 10:26:54 +02:00
|
|
|
subject, error->message);
|
|
|
|
|
}
|
2013-08-28 16:19:20 -05:00
|
|
|
g_clear_object (&active);
|
2013-07-29 12:42:16 -05:00
|
|
|
g_clear_object (&subject);
|
2013-08-28 16:19:20 -05:00
|
|
|
|
2012-09-13 13:17:46 -05:00
|
|
|
g_assert (error);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2011-01-10 23:39:12 -06:00
|
|
|
}
|
|
|
|
|
|
2012-09-13 16:51:58 -05:00
|
|
|
/***********************************************************************/
|
|
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
typedef struct {
|
|
|
|
|
NMManager *manager;
|
|
|
|
|
NMActiveConnection *active;
|
|
|
|
|
} AddAndActivateInfo;
|
|
|
|
|
|
2011-01-10 23:39:12 -06:00
|
|
|
static void
|
2015-07-14 16:53:24 +02:00
|
|
|
activation_add_done (NMSettings *settings,
|
2012-09-13 16:51:58 -05:00
|
|
|
NMSettingsConnection *new_connection,
|
2011-01-10 23:39:12 -06:00
|
|
|
GError *error,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2015-07-15 14:44:45 +02:00
|
|
|
NMAuthSubject *subject,
|
2011-01-10 23:39:12 -06:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2013-08-28 16:19:20 -05:00
|
|
|
AddAndActivateInfo *info = user_data;
|
2015-07-14 16:53:24 +02:00
|
|
|
NMManager *self;
|
|
|
|
|
gs_unref_object NMActiveConnection *active = NULL;
|
2012-09-13 16:51:58 -05:00
|
|
|
GError *local = NULL;
|
2011-01-10 23:39:12 -06:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
self = info->manager;
|
|
|
|
|
active = info->active;
|
|
|
|
|
g_slice_free (AddAndActivateInfo, info);
|
|
|
|
|
|
2012-09-13 16:51:58 -05:00
|
|
|
if (!error) {
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_active_connection_set_settings_connection (active, new_connection);
|
2013-08-28 16:19:20 -05:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
if (_internal_activate_generic (self, active, &local)) {
|
2015-07-17 10:34:10 +02:00
|
|
|
nm_settings_connection_commit_changes (new_connection,
|
|
|
|
|
NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION | NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED,
|
|
|
|
|
NULL, NULL);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_value (
|
2015-07-14 16:53:24 +02:00
|
|
|
context,
|
|
|
|
|
g_variant_new ("(oo)",
|
|
|
|
|
nm_connection_get_path (NM_CONNECTION (new_connection)),
|
|
|
|
|
nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))));
|
2015-07-14 10:26:54 +02:00
|
|
|
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_active_connection_get_settings_connection (active),
|
2015-07-14 10:26:54 +02:00
|
|
|
TRUE,
|
2016-04-20 12:10:55 +02:00
|
|
|
NULL,
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_active_connection_get_subject (active),
|
2015-07-14 10:26:54 +02:00
|
|
|
NULL);
|
2015-07-14 16:53:24 +02:00
|
|
|
return;
|
2013-08-28 16:19:20 -05:00
|
|
|
}
|
|
|
|
|
error = local;
|
2011-01-10 23:39:12 -06:00
|
|
|
}
|
2012-09-13 16:51:58 -05:00
|
|
|
|
2014-03-04 18:27:31 -05:00
|
|
|
g_assert (error);
|
2015-07-14 16:53:24 +02:00
|
|
|
_internal_activation_failed (self, active, error->message);
|
2015-04-22 15:08:21 +02:00
|
|
|
nm_settings_connection_delete (new_connection, NULL, NULL);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_gerror (context, error);
|
2015-07-14 10:26:54 +02:00
|
|
|
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
|
2015-08-10 12:33:01 +02:00
|
|
|
NULL,
|
2015-07-14 10:26:54 +02:00
|
|
|
FALSE,
|
2016-04-20 12:10:55 +02:00
|
|
|
NULL,
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_active_connection_get_subject (active),
|
2015-07-14 10:26:54 +02:00
|
|
|
error->message);
|
2012-09-13 16:51:58 -05:00
|
|
|
g_clear_error (&local);
|
2011-01-10 23:39:12 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-02-26 16:04:45 -06:00
|
|
|
_add_and_activate_auth_done (NMActiveConnection *active,
|
|
|
|
|
gboolean success,
|
|
|
|
|
const char *error_desc,
|
|
|
|
|
gpointer user_data1,
|
|
|
|
|
gpointer user_data2)
|
2011-01-10 23:39:12 -06:00
|
|
|
{
|
2013-08-28 16:19:20 -05:00
|
|
|
NMManager *self = user_data1;
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context = user_data2;
|
2013-08-28 16:19:20 -05:00
|
|
|
AddAndActivateInfo *info;
|
|
|
|
|
GError *error = NULL;
|
2012-09-13 16:51:58 -05:00
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
if (success) {
|
2015-07-14 16:53:24 +02:00
|
|
|
NMConnection *connection;
|
|
|
|
|
|
|
|
|
|
connection = g_object_steal_data (G_OBJECT (active),
|
|
|
|
|
TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE);
|
|
|
|
|
|
|
|
|
|
info = g_slice_new (AddAndActivateInfo);
|
2013-08-28 16:19:20 -05:00
|
|
|
info->manager = self;
|
|
|
|
|
info->active = g_object_ref (active);
|
2011-01-10 23:39:12 -06:00
|
|
|
|
|
|
|
|
/* Basic sender auth checks performed; try to add the connection */
|
2013-08-27 14:51:16 +02:00
|
|
|
nm_settings_add_connection_dbus (priv->settings,
|
2015-07-14 16:53:24 +02:00
|
|
|
connection,
|
2015-04-22 15:08:21 +02:00
|
|
|
FALSE,
|
2012-09-13 16:51:58 -05:00
|
|
|
context,
|
2013-08-27 14:51:16 +02:00
|
|
|
activation_add_done,
|
2013-08-28 16:19:20 -05:00
|
|
|
info);
|
2015-07-14 16:53:24 +02:00
|
|
|
g_object_unref (connection);
|
2013-08-28 16:19:20 -05:00
|
|
|
} else {
|
|
|
|
|
g_assert (error_desc);
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
error_desc);
|
2015-07-14 10:26:54 +02:00
|
|
|
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
|
2015-08-10 12:33:01 +02:00
|
|
|
NULL,
|
2015-07-14 10:26:54 +02:00
|
|
|
FALSE,
|
2016-04-20 12:10:55 +02:00
|
|
|
NULL,
|
2015-07-14 10:26:54 +02:00
|
|
|
nm_active_connection_get_subject (active),
|
|
|
|
|
error->message);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2011-01-10 23:39:12 -06:00
|
|
|
}
|
2014-02-26 16:04:45 -06:00
|
|
|
|
|
|
|
|
g_object_unref (active);
|
2011-01-10 23:39:12 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
impl_manager_add_and_activate_connection (NMManager *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
GVariant *settings,
|
2011-01-10 23:39:12 -06:00
|
|
|
const char *device_path,
|
2015-04-15 14:53:30 -04:00
|
|
|
const char *specific_object_path)
|
2011-01-10 23:39:12 -06:00
|
|
|
{
|
2012-09-13 13:17:46 -05:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
GSList *all_connections = NULL;
|
2013-11-01 10:23:09 +01:00
|
|
|
NMActiveConnection *active = NULL;
|
2013-07-29 12:42:16 -05:00
|
|
|
NMAuthSubject *subject = NULL;
|
2011-01-10 23:39:12 -06:00
|
|
|
GError *error = NULL;
|
2012-09-13 13:17:46 -05:00
|
|
|
NMDevice *device = NULL;
|
|
|
|
|
gboolean vpn = FALSE;
|
|
|
|
|
|
2014-02-10 10:51:15 +01:00
|
|
|
/* Normalize object paths */
|
|
|
|
|
if (g_strcmp0 (specific_object_path, "/") == 0)
|
|
|
|
|
specific_object_path = NULL;
|
|
|
|
|
if (g_strcmp0 (device_path, "/") == 0)
|
|
|
|
|
device_path = NULL;
|
|
|
|
|
|
2013-11-01 13:59:57 +01:00
|
|
|
/* Try to create a new connection with the given settings.
|
|
|
|
|
* We allow empty settings for AddAndActivateConnection(). In that case,
|
2014-02-10 11:13:55 +01:00
|
|
|
* the connection will be completed in nm_utils_complete_generic() or
|
2013-11-01 13:59:57 +01:00
|
|
|
* nm_device_complete_connection() below. Just make sure we don't expect
|
|
|
|
|
* specific data being in the connection till then (especially in
|
|
|
|
|
* validate_activation_request()).
|
|
|
|
|
*/
|
2014-08-13 14:34:29 -04:00
|
|
|
connection = nm_simple_connection_new ();
|
2015-04-15 14:53:30 -04:00
|
|
|
if (settings && g_variant_n_children (settings))
|
2016-03-23 16:12:12 +01:00
|
|
|
_nm_connection_replace_settings (connection, settings, NM_SETTING_PARSE_FLAGS_STRICT, NULL);
|
2012-09-13 13:17:46 -05:00
|
|
|
|
2013-07-29 12:42:16 -05:00
|
|
|
subject = validate_activation_request (self,
|
|
|
|
|
context,
|
|
|
|
|
connection,
|
|
|
|
|
device_path,
|
|
|
|
|
&device,
|
|
|
|
|
&vpn,
|
|
|
|
|
&error);
|
|
|
|
|
if (!subject)
|
2012-09-13 13:17:46 -05:00
|
|
|
goto error;
|
|
|
|
|
|
2016-05-16 19:24:23 +02:00
|
|
|
all_connections = nm_settings_get_connections_sorted (priv->settings);
|
2012-09-13 13:17:46 -05:00
|
|
|
if (vpn) {
|
|
|
|
|
/* Try to fill the VPN's connection setting and name at least */
|
|
|
|
|
if (!nm_connection_get_setting_vpn (connection)) {
|
2014-10-15 15:27:25 -04:00
|
|
|
error = g_error_new_literal (NM_CONNECTION_ERROR,
|
|
|
|
|
NM_CONNECTION_ERROR_MISSING_SETTING,
|
2012-09-13 13:17:46 -05:00
|
|
|
"VPN connections require a 'vpn' setting");
|
2014-10-15 15:27:25 -04:00
|
|
|
g_prefix_error (&error, "%s: ", NM_SETTING_VPN_SETTING_NAME);
|
2012-09-13 13:17:46 -05:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-08 13:57:20 +01:00
|
|
|
nm_utils_complete_generic (NM_PLATFORM_GET,
|
|
|
|
|
connection,
|
2012-09-13 13:17:46 -05:00
|
|
|
NM_SETTING_VPN_SETTING_NAME,
|
|
|
|
|
all_connections,
|
|
|
|
|
NULL,
|
2014-08-25 16:21:59 +02:00
|
|
|
_("VPN connection"),
|
2014-08-05 17:11:57 -04:00
|
|
|
NULL,
|
2012-09-13 13:17:46 -05:00
|
|
|
FALSE); /* No IPv6 by default for now */
|
|
|
|
|
} else {
|
|
|
|
|
/* Let each device subclass complete the connection */
|
|
|
|
|
if (!nm_device_complete_connection (device,
|
|
|
|
|
connection,
|
|
|
|
|
specific_object_path,
|
|
|
|
|
all_connections,
|
|
|
|
|
&error))
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
g_slist_free (all_connections);
|
|
|
|
|
all_connections = NULL;
|
2010-06-03 23:20:11 -07:00
|
|
|
|
2013-08-28 16:19:20 -05:00
|
|
|
active = _new_active_connection (self,
|
|
|
|
|
connection,
|
|
|
|
|
specific_object_path,
|
|
|
|
|
device,
|
|
|
|
|
subject,
|
|
|
|
|
&error);
|
|
|
|
|
if (!active)
|
2013-07-29 12:42:16 -05:00
|
|
|
goto error;
|
2012-09-13 13:17:46 -05:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
g_object_set_data_full (G_OBJECT (active),
|
|
|
|
|
TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE,
|
|
|
|
|
connection,
|
|
|
|
|
g_object_unref);
|
|
|
|
|
|
|
|
|
|
nm_active_connection_authorize (active, connection, _add_and_activate_auth_done, self, context);
|
2013-07-29 12:42:16 -05:00
|
|
|
g_object_unref (subject);
|
2013-08-28 16:19:20 -05:00
|
|
|
return;
|
2013-07-29 12:42:16 -05:00
|
|
|
|
2012-09-13 13:17:46 -05:00
|
|
|
error:
|
2016-04-20 12:10:55 +02:00
|
|
|
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, NULL, FALSE, NULL, subject, error->message);
|
2012-09-13 13:17:46 -05:00
|
|
|
g_clear_object (&connection);
|
|
|
|
|
g_slist_free (all_connections);
|
2013-08-28 16:19:20 -05:00
|
|
|
g_clear_object (&subject);
|
|
|
|
|
g_clear_object (&active);
|
2012-09-13 13:17:46 -05:00
|
|
|
|
|
|
|
|
g_assert (error);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2007-02-08 15:34:26 +00:00
|
|
|
}
|
|
|
|
|
|
2012-09-13 16:51:58 -05:00
|
|
|
/***********************************************************************/
|
|
|
|
|
|
2008-03-26 13:43:01 +00:00
|
|
|
gboolean
|
|
|
|
|
nm_manager_deactivate_connection (NMManager *manager,
|
|
|
|
|
const char *connection_path,
|
2008-10-11 19:57:45 +00:00
|
|
|
NMDeviceStateReason reason,
|
2008-03-26 13:43:01 +00:00
|
|
|
GError **error)
|
2007-10-03 14:48:25 +00:00
|
|
|
{
|
2012-09-14 15:21:29 -05:00
|
|
|
NMActiveConnection *active;
|
2008-03-26 13:43:01 +00:00
|
|
|
gboolean success = FALSE;
|
2007-10-03 14:48:25 +00:00
|
|
|
|
2012-09-14 15:21:29 -05:00
|
|
|
active = active_connection_get_by_path (manager, connection_path);
|
|
|
|
|
if (!active) {
|
|
|
|
|
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
|
|
|
|
|
"The connection was not active.");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2007-10-03 14:48:25 +00:00
|
|
|
|
2012-09-14 15:21:29 -05:00
|
|
|
if (NM_IS_VPN_CONNECTION (active)) {
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
NMVpnConnectionStateReason vpn_reason = NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED;
|
2007-10-03 14:48:25 +00:00
|
|
|
|
2012-09-14 15:21:29 -05:00
|
|
|
if (reason == NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
|
|
|
|
|
vpn_reason = NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED;
|
2015-08-19 18:55:53 +02:00
|
|
|
if (nm_vpn_connection_deactivate (NM_VPN_CONNECTION (active), vpn_reason, FALSE))
|
2008-03-26 13:43:01 +00:00
|
|
|
success = TRUE;
|
2013-06-28 14:04:29 +02:00
|
|
|
else
|
|
|
|
|
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
|
|
|
|
|
"The VPN connection was not active.");
|
2008-03-26 13:43:01 +00:00
|
|
|
} else {
|
2012-09-14 15:21:29 -05:00
|
|
|
g_assert (NM_IS_ACT_REQUEST (active));
|
|
|
|
|
nm_device_state_changed (nm_active_connection_get_device (active),
|
2014-01-03 13:58:05 -05:00
|
|
|
NM_DEVICE_STATE_DEACTIVATING,
|
2012-09-14 15:21:29 -05:00
|
|
|
reason);
|
|
|
|
|
success = TRUE;
|
2008-03-26 13:43:01 +00:00
|
|
|
}
|
|
|
|
|
|
2012-09-14 15:21:29 -05:00
|
|
|
if (success)
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (manager, PROP_ACTIVE_CONNECTIONS);
|
2012-09-14 15:21:29 -05:00
|
|
|
|
2008-03-26 13:43:01 +00:00
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-04 00:42:10 -07:00
|
|
|
static void
|
|
|
|
|
deactivate_net_auth_done_cb (NMAuthChain *chain,
|
2011-05-18 22:20:24 -05:00
|
|
|
GError *auth_error,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2010-06-04 00:42:10 -07:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2011-05-18 22:20:24 -05:00
|
|
|
GError *error = NULL;
|
2010-06-04 00:42:10 -07:00
|
|
|
NMAuthCallResult result;
|
2015-07-14 10:26:54 +02:00
|
|
|
NMActiveConnection *active;
|
|
|
|
|
char *path;
|
2010-06-04 00:42:10 -07:00
|
|
|
|
2013-07-29 11:53:23 -05:00
|
|
|
g_assert (context);
|
|
|
|
|
|
2010-06-04 00:42:10 -07:00
|
|
|
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
|
|
|
|
|
|
2015-07-14 10:26:54 +02:00
|
|
|
path = nm_auth_chain_get_data (chain, "path");
|
2012-10-08 12:52:15 -05:00
|
|
|
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
|
|
|
|
|
|
2012-06-01 16:53:23 -05:00
|
|
|
if (auth_error) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "Disconnect request failed: %s", auth_error->message);
|
2012-06-01 16:53:23 -05:00
|
|
|
error = g_error_new (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Deactivate request failed: %s",
|
|
|
|
|
auth_error->message);
|
|
|
|
|
} else if (result != NM_AUTH_CALL_RESULT_YES) {
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Not authorized to deactivate connections");
|
|
|
|
|
} else {
|
|
|
|
|
/* success; deactivation allowed */
|
2011-05-18 22:20:24 -05:00
|
|
|
if (!nm_manager_deactivate_connection (self,
|
2015-07-14 10:26:54 +02:00
|
|
|
path,
|
2011-05-18 22:20:24 -05:00
|
|
|
NM_DEVICE_STATE_REASON_USER_REQUESTED,
|
|
|
|
|
&error))
|
2016-02-28 16:25:36 +01:00
|
|
|
nm_assert (error);
|
2010-06-04 00:42:10 -07:00
|
|
|
}
|
|
|
|
|
|
2016-02-28 16:25:36 +01:00
|
|
|
active = active_connection_get_by_path (self, path);
|
2015-07-14 10:26:54 +02:00
|
|
|
if (active) {
|
|
|
|
|
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE,
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_active_connection_get_settings_connection (active),
|
2015-07-14 10:26:54 +02:00
|
|
|
!error,
|
2016-04-20 12:10:55 +02:00
|
|
|
NULL,
|
2015-07-14 10:26:54 +02:00
|
|
|
nm_auth_chain_get_subject (chain),
|
|
|
|
|
error ? error->message : NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
if (error)
|
|
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
|
|
|
|
else
|
|
|
|
|
g_dbus_method_invocation_return_value (context, NULL);
|
|
|
|
|
|
2010-06-04 00:42:10 -07:00
|
|
|
nm_auth_chain_unref (chain);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
impl_manager_deactivate_connection (NMManager *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
const char *active_path)
|
2010-06-04 00:42:10 -07:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2015-08-12 18:29:10 +02:00
|
|
|
NMActiveConnection *ac;
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection *connection = NULL;
|
2010-06-04 00:42:10 -07:00
|
|
|
GError *error = NULL;
|
2014-01-17 11:18:23 -06:00
|
|
|
NMAuthSubject *subject = NULL;
|
2010-06-04 00:42:10 -07:00
|
|
|
NMAuthChain *chain;
|
2014-01-17 11:18:23 -06:00
|
|
|
char *error_desc = NULL;
|
2010-06-04 00:42:10 -07:00
|
|
|
|
2012-08-22 17:11:31 -05:00
|
|
|
/* Find the connection by its object path */
|
2015-08-12 18:29:10 +02:00
|
|
|
ac = active_connection_get_by_path (self, active_path);
|
|
|
|
|
if (ac)
|
2015-07-14 16:53:24 +02:00
|
|
|
connection = nm_active_connection_get_settings_connection (ac);
|
2010-06-04 00:42:10 -07:00
|
|
|
|
|
|
|
|
if (!connection) {
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
|
|
|
|
|
"The connection was not active.");
|
2013-07-29 11:53:23 -05:00
|
|
|
goto done;
|
2010-06-04 00:42:10 -07:00
|
|
|
}
|
|
|
|
|
|
2014-01-17 11:18:23 -06:00
|
|
|
/* Validate the caller */
|
2014-08-14 13:34:57 +02:00
|
|
|
subject = nm_auth_subject_new_unix_process_from_context (context);
|
2014-01-17 11:18:23 -06:00
|
|
|
if (!subject) {
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Failed to get request UID.");
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Ensure the subject has permissions for this connection */
|
2015-07-14 16:53:24 +02:00
|
|
|
if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection),
|
2014-08-14 13:34:57 +02:00
|
|
|
subject,
|
|
|
|
|
&error_desc)) {
|
2014-01-17 11:18:23 -06:00
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
error_desc);
|
|
|
|
|
g_free (error_desc);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-16 12:30:41 -06:00
|
|
|
/* Validate the user request */
|
2014-01-17 11:18:23 -06:00
|
|
|
chain = nm_auth_chain_new_subject (subject, context, deactivate_net_auth_done_cb, self);
|
2013-07-29 11:53:23 -05:00
|
|
|
if (!chain) {
|
2010-06-04 00:42:10 -07:00
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
2013-07-29 11:53:23 -05:00
|
|
|
"Unable to authenticate request.");
|
|
|
|
|
goto done;
|
2010-06-04 00:42:10 -07:00
|
|
|
}
|
2013-07-29 11:53:23 -05:00
|
|
|
|
|
|
|
|
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
|
|
|
|
nm_auth_chain_set_data (chain, "path", g_strdup (active_path), g_free);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
|
|
|
|
|
|
|
|
|
|
done:
|
2015-07-14 10:26:54 +02:00
|
|
|
if (error) {
|
|
|
|
|
if (connection) {
|
2016-04-20 12:10:55 +02:00
|
|
|
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE, NULL,
|
2015-07-14 10:26:54 +02:00
|
|
|
subject, error->message);
|
|
|
|
|
}
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2015-07-14 10:26:54 +02:00
|
|
|
}
|
|
|
|
|
g_clear_object (&subject);
|
2007-10-03 14:48:25 +00:00
|
|
|
}
|
|
|
|
|
|
2014-04-03 15:14:00 -04:00
|
|
|
static gboolean
|
|
|
|
|
device_is_wake_on_lan (NMDevice *device)
|
|
|
|
|
{
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
return nm_platform_link_get_wake_on_lan (NM_PLATFORM_GET, nm_device_get_ip_ifindex (device));
|
2014-04-03 15:14:00 -04:00
|
|
|
}
|
|
|
|
|
|
2016-05-05 14:14:40 +02:00
|
|
|
static gboolean
|
|
|
|
|
sleep_devices_add (NMManager *self, NMDevice *device, gboolean suspending)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
NMSleepMonitorInhibitorHandle *handle = NULL;
|
|
|
|
|
|
|
|
|
|
if (g_hash_table_lookup_extended (priv->sleep_devices, device, NULL, (gpointer *) &handle)) {
|
|
|
|
|
if (suspending) {
|
|
|
|
|
/* if we are suspending, always insert a new handle in sleep_devices.
|
|
|
|
|
* Even if we had an old handle, it might be stale by now. */
|
|
|
|
|
g_hash_table_insert (priv->sleep_devices, device,
|
|
|
|
|
nm_sleep_monitor_inhibit_take (priv->sleep_monitor));
|
|
|
|
|
if (handle)
|
|
|
|
|
nm_sleep_monitor_inhibit_release (priv->sleep_monitor, handle);
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_hash_table_insert (priv->sleep_devices,
|
|
|
|
|
g_object_ref (device),
|
|
|
|
|
suspending
|
|
|
|
|
? nm_sleep_monitor_inhibit_take (priv->sleep_monitor)
|
|
|
|
|
: NULL);
|
|
|
|
|
g_signal_connect (device, "notify::" NM_DEVICE_STATE, (GCallback) device_sleep_cb, self);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
sleep_devices_remove (NMManager *self, NMDevice *device)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
NMSleepMonitorInhibitorHandle *handle;
|
|
|
|
|
|
|
|
|
|
if (!g_hash_table_lookup_extended (priv->sleep_devices, device, NULL, (gpointer *) &handle))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (handle)
|
|
|
|
|
nm_sleep_monitor_inhibit_release (priv->sleep_monitor, handle);
|
|
|
|
|
|
|
|
|
|
/* Remove device from hash */
|
|
|
|
|
g_signal_handlers_disconnect_by_func (device, device_sleep_cb, self);
|
|
|
|
|
g_hash_table_remove (priv->sleep_devices, device);
|
|
|
|
|
g_object_unref (device);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
sleep_devices_clear (NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
NMDevice *device;
|
|
|
|
|
NMSleepMonitorInhibitorHandle *handle;
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
|
|
|
|
|
if (!priv->sleep_devices)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_hash_table_iter_init (&iter, priv->sleep_devices);
|
|
|
|
|
while (g_hash_table_iter_next (&iter, (gpointer *) &device, (gpointer *) &handle)) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (device, device_sleep_cb, self);
|
|
|
|
|
if (handle)
|
|
|
|
|
nm_sleep_monitor_inhibit_release (priv->sleep_monitor, handle);
|
|
|
|
|
g_object_unref (device);
|
|
|
|
|
g_hash_table_iter_remove (&iter);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
device_sleep_cb (NMDevice *device,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
switch (nm_device_get_state (device)) {
|
|
|
|
|
case NM_DEVICE_STATE_DISCONNECTED:
|
|
|
|
|
_LOGD (LOGD_SUSPEND, "sleep: unmanaging device %s", nm_device_get_ip_iface (device));
|
|
|
|
|
nm_device_set_unmanaged_by_flags_queue (device,
|
|
|
|
|
NM_UNMANAGED_SLEEPING,
|
|
|
|
|
TRUE,
|
|
|
|
|
NM_DEVICE_STATE_REASON_SLEEPING);
|
|
|
|
|
break;
|
|
|
|
|
case NM_DEVICE_STATE_UNMANAGED:
|
|
|
|
|
_LOGD (LOGD_SUSPEND, "sleep: device %s is ready", nm_device_get_ip_iface (device));
|
|
|
|
|
|
|
|
|
|
if (!sleep_devices_remove (self, device))
|
|
|
|
|
g_return_if_reached ();
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-22 08:55:30 -07:00
|
|
|
static void
|
2014-04-03 15:14:00 -04:00
|
|
|
do_sleep_wake (NMManager *self, gboolean sleeping_changed)
|
2007-02-08 15:34:26 +00:00
|
|
|
{
|
2010-05-22 08:55:30 -07:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2014-04-03 15:14:00 -04:00
|
|
|
gboolean suspending, waking_from_suspend;
|
2009-06-11 00:39:12 -04:00
|
|
|
GSList *iter;
|
2007-02-08 15:34:26 +00:00
|
|
|
|
2014-04-03 15:14:00 -04:00
|
|
|
suspending = sleeping_changed && priv->sleeping;
|
|
|
|
|
waking_from_suspend = sleeping_changed && !priv->sleeping;
|
|
|
|
|
|
2010-05-22 08:55:30 -07:00
|
|
|
if (manager_sleeping (self)) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_SUSPEND, "%s...", suspending ? "sleeping" : "disabling");
|
2007-02-08 15:34:26 +00:00
|
|
|
|
2014-04-03 15:14:00 -04:00
|
|
|
/* FIXME: are there still hardware devices that need to be disabled around
|
|
|
|
|
* suspend/resume?
|
2007-02-08 15:34:26 +00:00
|
|
|
*/
|
2013-12-17 14:24:39 -05:00
|
|
|
for (iter = priv->devices; iter; iter = iter->next) {
|
|
|
|
|
NMDevice *device = iter->data;
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-04-03 15:14:00 -04:00
|
|
|
/* FIXME: shouldn't we be unmanaging software devices if !suspending? */
|
|
|
|
|
if (nm_device_is_software (device))
|
|
|
|
|
continue;
|
|
|
|
|
/* Wake-on-LAN devices will be taken down post-suspend rather than pre- */
|
2016-05-05 14:14:40 +02:00
|
|
|
if (suspending && device_is_wake_on_lan (device)) {
|
|
|
|
|
_LOGD (LOGD_SUSPEND, "sleep: device %s has wake-on-lan, skipping",
|
|
|
|
|
nm_device_get_ip_iface (device));
|
2014-04-03 15:14:00 -04:00
|
|
|
continue;
|
2016-05-05 14:14:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nm_device_is_activating (device) ||
|
|
|
|
|
nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
|
|
|
|
|
_LOGD (LOGD_SUSPEND, "sleep: wait disconnection of device %s",
|
|
|
|
|
nm_device_get_ip_iface (device));
|
2014-04-03 15:14:00 -04:00
|
|
|
|
2016-05-05 14:14:40 +02:00
|
|
|
if (sleep_devices_add (self, device, suspending))
|
|
|
|
|
nm_device_queue_state (device, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_SLEEPING);
|
|
|
|
|
} else {
|
|
|
|
|
nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, TRUE, NM_DEVICE_STATE_REASON_SLEEPING);
|
|
|
|
|
}
|
2013-12-17 14:24:39 -05:00
|
|
|
}
|
2010-05-22 08:55:30 -07:00
|
|
|
} else {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_SUSPEND, "%s...", waking_from_suspend ? "waking up" : "re-enabling");
|
2014-04-03 15:14:00 -04:00
|
|
|
|
|
|
|
|
if (waking_from_suspend) {
|
2016-05-05 14:14:40 +02:00
|
|
|
sleep_devices_clear (self);
|
2014-04-03 15:14:00 -04:00
|
|
|
/* Belatedly take down Wake-on-LAN devices; ideally we wouldn't have to do this
|
|
|
|
|
* but for now it's the only way to make sure we re-check their connectivity.
|
|
|
|
|
*/
|
|
|
|
|
for (iter = priv->devices; iter; iter = iter->next) {
|
|
|
|
|
NMDevice *device = iter->data;
|
|
|
|
|
|
|
|
|
|
if (nm_device_is_software (device))
|
|
|
|
|
continue;
|
|
|
|
|
if (device_is_wake_on_lan (device))
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, TRUE, NM_DEVICE_STATE_REASON_SLEEPING);
|
2014-04-03 15:14:00 -04:00
|
|
|
}
|
|
|
|
|
}
|
2007-02-08 15:34:26 +00:00
|
|
|
|
2009-11-24 10:43:43 -08:00
|
|
|
/* Ensure rfkill state is up-to-date since we don't respond to state
|
|
|
|
|
* changes during sleep.
|
|
|
|
|
*/
|
2009-12-23 00:03:45 -08:00
|
|
|
nm_manager_rfkill_update (self, RFKILL_TYPE_UNKNOWN);
|
2009-11-24 10:43:43 -08:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
/* Re-manage managed devices */
|
|
|
|
|
for (iter = priv->devices; iter; iter = iter->next) {
|
|
|
|
|
NMDevice *device = NM_DEVICE (iter->data);
|
2009-12-23 00:03:45 -08:00
|
|
|
guint i;
|
2009-11-20 09:11:46 -08:00
|
|
|
|
2016-03-26 01:26:36 -04:00
|
|
|
if (nm_device_is_software (device)) {
|
|
|
|
|
/* We do not manage/unmanage software devices but
|
|
|
|
|
* their dhcp leases could have gone stale so we need
|
|
|
|
|
* to renew them */
|
|
|
|
|
nm_device_update_dynamic_ip_setup (device);
|
2013-12-17 14:24:39 -05:00
|
|
|
continue;
|
2016-03-26 01:26:36 -04:00
|
|
|
}
|
2013-12-17 14:24:39 -05:00
|
|
|
|
2009-11-20 09:11:46 -08:00
|
|
|
/* enable/disable wireless devices since that we don't respond
|
|
|
|
|
* to killswitch changes during sleep.
|
|
|
|
|
*/
|
2009-12-23 00:03:45 -08:00
|
|
|
for (i = 0; i < RFKILL_TYPE_MAX; i++) {
|
|
|
|
|
RadioState *rstate = &priv->radio_states[i];
|
2011-04-13 21:58:25 -05:00
|
|
|
gboolean enabled = radio_enabled_for_rstate (rstate, TRUE);
|
2009-12-23 00:03:45 -08:00
|
|
|
|
2010-04-08 18:23:43 -07:00
|
|
|
if (rstate->desc) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_RFKILL, "%s %s devices (hw_enabled %d, sw_enabled %d, user_enabled %d)",
|
|
|
|
|
enabled ? "enabling" : "disabling",
|
|
|
|
|
rstate->desc, rstate->hw_enabled, rstate->sw_enabled, rstate->user_enabled);
|
2010-04-08 18:23:43 -07:00
|
|
|
}
|
|
|
|
|
|
2011-11-18 12:02:58 -06:00
|
|
|
if (nm_device_get_rfkill_type (device) == rstate->rtype)
|
2011-11-17 23:38:08 -06:00
|
|
|
nm_device_set_enabled (device, enabled);
|
2009-12-23 00:03:45 -08:00
|
|
|
}
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2015-11-05 07:52:51 +01:00
|
|
|
nm_device_set_autoconnect (device, TRUE);
|
2012-05-14 15:32:54 +02:00
|
|
|
|
device: remove default-unmanaged and refactor unmanaged flags
Get rid of NM_UNMANAGED_DEFAULT and refine the interaction between
unmanaged flags, device state and managed property.
Previously, the NM_UNMANAGED_DEFAULT was special in that a device was
still considered managed if it had solely the NM_UNMANAGED_DEFAULT flag
set and its state was managed. Thus, whether the device (state) was managed,
depended on the device state too.
Now, a device is considered managed (or unmanaged) based on the unmanaged
flags and realization state alone. At the same time, the device state
directly corresponds to the managed property of the device. Of course,
while changing the unmanaged flags, that invariant is shortly violated
until the state transistion is complete.
Introduce more unmanaged flags whereas some of them are non-authorative.
For example, the EXTERNAL_DOWN flag has only effect as long as the user
didn't explicitly manage the device (NM_UNMANAGED_USER_EXPLICIT). In other
words, certain flags can render other flags ineffective. Whether the device
is considered managed depends on the flags but also at the explicitly unset flags.
In a way, this is similar to previous where NM_UNMANAGED_DEFAULT was ignored
(if no other flags were present).
Also, previously a device that was NM_UNMANAGED_DEFAULT and in disconnected
state would transition back to unmanaged. No longer do that. Once a device is
managed, it stays managed as long as the flags indicate it should be managed.
However, the user can also modify the unmanaged flags via the D-Bus API.
Also get rid or nm_device_finish_init(). That was previously called
by NMManager after add_device(). As we now realize devices (possibly
multiple times) this should be handled during realization.
https://bugzilla.gnome.org/show_bug.cgi?id=746566
2015-09-15 15:35:16 +02:00
|
|
|
nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, FALSE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
|
2008-05-22 14:27:40 +00:00
|
|
|
}
|
2007-02-08 15:34:26 +00:00
|
|
|
}
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
nm_manager_update_state (self);
|
2010-05-22 08:55:30 -07:00
|
|
|
}
|
|
|
|
|
|
2010-05-29 23:11:45 -07:00
|
|
|
static void
|
|
|
|
|
_internal_sleep (NMManager *self, gboolean do_sleep)
|
2010-05-22 08:55:30 -07:00
|
|
|
{
|
2016-04-27 18:26:39 +02:00
|
|
|
NMManagerPrivate *priv;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (self));
|
|
|
|
|
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (self);
|
2010-05-22 08:55:30 -07:00
|
|
|
|
2010-08-31 15:45:55 -05:00
|
|
|
if (priv->sleeping == do_sleep)
|
|
|
|
|
return;
|
|
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_SUSPEND, "%s requested (sleeping: %s enabled: %s)",
|
|
|
|
|
do_sleep ? "sleep" : "wake",
|
|
|
|
|
priv->sleeping ? "yes" : "no",
|
|
|
|
|
priv->net_enabled ? "yes" : "no");
|
2010-05-22 08:55:30 -07:00
|
|
|
|
2010-05-28 13:06:14 -07:00
|
|
|
priv->sleeping = do_sleep;
|
2010-05-22 08:55:30 -07:00
|
|
|
|
2014-04-03 15:14:00 -04:00
|
|
|
do_sleep_wake (self, TRUE);
|
2009-10-20 15:25:04 -07:00
|
|
|
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_SLEEPING);
|
2010-05-29 23:11:45 -07:00
|
|
|
}
|
|
|
|
|
|
2010-10-15 10:28:38 -05:00
|
|
|
#if 0
|
2010-05-29 23:11:45 -07:00
|
|
|
static void
|
|
|
|
|
sleep_auth_done_cb (NMAuthChain *chain,
|
|
|
|
|
GError *error,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2010-05-29 23:11:45 -07:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
GError *ret_error;
|
|
|
|
|
NMAuthCallResult result;
|
|
|
|
|
gboolean do_sleep;
|
|
|
|
|
|
|
|
|
|
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
|
2010-06-02 02:16:14 -07:00
|
|
|
|
2012-10-08 12:52:15 -05:00
|
|
|
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SLEEP_WAKE);
|
2010-05-29 23:11:45 -07:00
|
|
|
if (error) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_SUSPEND, "Sleep/wake request failed: %s", error->message);
|
2010-05-29 23:11:45 -07:00
|
|
|
ret_error = g_error_new (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Sleep/wake request failed: %s",
|
|
|
|
|
error->message);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, ret_error);
|
2010-05-29 23:11:45 -07:00
|
|
|
} else if (result != NM_AUTH_CALL_RESULT_YES) {
|
|
|
|
|
ret_error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Not authorized to sleep/wake");
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, ret_error);
|
2010-05-29 23:11:45 -07:00
|
|
|
} else {
|
2010-06-02 02:16:14 -07:00
|
|
|
/* Auth success */
|
|
|
|
|
do_sleep = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "sleep"));
|
2010-05-29 23:11:45 -07:00
|
|
|
_internal_sleep (self, do_sleep);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_value (context, NULL);
|
2010-05-29 23:11:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_auth_chain_unref (chain);
|
|
|
|
|
}
|
2010-10-15 10:28:38 -05:00
|
|
|
#endif
|
2010-05-29 23:11:45 -07:00
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
impl_manager_sleep (NMManager *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
gboolean do_sleep)
|
2010-05-29 23:11:45 -07:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv;
|
2010-05-30 08:30:37 -07:00
|
|
|
GError *error = NULL;
|
2015-07-14 10:26:54 +02:00
|
|
|
gs_unref_object NMAuthSubject *subject = NULL;
|
2010-10-15 10:28:38 -05:00
|
|
|
#if 0
|
|
|
|
|
NMAuthChain *chain;
|
2010-05-30 08:30:37 -07:00
|
|
|
const char *error_desc = NULL;
|
2010-10-15 10:28:38 -05:00
|
|
|
#endif
|
2010-05-29 23:11:45 -07:00
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (self));
|
|
|
|
|
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (self);
|
2015-07-14 10:26:54 +02:00
|
|
|
subject = nm_auth_subject_new_unix_process_from_context (context);
|
2010-05-29 23:11:45 -07:00
|
|
|
|
|
|
|
|
if (priv->sleeping == do_sleep) {
|
|
|
|
|
error = g_error_new (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE,
|
|
|
|
|
"Already %s", do_sleep ? "asleep" : "awake");
|
2015-07-14 10:26:54 +02:00
|
|
|
nm_audit_log_control_op (NM_AUDIT_OP_SLEEP_CONTROL, do_sleep ? "on" : "off", FALSE, subject,
|
|
|
|
|
error->message);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2010-05-29 23:11:45 -07:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-15 10:28:38 -05:00
|
|
|
/* Unconditionally allow the request. Previously it was polkit protected
|
|
|
|
|
* but unfortunately that doesn't work for short-lived processes like
|
|
|
|
|
* pm-utils. It uses dbus-send without --print-reply, which quits
|
|
|
|
|
* immediately after sending the request, and NM is unable to obtain the
|
|
|
|
|
* sender's UID as dbus-send has already dropped off the bus. Thus NM
|
|
|
|
|
* fails the request. Instead, don't validate the request, but rely on
|
|
|
|
|
* D-Bus permissions to restrict the call to root.
|
|
|
|
|
*/
|
|
|
|
|
_internal_sleep (self, do_sleep);
|
2015-07-14 10:26:54 +02:00
|
|
|
nm_audit_log_control_op (NM_AUDIT_OP_SLEEP_CONTROL, do_sleep ? "on" : "off", TRUE, subject, NULL);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_value (context, NULL);
|
2010-10-15 10:28:38 -05:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
#if 0
|
2012-12-16 12:30:41 -06:00
|
|
|
chain = nm_auth_chain_new (context, sleep_auth_done_cb, self, &error_desc);
|
|
|
|
|
if (chain) {
|
|
|
|
|
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
|
|
|
|
nm_auth_chain_set_data (chain, "sleep", GUINT_TO_POINTER (do_sleep), NULL);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, TRUE);
|
|
|
|
|
} else {
|
2010-05-30 08:30:37 -07:00
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
error_desc);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2010-05-30 08:30:37 -07:00
|
|
|
}
|
2010-10-15 10:28:38 -05:00
|
|
|
#endif
|
2007-02-12 09:23:43 +00:00
|
|
|
}
|
|
|
|
|
|
2010-08-31 15:45:55 -05:00
|
|
|
static void
|
2016-04-27 18:21:28 +02:00
|
|
|
sleeping_cb (NMSleepMonitor *monitor, gboolean is_about_to_suspend, gpointer user_data)
|
2010-08-31 15:45:55 -05:00
|
|
|
{
|
2016-04-27 18:26:39 +02:00
|
|
|
NMManager *self = user_data;
|
|
|
|
|
|
2016-04-27 18:21:28 +02:00
|
|
|
_LOGD (LOGD_SUSPEND, "Received %s signal", is_about_to_suspend ? "sleeping" : "resuming");
|
|
|
|
|
_internal_sleep (self, is_about_to_suspend);
|
2010-08-31 15:45:55 -05:00
|
|
|
}
|
|
|
|
|
|
2010-05-29 23:00:46 -07:00
|
|
|
static void
|
|
|
|
|
_internal_enable (NMManager *self, gboolean enable)
|
2010-05-22 08:55:30 -07:00
|
|
|
{
|
2010-05-29 23:00:46 -07:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2010-05-22 08:55:30 -07:00
|
|
|
|
2016-04-07 18:42:24 +02:00
|
|
|
nm_config_state_set (priv->config, TRUE, FALSE,
|
|
|
|
|
NM_CONFIG_STATE_PROPERTY_NETWORKING_ENABLED, enable);
|
2010-05-22 08:55:30 -07:00
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_SUSPEND, "%s requested (sleeping: %s enabled: %s)",
|
|
|
|
|
enable ? "enable" : "disable",
|
|
|
|
|
priv->sleeping ? "yes" : "no",
|
|
|
|
|
priv->net_enabled ? "yes" : "no");
|
2010-05-22 08:55:30 -07:00
|
|
|
|
|
|
|
|
priv->net_enabled = enable;
|
|
|
|
|
|
2014-04-03 15:14:00 -04:00
|
|
|
do_sleep_wake (self, FALSE);
|
2010-05-22 08:55:30 -07:00
|
|
|
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_NETWORKING_ENABLED);
|
2010-05-29 23:00:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
enable_net_done_cb (NMAuthChain *chain,
|
|
|
|
|
GError *error,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2010-05-29 23:00:46 -07:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2012-10-08 12:52:15 -05:00
|
|
|
GError *ret_error = NULL;
|
2010-05-29 23:00:46 -07:00
|
|
|
NMAuthCallResult result;
|
|
|
|
|
gboolean enable;
|
2015-07-14 10:26:54 +02:00
|
|
|
NMAuthSubject *subject;
|
2010-05-29 23:00:46 -07:00
|
|
|
|
2013-07-29 11:53:23 -05:00
|
|
|
g_assert (context);
|
|
|
|
|
|
2010-05-29 23:00:46 -07:00
|
|
|
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
|
2015-07-14 10:26:54 +02:00
|
|
|
enable = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "enable"));
|
|
|
|
|
subject = nm_auth_chain_get_subject (chain);
|
2010-06-02 02:16:14 -07:00
|
|
|
|
2012-10-08 12:52:15 -05:00
|
|
|
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK);
|
2010-05-29 23:00:46 -07:00
|
|
|
if (error) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "Enable request failed: %s", error->message);
|
2010-05-29 23:00:46 -07:00
|
|
|
ret_error = g_error_new (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Enable request failed: %s",
|
|
|
|
|
error->message);
|
|
|
|
|
} else if (result != NM_AUTH_CALL_RESULT_YES) {
|
|
|
|
|
ret_error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Not authorized to enable/disable networking");
|
|
|
|
|
} else {
|
2010-06-02 02:16:14 -07:00
|
|
|
/* Auth success */
|
2010-05-29 23:00:46 -07:00
|
|
|
_internal_enable (self, enable);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_value (context, NULL);
|
2015-07-14 10:26:54 +02:00
|
|
|
nm_audit_log_control_op (NM_AUDIT_OP_NET_CONTROL, enable ? "on" : "off", TRUE,
|
|
|
|
|
subject, NULL);
|
2010-05-29 23:00:46 -07:00
|
|
|
}
|
|
|
|
|
|
2012-10-08 12:52:15 -05:00
|
|
|
if (ret_error) {
|
2015-07-14 10:26:54 +02:00
|
|
|
nm_audit_log_control_op (NM_AUDIT_OP_NET_CONTROL, enable ? "on" : "off", FALSE,
|
|
|
|
|
subject, ret_error->message);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, ret_error);
|
2012-10-08 12:52:15 -05:00
|
|
|
}
|
|
|
|
|
|
2010-05-29 23:00:46 -07:00
|
|
|
nm_auth_chain_unref (chain);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
impl_manager_enable (NMManager *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
gboolean enable)
|
2010-05-29 23:00:46 -07:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv;
|
|
|
|
|
NMAuthChain *chain;
|
2010-05-30 08:30:37 -07:00
|
|
|
GError *error = NULL;
|
2010-05-29 23:00:46 -07:00
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (self));
|
|
|
|
|
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->net_enabled == enable) {
|
|
|
|
|
error = g_error_new (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED,
|
|
|
|
|
"Already %s", enable ? "enabled" : "disabled");
|
2013-07-29 11:53:23 -05:00
|
|
|
goto done;
|
2010-05-29 23:00:46 -07:00
|
|
|
}
|
|
|
|
|
|
2013-07-29 11:53:23 -05:00
|
|
|
chain = nm_auth_chain_new_context (context, enable_net_done_cb, self);
|
|
|
|
|
if (!chain) {
|
2010-05-30 08:30:37 -07:00
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
2013-07-29 11:53:23 -05:00
|
|
|
"Unable to authenticate request.");
|
|
|
|
|
goto done;
|
2010-05-30 08:30:37 -07:00
|
|
|
}
|
2013-07-29 11:53:23 -05:00
|
|
|
|
|
|
|
|
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
|
|
|
|
nm_auth_chain_set_data (chain, "enable", GUINT_TO_POINTER (enable), NULL);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, TRUE);
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
if (error)
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2010-05-22 08:55:30 -07:00
|
|
|
}
|
|
|
|
|
|
2010-05-28 18:23:00 -07:00
|
|
|
/* Permissions */
|
|
|
|
|
|
2010-06-02 02:16:14 -07:00
|
|
|
static void
|
2016-04-27 18:26:39 +02:00
|
|
|
get_perm_add_result (NMManager *self, NMAuthChain *chain, GVariantBuilder *results, const char *permission)
|
2010-06-02 02:16:14 -07:00
|
|
|
{
|
|
|
|
|
NMAuthCallResult result;
|
|
|
|
|
|
2012-10-08 12:52:15 -05:00
|
|
|
result = nm_auth_chain_get_result (chain, permission);
|
2010-06-02 02:16:14 -07:00
|
|
|
if (result == NM_AUTH_CALL_RESULT_YES)
|
2015-04-15 14:53:30 -04:00
|
|
|
g_variant_builder_add (results, "{ss}", permission, "yes");
|
2010-06-02 02:16:14 -07:00
|
|
|
else if (result == NM_AUTH_CALL_RESULT_NO)
|
2015-04-15 14:53:30 -04:00
|
|
|
g_variant_builder_add (results, "{ss}", permission, "no");
|
2010-06-02 02:16:14 -07:00
|
|
|
else if (result == NM_AUTH_CALL_RESULT_AUTH)
|
2015-04-15 14:53:30 -04:00
|
|
|
g_variant_builder_add (results, "{ss}", permission, "auth");
|
2010-06-02 02:16:14 -07:00
|
|
|
else {
|
2016-04-27 18:26:39 +02:00
|
|
|
_LOGD (LOGD_CORE, "unknown auth chain result %d", result);
|
2010-06-02 02:16:14 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-28 18:23:00 -07:00
|
|
|
static void
|
|
|
|
|
get_permissions_done_cb (NMAuthChain *chain,
|
|
|
|
|
GError *error,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2010-05-29 23:00:46 -07:00
|
|
|
gpointer user_data)
|
2010-05-28 18:23:00 -07:00
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
GError *ret_error;
|
2015-04-15 14:53:30 -04:00
|
|
|
GVariantBuilder results;
|
2010-05-28 18:23:00 -07:00
|
|
|
|
2013-07-29 11:53:23 -05:00
|
|
|
g_assert (context);
|
|
|
|
|
|
2010-05-28 18:23:00 -07:00
|
|
|
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
|
|
|
|
|
if (error) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "Permissions request failed: %s", error->message);
|
2010-05-28 18:23:00 -07:00
|
|
|
ret_error = g_error_new (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Permissions request failed: %s",
|
|
|
|
|
error->message);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, ret_error);
|
2010-05-28 18:23:00 -07:00
|
|
|
} else {
|
2015-04-15 14:53:30 -04:00
|
|
|
g_variant_builder_init (&results, G_VARIANT_TYPE ("a{ss}"));
|
2012-10-08 12:52:15 -05:00
|
|
|
|
2016-04-27 18:26:39 +02:00
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK);
|
|
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_SLEEP_WAKE);
|
|
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI);
|
|
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN);
|
|
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX);
|
|
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_NETWORK_CONTROL);
|
|
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED);
|
|
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN);
|
|
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM);
|
|
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN);
|
|
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME);
|
2016-06-01 22:04:00 +02:00
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS);
|
2016-05-30 15:42:44 +02:00
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_RELOAD);
|
2016-08-17 15:34:55 +02:00
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK);
|
2016-08-10 11:54:32 +02:00
|
|
|
get_perm_add_result (self, chain, &results, NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS);
|
2012-10-08 12:52:15 -05:00
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_value (context,
|
|
|
|
|
g_variant_new ("(a{ss})", &results));
|
2010-05-28 18:23:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_auth_chain_unref (chain);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
impl_manager_get_permissions (NMManager *self,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context)
|
2010-05-28 18:23:00 -07:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
NMAuthChain *chain;
|
2013-07-29 11:53:23 -05:00
|
|
|
GError *error = NULL;
|
2010-05-28 18:23:00 -07:00
|
|
|
|
2013-07-29 11:53:23 -05:00
|
|
|
chain = nm_auth_chain_new_context (context, get_permissions_done_cb, self);
|
|
|
|
|
if (!chain) {
|
2012-12-16 12:30:41 -06:00
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
2013-07-29 11:53:23 -05:00
|
|
|
"Unable to authenticate request.");
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2013-07-29 11:53:23 -05:00
|
|
|
return;
|
2012-10-08 12:52:15 -05:00
|
|
|
}
|
2013-07-29 11:53:23 -05:00
|
|
|
|
|
|
|
|
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, FALSE);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, FALSE);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, FALSE);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, FALSE);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX, FALSE);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, FALSE);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, FALSE);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, FALSE);
|
2016-06-01 22:04:00 +02:00
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS, FALSE);
|
2016-05-30 15:42:44 +02:00
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_RELOAD, FALSE);
|
2016-08-17 15:34:55 +02:00
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, FALSE);
|
2016-08-10 11:54:32 +02:00
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS, FALSE);
|
2010-05-28 18:23:00 -07:00
|
|
|
}
|
|
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
static void
|
|
|
|
|
impl_manager_get_state (NMManager *self,
|
|
|
|
|
GDBusMethodInvocation *context)
|
2011-03-08 12:57:35 -06:00
|
|
|
{
|
2015-04-15 14:53:30 -04:00
|
|
|
nm_manager_update_state (self);
|
|
|
|
|
g_dbus_method_invocation_return_value (context,
|
|
|
|
|
g_variant_new ("(u)", NM_MANAGER_GET_PRIVATE (self)->state));
|
2011-03-08 12:57:35 -06:00
|
|
|
}
|
|
|
|
|
|
2014-01-22 13:07:24 -06:00
|
|
|
static void
|
2015-04-15 14:53:30 -04:00
|
|
|
impl_manager_set_logging (NMManager *self,
|
|
|
|
|
GDBusMethodInvocation *context,
|
2010-04-08 08:56:17 -07:00
|
|
|
const char *level,
|
2015-04-15 14:53:30 -04:00
|
|
|
const char *domains)
|
2010-04-08 08:56:17 -07:00
|
|
|
{
|
2014-01-22 13:07:24 -06:00
|
|
|
GError *error = NULL;
|
|
|
|
|
|
2016-08-23 09:38:40 +02:00
|
|
|
/* The permission is already enforced by the D-Bus daemon, but we ensure
|
|
|
|
|
* that the caller is still alive so that clients are forced to wait and
|
|
|
|
|
* we'll be able to switch to polkit without breaking behavior.
|
|
|
|
|
*/
|
|
|
|
|
if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (),
|
|
|
|
|
context,
|
|
|
|
|
G_MAXULONG,
|
|
|
|
|
NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED))
|
|
|
|
|
return;
|
|
|
|
|
|
2014-01-22 13:07:24 -06:00
|
|
|
if (nm_logging_setup (level, domains, NULL, &error)) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_CORE, "logging: level '%s' domains '%s'",
|
|
|
|
|
nm_logging_level_to_string (), nm_logging_domains_to_string ());
|
2010-04-08 08:56:17 -07:00
|
|
|
}
|
2014-01-22 13:07:24 -06:00
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
if (error)
|
|
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
|
|
|
|
else
|
|
|
|
|
g_dbus_method_invocation_return_value (context, NULL);
|
2010-04-08 08:56:17 -07:00
|
|
|
}
|
2007-08-15 07:52:25 +00:00
|
|
|
|
2012-12-12 14:21:40 +01:00
|
|
|
static void
|
|
|
|
|
impl_manager_get_logging (NMManager *manager,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context)
|
2012-12-12 14:21:40 +01:00
|
|
|
{
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_return_value (context,
|
|
|
|
|
g_variant_new ("(ss)",
|
|
|
|
|
nm_logging_level_to_string (),
|
|
|
|
|
nm_logging_domains_to_string ()));
|
2012-12-12 14:21:40 +01:00
|
|
|
}
|
|
|
|
|
|
2013-07-30 16:31:31 -04:00
|
|
|
static void
|
|
|
|
|
connectivity_check_done (GObject *object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context = user_data;
|
2013-07-30 16:31:31 -04:00
|
|
|
NMConnectivityState state;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
state = nm_connectivity_check_finish (NM_CONNECTIVITY (object), result, &error);
|
2015-04-15 14:53:30 -04:00
|
|
|
if (error)
|
|
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
|
|
|
|
else {
|
|
|
|
|
g_dbus_method_invocation_return_value (context,
|
|
|
|
|
g_variant_new ("(u)", state));
|
|
|
|
|
}
|
2013-07-30 16:31:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
check_connectivity_auth_done_cb (NMAuthChain *chain,
|
|
|
|
|
GError *auth_error,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context,
|
2013-07-30 16:31:31 -04:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
NMAuthCallResult result;
|
|
|
|
|
|
|
|
|
|
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
|
|
|
|
|
|
|
|
|
|
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
|
|
|
|
|
|
|
|
|
|
if (auth_error) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "CheckConnectivity request failed: %s", auth_error->message);
|
2013-07-30 16:31:31 -04:00
|
|
|
error = g_error_new (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Connectivity check request failed: %s",
|
|
|
|
|
auth_error->message);
|
|
|
|
|
} else if (result != NM_AUTH_CALL_RESULT_YES) {
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Not authorized to recheck connectivity");
|
|
|
|
|
} else {
|
|
|
|
|
/* it's allowed */
|
|
|
|
|
nm_connectivity_check_async (priv->connectivity,
|
|
|
|
|
connectivity_check_done,
|
|
|
|
|
context);
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
if (error)
|
|
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2013-07-30 16:31:31 -04:00
|
|
|
nm_auth_chain_unref (chain);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2015-04-15 14:53:30 -04:00
|
|
|
impl_manager_check_connectivity (NMManager *self,
|
|
|
|
|
GDBusMethodInvocation *context)
|
2013-07-30 16:31:31 -04:00
|
|
|
{
|
2015-04-15 14:53:30 -04:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2013-07-30 16:31:31 -04:00
|
|
|
NMAuthChain *chain;
|
2013-07-29 11:53:23 -05:00
|
|
|
GError *error = NULL;
|
2013-07-30 16:31:31 -04:00
|
|
|
|
2013-07-29 11:53:23 -05:00
|
|
|
/* Validate the request */
|
2015-04-15 14:53:30 -04:00
|
|
|
chain = nm_auth_chain_new_context (context, check_connectivity_auth_done_cb, self);
|
2013-07-29 11:53:23 -05:00
|
|
|
if (!chain) {
|
2013-07-30 16:31:31 -04:00
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
2013-07-29 11:53:23 -05:00
|
|
|
"Unable to authenticate request.");
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
2013-07-29 11:53:23 -05:00
|
|
|
return;
|
2013-07-30 16:31:31 -04:00
|
|
|
}
|
2013-07-29 11:53:23 -05:00
|
|
|
|
|
|
|
|
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
|
2013-07-30 16:31:31 -04:00
|
|
|
}
|
|
|
|
|
|
2014-09-17 14:17:30 -05:00
|
|
|
static void
|
|
|
|
|
start_factory (NMDeviceFactory *factory, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
nm_device_factory_start (factory);
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-03 09:26:31 -04:00
|
|
|
gboolean
|
|
|
|
|
nm_manager_start (NMManager *self, GError **error)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2014-09-24 16:58:07 -05:00
|
|
|
GSList *iter, *connections;
|
2009-12-23 00:03:45 -08:00
|
|
|
guint i;
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2015-08-03 09:26:31 -04:00
|
|
|
if (!nm_settings_start (priv->settings, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2016-01-04 09:59:16 +01:00
|
|
|
g_signal_connect (NM_PLATFORM_GET,
|
core: better order the code at startup
NM was calling nm_bus_manager_start_service() to claim its bus name
before it exported any of its objects, but this didn't matter under
dbus-glib, because no client connections would be accepted until the
main loop was started later on, by which point we would have exported
everything.
But with gdbus, method calls are initially received in the gdbus
worker thread, which means that clients would be able to connect right
away and then be told that the expected interfaces don't exist.
So move the nm_bus_manager_start_service() call to occur after
creating NMSettings and NMManager (and, indirectly, NMAgentManager).
This requires splitting out the slow parts of nm_settings_new() into a
new nm_settings_start(), so that we can create and export it first,
and then read the connections, etc afterward. (Likewise, there were
still a few potentially-slow bits in nm_manager_new() which are now
moved into nm_manager_start().)
2015-07-31 13:00:22 -04:00
|
|
|
NM_PLATFORM_SIGNAL_LINK_CHANGED,
|
|
|
|
|
G_CALLBACK (platform_link_cb),
|
|
|
|
|
self);
|
|
|
|
|
|
2009-12-23 00:03:45 -08:00
|
|
|
/* Set initial radio enabled/disabled state */
|
|
|
|
|
for (i = 0; i < RFKILL_TYPE_MAX; i++) {
|
|
|
|
|
RadioState *rstate = &priv->radio_states[i];
|
2011-04-13 21:58:25 -05:00
|
|
|
gboolean enabled;
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2009-12-23 00:03:45 -08:00
|
|
|
if (!rstate->desc)
|
|
|
|
|
continue;
|
|
|
|
|
|
2014-04-15 16:25:39 -05:00
|
|
|
/* recheck kernel rfkill state */
|
|
|
|
|
update_rstate_from_rfkill (priv->rfkill_mgr, rstate);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2010-09-01 17:08:10 -05:00
|
|
|
if (rstate->desc) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_RFKILL, "%s %s by radio killswitch; %s by state file",
|
|
|
|
|
rstate->desc,
|
|
|
|
|
(rstate->hw_enabled && rstate->sw_enabled) ? "enabled" : "disabled",
|
|
|
|
|
rstate->user_enabled ? "enabled" : "disabled");
|
2010-09-01 17:08:10 -05:00
|
|
|
}
|
2011-04-13 21:58:25 -05:00
|
|
|
enabled = radio_enabled_for_rstate (rstate, TRUE);
|
|
|
|
|
manager_update_radio_enabled (self, rstate, enabled);
|
2009-12-23 00:03:45 -08:00
|
|
|
}
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2010-05-22 08:55:30 -07:00
|
|
|
/* Log overall networking status - enabled/disabled */
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_CORE, "Networking is %s by state file",
|
|
|
|
|
priv->net_enabled ? "enabled" : "disabled");
|
2010-04-08 18:23:43 -07:00
|
|
|
|
2010-10-27 15:47:10 -05:00
|
|
|
system_unmanaged_devices_changed_cb (priv->settings, NULL, self);
|
|
|
|
|
system_hostname_changed_cb (priv->settings, NULL, self);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-09-05 14:48:21 -05:00
|
|
|
/* Start device factories */
|
core: better order the code at startup
NM was calling nm_bus_manager_start_service() to claim its bus name
before it exported any of its objects, but this didn't matter under
dbus-glib, because no client connections would be accepted until the
main loop was started later on, by which point we would have exported
everything.
But with gdbus, method calls are initially received in the gdbus
worker thread, which means that clients would be able to connect right
away and then be told that the expected interfaces don't exist.
So move the nm_bus_manager_start_service() call to occur after
creating NMSettings and NMManager (and, indirectly, NMAgentManager).
This requires splitting out the slow parts of nm_settings_new() into a
new nm_settings_start(), so that we can create and export it first,
and then read the connections, etc afterward. (Likewise, there were
still a few potentially-slow bits in nm_manager_new() which are now
moved into nm_manager_start().)
2015-07-31 13:00:22 -04:00
|
|
|
nm_device_factory_manager_load_factories (_register_device_factory, self);
|
2014-09-17 14:17:30 -05:00
|
|
|
nm_device_factory_manager_for_each_factory (start_factory, NULL);
|
2014-09-05 14:48:21 -05:00
|
|
|
|
2015-05-04 16:54:51 +02:00
|
|
|
platform_query_devices (self);
|
2011-10-18 13:48:44 +02:00
|
|
|
|
core: better order the code at startup
NM was calling nm_bus_manager_start_service() to claim its bus name
before it exported any of its objects, but this didn't matter under
dbus-glib, because no client connections would be accepted until the
main loop was started later on, by which point we would have exported
everything.
But with gdbus, method calls are initially received in the gdbus
worker thread, which means that clients would be able to connect right
away and then be told that the expected interfaces don't exist.
So move the nm_bus_manager_start_service() call to occur after
creating NMSettings and NMManager (and, indirectly, NMAgentManager).
This requires splitting out the slow parts of nm_settings_new() into a
new nm_settings_start(), so that we can create and export it first,
and then read the connections, etc afterward. (Likewise, there were
still a few potentially-slow bits in nm_manager_new() which are now
moved into nm_manager_start().)
2015-07-31 13:00:22 -04:00
|
|
|
/* Load VPN plugins */
|
|
|
|
|
priv->vpn_manager = g_object_ref (nm_vpn_manager_get ());
|
|
|
|
|
|
2014-09-24 16:58:07 -05:00
|
|
|
/* Connections added before the manager is started do not emit
|
2011-10-18 13:48:44 +02:00
|
|
|
* connection-added signals thus devices have to be created manually.
|
|
|
|
|
*/
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "creating virtual devices...");
|
2016-05-16 19:24:23 +02:00
|
|
|
connections = nm_settings_get_connections_sorted (priv->settings);
|
2014-09-24 16:58:07 -05:00
|
|
|
for (iter = connections; iter; iter = iter->next)
|
2016-04-13 16:03:06 +02:00
|
|
|
connection_changed (self, NM_CONNECTION (iter->data));
|
2014-09-24 16:58:07 -05:00
|
|
|
g_slist_free (connections);
|
core: only manage those bridges created by NetworkManager (rh #905035)
Until we handle bridges non-destructively, only manage bridges
created by NM. When quitting write out a file listing all
bridges created by NM and a timestamp, and when starting read
that file and if the timestamp is within 30 minutes, manage
any bridge that was listed in that file. This scheme, while
not foolproof (eg, if NM crashes), should ensure that NM can
recognize bridges it created if it's restarted. The file
is stored in /run or /var/run, which is cleaned each restart,
ensuring that the state does not persist across reboots.
If an automatic or user-initiated activation request for
a bridge NM does not manage is received, that request is
denied. Only if the bridge interface does not yet exist, or
was present in the managed bridges file, will an
NMDeviceBridge be created and activation be possible.
2013-02-01 18:03:11 -06:00
|
|
|
|
2015-08-25 13:32:53 +02:00
|
|
|
priv->devices_inited = TRUE;
|
|
|
|
|
|
2013-08-13 17:45:34 -04:00
|
|
|
check_if_startup_complete (self);
|
2015-08-03 09:26:31 -04:00
|
|
|
|
|
|
|
|
return TRUE;
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
|
2014-10-29 09:12:18 -05:00
|
|
|
void
|
|
|
|
|
nm_manager_stop (NMManager *self)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
/* Remove all devices */
|
|
|
|
|
while (priv->devices)
|
|
|
|
|
remove_device (self, NM_DEVICE (priv->devices->data), TRUE, TRUE);
|
2016-01-22 15:19:06 +01:00
|
|
|
|
|
|
|
|
_active_connection_cleanup (self);
|
2014-10-29 09:12:18 -05:00
|
|
|
}
|
|
|
|
|
|
2010-07-01 10:32:11 -07:00
|
|
|
static gboolean
|
|
|
|
|
handle_firmware_changed (gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
|
|
priv->fw_changed_id = 0;
|
|
|
|
|
|
|
|
|
|
/* Try to re-enable devices with missing firmware */
|
|
|
|
|
for (iter = priv->devices; iter; iter = iter->next) {
|
|
|
|
|
NMDevice *candidate = NM_DEVICE (iter->data);
|
|
|
|
|
NMDeviceState state = nm_device_get_state (candidate);
|
|
|
|
|
|
|
|
|
|
if ( nm_device_get_firmware_missing (candidate)
|
|
|
|
|
&& (state == NM_DEVICE_STATE_UNAVAILABLE)) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_CORE, "(%s): firmware may now be available",
|
|
|
|
|
nm_device_get_iface (candidate));
|
2010-07-01 10:32:11 -07:00
|
|
|
|
|
|
|
|
/* Re-set unavailable state to try bringing the device up again */
|
|
|
|
|
nm_device_state_changed (candidate,
|
|
|
|
|
NM_DEVICE_STATE_UNAVAILABLE,
|
|
|
|
|
NM_DEVICE_STATE_REASON_NONE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-21 21:21:30 +02:00
|
|
|
static void
|
2011-12-13 17:35:36 -06:00
|
|
|
connectivity_changed (NMConnectivity *connectivity,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
gpointer user_data)
|
2011-10-21 21:21:30 +02:00
|
|
|
{
|
2011-12-13 17:35:36 -06:00
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
2011-10-21 21:21:30 +02:00
|
|
|
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "connectivity checking indicates %s",
|
|
|
|
|
nm_connectivity_state_to_string (nm_connectivity_get_state (connectivity)));
|
2011-10-21 21:21:30 +02:00
|
|
|
|
2011-12-13 17:35:36 -06:00
|
|
|
nm_manager_update_state (self);
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_CONNECTIVITY);
|
2011-10-21 21:21:30 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-01 10:32:11 -07:00
|
|
|
static void
|
|
|
|
|
firmware_dir_changed (GFileMonitor *monitor,
|
|
|
|
|
GFile *file,
|
|
|
|
|
GFile *other_file,
|
|
|
|
|
GFileMonitorEvent event_type,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
switch (event_type) {
|
|
|
|
|
case G_FILE_MONITOR_EVENT_CREATED:
|
|
|
|
|
case G_FILE_MONITOR_EVENT_CHANGED:
|
|
|
|
|
case G_FILE_MONITOR_EVENT_MOVED:
|
|
|
|
|
case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
|
|
|
|
|
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
|
|
|
|
|
if (!priv->fw_changed_id) {
|
|
|
|
|
priv->fw_changed_id = g_timeout_add_seconds (4, handle_firmware_changed, self);
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGI (LOGD_CORE, "kernel firmware directory '%s' changed",
|
|
|
|
|
KERNEL_FIRMWARE_DIR);
|
2010-07-01 10:32:11 -07:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-03 09:15:24 +02:00
|
|
|
static void
|
|
|
|
|
connection_metered_changed (GObject *object,
|
|
|
|
|
NMMetered metered,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
nm_manager_update_metered (NM_MANAGER (user_data));
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-22 13:06:51 -04:00
|
|
|
static void
|
|
|
|
|
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.
|
|
|
|
|
*/
|
|
|
|
|
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) {
|
2015-06-03 09:15:24 +02:00
|
|
|
if (priv->primary_connection) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->primary_connection,
|
|
|
|
|
G_CALLBACK (connection_metered_changed),
|
|
|
|
|
self);
|
|
|
|
|
g_clear_object (&priv->primary_connection);
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-22 13:06:51 -04:00
|
|
|
priv->primary_connection = ac ? g_object_ref (ac) : NULL;
|
2015-06-03 09:15:24 +02:00
|
|
|
|
|
|
|
|
if (priv->primary_connection) {
|
|
|
|
|
g_signal_connect (priv->primary_connection, NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED,
|
|
|
|
|
G_CALLBACK (connection_metered_changed), self);
|
|
|
|
|
}
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_PRIMARY_CONNECTION);
|
|
|
|
|
_notify (self, PROP_PRIMARY_CONNECTION_TYPE);
|
2015-06-03 09:15:24 +02:00
|
|
|
nm_manager_update_metered (self);
|
2013-08-22 13:06:51 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
NMDevice *activating, *best;
|
|
|
|
|
NMActiveConnection *ac;
|
|
|
|
|
|
|
|
|
|
/* 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_device (priv->policy);
|
|
|
|
|
best = nm_policy_get_default_ip4_device (priv->policy);
|
|
|
|
|
if (!activating && !best)
|
|
|
|
|
activating = nm_policy_get_activating_ip6_device (priv->policy);
|
|
|
|
|
|
|
|
|
|
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;
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "ActivatingConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
|
2016-04-01 17:34:51 +02:00
|
|
|
_notify (self, PROP_ACTIVATING_CONNECTION);
|
2013-08-22 13:06:51 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-17 17:01:10 +02:00
|
|
|
#define NM_PERM_DENIED_ERROR "org.freedesktop.NetworkManager.PermissionDenied"
|
2015-04-15 14:53:30 -04:00
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
NMManager *self;
|
|
|
|
|
GDBusConnection *connection;
|
|
|
|
|
GDBusMessage *message;
|
|
|
|
|
NMAuthSubject *subject;
|
|
|
|
|
const char *permission;
|
|
|
|
|
const char *audit_op;
|
2015-08-20 13:42:00 +02:00
|
|
|
char *audit_prop_value;
|
2015-09-15 11:34:00 +02:00
|
|
|
GType interface_type;
|
|
|
|
|
const char *glib_propname;
|
2015-04-15 14:53:30 -04:00
|
|
|
} PropertyFilterData;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_property_filter_data (PropertyFilterData *pfd)
|
|
|
|
|
{
|
|
|
|
|
g_object_unref (pfd->self);
|
|
|
|
|
g_object_unref (pfd->connection);
|
|
|
|
|
g_object_unref (pfd->message);
|
2015-09-14 18:32:27 +02:00
|
|
|
g_clear_object (&pfd->subject);
|
2015-08-20 13:42:00 +02:00
|
|
|
g_free (pfd->audit_prop_value);
|
2015-08-20 13:32:34 +02:00
|
|
|
g_slice_free (PropertyFilterData, pfd);
|
2015-04-15 14:53:30 -04:00
|
|
|
}
|
2010-08-25 15:12:32 -05:00
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
prop_set_auth_done_cb (NMAuthChain *chain,
|
|
|
|
|
GError *error,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusMethodInvocation *context, /* NULL */
|
2010-08-25 15:12:32 -05:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2015-04-15 14:53:30 -04:00
|
|
|
PropertyFilterData *pfd = user_data;
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pfd->self);
|
2010-08-25 15:12:32 -05:00
|
|
|
NMAuthCallResult result;
|
2015-07-03 11:06:39 +02:00
|
|
|
GDBusMessage *reply = NULL;
|
2015-09-15 11:34:00 +02:00
|
|
|
const char *error_message;
|
2015-07-20 17:30:02 -05:00
|
|
|
gs_unref_object NMExportedObject *object = NULL;
|
2015-07-03 11:06:39 +02:00
|
|
|
const NMGlobalDnsConfig *global_dns;
|
|
|
|
|
gs_unref_variant GVariant *value = NULL;
|
|
|
|
|
GVariant *args;
|
2010-08-25 15:12:32 -05:00
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
|
|
|
|
|
result = nm_auth_chain_get_result (chain, pfd->permission);
|
2012-10-08 12:52:15 -05:00
|
|
|
if (error || (result != NM_AUTH_CALL_RESULT_YES)) {
|
2015-04-15 14:53:30 -04:00
|
|
|
reply = g_dbus_message_new_method_error (pfd->message,
|
|
|
|
|
NM_PERM_DENIED_ERROR,
|
2015-09-15 11:34:00 +02:00
|
|
|
(error_message = "Not authorized to perform this operation"));
|
|
|
|
|
if (error)
|
|
|
|
|
error_message = error->message;
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-20 17:30:02 -05:00
|
|
|
object = NM_EXPORTED_OBJECT (nm_bus_manager_get_registered_object (priv->dbus_mgr,
|
|
|
|
|
g_dbus_message_get_path (pfd->message)));
|
2015-09-15 11:34:00 +02:00
|
|
|
if (!object) {
|
|
|
|
|
reply = g_dbus_message_new_method_error (pfd->message,
|
|
|
|
|
"org.freedesktop.DBus.Error.UnknownObject",
|
|
|
|
|
(error_message = "Object doesn't exist."));
|
|
|
|
|
goto done;
|
2010-08-25 15:12:32 -05:00
|
|
|
}
|
|
|
|
|
|
2015-09-15 11:34:00 +02:00
|
|
|
/* do some extra type checking... */
|
|
|
|
|
if (!nm_exported_object_get_interface_by_type (object, pfd->interface_type)) {
|
|
|
|
|
reply = g_dbus_message_new_method_error (pfd->message,
|
|
|
|
|
"org.freedesktop.DBus.Error.InvalidArgs",
|
|
|
|
|
(error_message = "Object is of unexpected type."));
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-03 11:06:39 +02:00
|
|
|
args = g_dbus_message_get_body (pfd->message);
|
|
|
|
|
g_variant_get (args, "(&s&sv)", NULL, NULL, &value);
|
|
|
|
|
g_assert (pfd->glib_propname);
|
|
|
|
|
|
|
|
|
|
if (!strcmp (pfd->glib_propname, NM_MANAGER_GLOBAL_DNS_CONFIGURATION)) {
|
|
|
|
|
g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a{sv}")));
|
|
|
|
|
global_dns = nm_config_data_get_global_dns_config (nm_config_get_data (priv->config));
|
|
|
|
|
|
|
|
|
|
if (global_dns && !nm_global_dns_config_is_internal (global_dns)) {
|
|
|
|
|
reply = g_dbus_message_new_method_error (pfd->message,
|
|
|
|
|
NM_PERM_DENIED_ERROR,
|
|
|
|
|
(error_message = "Global DNS configuration already set via configuration file"));
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
/* ... but set the property on the @object itself. It would be correct to set the property
|
|
|
|
|
* on the skeleton interface, but as it is now, the result is the same. */
|
|
|
|
|
g_object_set (object, pfd->glib_propname, value, NULL);
|
2016-08-10 11:54:32 +02:00
|
|
|
} else if (!strcmp (pfd->glib_propname, NM_DEVICE_STATISTICS_REFRESH_RATE_MS)) {
|
|
|
|
|
g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32));
|
|
|
|
|
/* the same here */
|
2016-08-16 11:07:36 +02:00
|
|
|
g_object_set (object, pfd->glib_propname, (guint) g_variant_get_uint32 (value), NULL);
|
2015-07-03 11:06:39 +02:00
|
|
|
} else {
|
|
|
|
|
g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN));
|
|
|
|
|
/* the same here */
|
|
|
|
|
g_object_set (object, pfd->glib_propname, g_variant_get_boolean (value), NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-15 11:34:00 +02:00
|
|
|
reply = g_dbus_message_new_method_reply (pfd->message);
|
|
|
|
|
g_dbus_message_set_body (reply, g_variant_new_tuple (NULL, 0));
|
|
|
|
|
error_message = NULL;
|
|
|
|
|
done:
|
|
|
|
|
nm_audit_log_control_op (pfd->audit_op, pfd->audit_prop_value, !error_message, pfd->subject, error_message);
|
|
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_connection_send_message (pfd->connection, reply,
|
|
|
|
|
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
|
|
|
|
NULL, NULL);
|
|
|
|
|
g_object_unref (reply);
|
2010-08-25 15:12:32 -05:00
|
|
|
nm_auth_chain_unref (chain);
|
2015-04-15 14:53:30 -04:00
|
|
|
|
|
|
|
|
free_property_filter_data (pfd);
|
2010-08-25 15:12:32 -05:00
|
|
|
}
|
|
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
static gboolean
|
|
|
|
|
do_set_property_check (gpointer user_data)
|
2010-08-25 15:12:32 -05:00
|
|
|
{
|
2015-04-15 14:53:30 -04:00
|
|
|
PropertyFilterData *pfd = user_data;
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pfd->self);
|
|
|
|
|
GDBusMessage *reply = NULL;
|
2010-08-25 15:12:32 -05:00
|
|
|
NMAuthChain *chain;
|
2015-08-20 13:42:00 +02:00
|
|
|
const char *error_message = NULL;
|
2010-08-25 15:12:32 -05:00
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
pfd->subject = nm_auth_subject_new_unix_process_from_message (pfd->connection, pfd->message);
|
|
|
|
|
if (!pfd->subject) {
|
|
|
|
|
reply = g_dbus_message_new_method_error (pfd->message,
|
|
|
|
|
NM_PERM_DENIED_ERROR,
|
2015-08-20 13:42:00 +02:00
|
|
|
(error_message = "Could not determine request UID."));
|
2010-08-25 15:12:32 -05:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-16 12:30:41 -06:00
|
|
|
/* Validate the user request */
|
2015-04-15 14:53:30 -04:00
|
|
|
chain = nm_auth_chain_new_subject (pfd->subject, NULL, prop_set_auth_done_cb, pfd);
|
2013-07-29 11:53:23 -05:00
|
|
|
if (!chain) {
|
2015-04-15 14:53:30 -04:00
|
|
|
reply = g_dbus_message_new_method_error (pfd->message,
|
|
|
|
|
NM_PERM_DENIED_ERROR,
|
2015-08-20 13:42:00 +02:00
|
|
|
(error_message = "Could not authenticate request."));
|
2013-07-29 11:53:23 -05:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-08 12:52:15 -05:00
|
|
|
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
2015-04-15 14:53:30 -04:00
|
|
|
nm_auth_chain_add_call (chain, pfd->permission, TRUE);
|
2010-08-25 15:12:32 -05:00
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
if (reply) {
|
2015-08-20 13:42:00 +02:00
|
|
|
nm_audit_log_control_op (pfd->audit_op, pfd->audit_prop_value, FALSE, pfd->subject, error_message);
|
2015-04-15 14:53:30 -04:00
|
|
|
g_dbus_connection_send_message (pfd->connection, reply,
|
|
|
|
|
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
|
|
|
|
NULL, NULL);
|
|
|
|
|
g_object_unref (reply);
|
|
|
|
|
free_property_filter_data (pfd);
|
2010-08-25 15:12:32 -05:00
|
|
|
}
|
2013-07-29 11:53:23 -05:00
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GDBusMessage *
|
|
|
|
|
prop_filter (GDBusConnection *connection,
|
|
|
|
|
GDBusMessage *message,
|
|
|
|
|
gboolean incoming,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2015-08-20 14:25:46 +02:00
|
|
|
gs_unref_object NMManager *self = NULL;
|
2015-07-03 11:06:39 +02:00
|
|
|
GVariant *args;
|
2015-04-15 14:53:30 -04:00
|
|
|
const char *propiface = NULL;
|
|
|
|
|
const char *propname = NULL;
|
|
|
|
|
const char *glib_propname = NULL, *permission = NULL;
|
|
|
|
|
const char *audit_op = NULL;
|
2015-09-15 11:34:00 +02:00
|
|
|
GType interface_type = G_TYPE_INVALID;
|
2015-04-15 14:53:30 -04:00
|
|
|
PropertyFilterData *pfd;
|
2015-07-03 11:06:39 +02:00
|
|
|
const GVariantType *expected_type = G_VARIANT_TYPE_BOOLEAN;
|
|
|
|
|
gs_unref_variant GVariant *value = NULL;
|
2015-04-15 14:53:30 -04:00
|
|
|
|
2015-08-20 14:25:46 +02:00
|
|
|
self = g_weak_ref_get (user_data);
|
|
|
|
|
if (!self)
|
|
|
|
|
return message;
|
|
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
/* The sole purpose of this function is to validate property accesses on the
|
|
|
|
|
* NMManager object since gdbus doesn't give us this functionality.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* Only filter org.freedesktop.DBus.Properties.Set calls */
|
|
|
|
|
if ( !incoming
|
|
|
|
|
|| g_dbus_message_get_message_type (message) != G_DBUS_MESSAGE_TYPE_METHOD_CALL
|
2015-09-21 13:16:33 +02:00
|
|
|
|| g_strcmp0 (g_dbus_message_get_interface (message), DBUS_INTERFACE_PROPERTIES) != 0
|
|
|
|
|
|| g_strcmp0 (g_dbus_message_get_member (message), "Set") != 0)
|
2015-04-15 14:53:30 -04:00
|
|
|
return message;
|
|
|
|
|
|
|
|
|
|
args = g_dbus_message_get_body (message);
|
|
|
|
|
if (!g_variant_is_of_type (args, G_VARIANT_TYPE ("(ssv)")))
|
|
|
|
|
return message;
|
|
|
|
|
g_variant_get (args, "(&s&sv)", &propiface, &propname, &value);
|
|
|
|
|
|
|
|
|
|
/* Only filter calls to filtered properties, on existing objects */
|
|
|
|
|
if (!strcmp (propiface, NM_DBUS_INTERFACE)) {
|
|
|
|
|
if (!strcmp (propname, "WirelessEnabled")) {
|
|
|
|
|
glib_propname = NM_MANAGER_WIRELESS_ENABLED;
|
|
|
|
|
permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI;
|
|
|
|
|
audit_op = NM_AUDIT_OP_RADIO_CONTROL;
|
|
|
|
|
} else if (!strcmp (propname, "WwanEnabled")) {
|
|
|
|
|
glib_propname = NM_MANAGER_WWAN_ENABLED;
|
|
|
|
|
permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN;
|
|
|
|
|
audit_op = NM_AUDIT_OP_RADIO_CONTROL;
|
|
|
|
|
} else if (!strcmp (propname, "WimaxEnabled")) {
|
|
|
|
|
glib_propname = NM_MANAGER_WIMAX_ENABLED;
|
|
|
|
|
permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX;
|
|
|
|
|
audit_op = NM_AUDIT_OP_RADIO_CONTROL;
|
2015-07-03 11:06:39 +02:00
|
|
|
} else if (!strcmp (propname, "GlobalDnsConfiguration")) {
|
|
|
|
|
glib_propname = NM_MANAGER_GLOBAL_DNS_CONFIGURATION;
|
|
|
|
|
permission = NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS;
|
|
|
|
|
audit_op = NM_AUDIT_OP_NET_CONTROL;
|
|
|
|
|
expected_type = G_VARIANT_TYPE ("a{sv}");
|
2015-04-15 14:53:30 -04:00
|
|
|
} else
|
|
|
|
|
return message;
|
2015-09-15 11:34:00 +02:00
|
|
|
interface_type = NMDBUS_TYPE_MANAGER_SKELETON;
|
2015-04-15 14:53:30 -04:00
|
|
|
} else if (!strcmp (propiface, NM_DBUS_INTERFACE_DEVICE)) {
|
|
|
|
|
if (!strcmp (propname, "Autoconnect")) {
|
|
|
|
|
glib_propname = NM_DEVICE_AUTOCONNECT;
|
|
|
|
|
permission = NM_AUTH_PERMISSION_NETWORK_CONTROL;
|
|
|
|
|
audit_op = NM_AUDIT_OP_DEVICE_AUTOCONNECT;
|
2015-09-15 14:27:31 +02:00
|
|
|
} else if (!strcmp (propname, "Managed")) {
|
|
|
|
|
glib_propname = NM_DEVICE_MANAGED;
|
|
|
|
|
permission = NM_AUTH_PERMISSION_NETWORK_CONTROL;
|
|
|
|
|
audit_op = NM_AUDIT_OP_DEVICE_MANAGED;
|
2015-04-15 14:53:30 -04:00
|
|
|
} else
|
|
|
|
|
return message;
|
2015-09-15 11:34:00 +02:00
|
|
|
interface_type = NMDBUS_TYPE_DEVICE_SKELETON;
|
2016-08-10 11:54:32 +02:00
|
|
|
} else if (!strcmp (propiface, NM_DBUS_INTERFACE_DEVICE_STATISTICS)) {
|
|
|
|
|
if (!strcmp (propname, "RefreshRateMs")) {
|
|
|
|
|
glib_propname = NM_DEVICE_STATISTICS_REFRESH_RATE_MS;
|
|
|
|
|
permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS;
|
|
|
|
|
audit_op = NM_AUDIT_OP_STATISTICS;
|
|
|
|
|
expected_type = G_VARIANT_TYPE ("u");
|
|
|
|
|
} else
|
|
|
|
|
return message;
|
|
|
|
|
interface_type = NMDBUS_TYPE_DEVICE_SKELETON;
|
2015-04-15 14:53:30 -04:00
|
|
|
} else
|
|
|
|
|
return message;
|
|
|
|
|
|
2015-07-03 11:06:39 +02:00
|
|
|
if (!g_variant_is_of_type (value, expected_type))
|
|
|
|
|
return message;
|
|
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
/* This filter function is called from a gdbus worker thread which we can't
|
|
|
|
|
* make other D-Bus calls from. In particular, we cannot call
|
|
|
|
|
* org.freedesktop.DBus.GetConnectionUnixUser to find the remote UID.
|
|
|
|
|
*/
|
2015-08-20 13:32:34 +02:00
|
|
|
pfd = g_slice_new0 (PropertyFilterData);
|
2015-08-20 14:25:46 +02:00
|
|
|
pfd->self = self;
|
|
|
|
|
self = NULL;
|
2015-04-15 14:53:30 -04:00
|
|
|
pfd->connection = g_object_ref (connection);
|
|
|
|
|
pfd->message = message;
|
|
|
|
|
pfd->permission = permission;
|
2015-09-15 11:34:00 +02:00
|
|
|
pfd->interface_type = interface_type;
|
|
|
|
|
pfd->glib_propname = glib_propname;
|
2015-04-15 14:53:30 -04:00
|
|
|
pfd->audit_op = audit_op;
|
2015-07-03 11:06:39 +02:00
|
|
|
if (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)) {
|
|
|
|
|
pfd->audit_prop_value = g_strdup_printf ("%s:%d", pfd->glib_propname,
|
|
|
|
|
g_variant_get_boolean (value));
|
|
|
|
|
} else
|
|
|
|
|
pfd->audit_prop_value = g_strdup (pfd->glib_propname);
|
|
|
|
|
|
2015-04-15 14:53:30 -04:00
|
|
|
g_idle_add (do_set_property_check, pfd);
|
|
|
|
|
|
|
|
|
|
return NULL;
|
2010-08-25 15:12:32 -05:00
|
|
|
}
|
|
|
|
|
|
2015-08-20 14:25:46 +02:00
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
_set_prop_filter_free2 (gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
g_slice_free (GWeakRef, user_data);
|
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_set_prop_filter_free (gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
g_weak_ref_clear (user_data);
|
|
|
|
|
|
|
|
|
|
/* Delay the final deletion of the user_data. There is a race when
|
|
|
|
|
* calling g_dbus_connection_remove_filter() that the callback and user_data
|
|
|
|
|
* might have been copied and being executed after the destroy function
|
|
|
|
|
* runs (bgo #704568).
|
|
|
|
|
* This doesn't really fix the race, but it should work well enough. */
|
|
|
|
|
g_timeout_add_seconds (2, _set_prop_filter_free2, user_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_set_prop_filter (NMManager *self, GDBusConnection *connection)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
nm_assert ((!priv->prop_filter.connection) == (!priv->prop_filter.id));
|
|
|
|
|
|
|
|
|
|
if (priv->prop_filter.connection == connection)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (priv->prop_filter.connection) {
|
|
|
|
|
g_dbus_connection_remove_filter (priv->prop_filter.connection, priv->prop_filter.id);
|
|
|
|
|
priv->prop_filter.id = 0;
|
|
|
|
|
g_clear_object (&priv->prop_filter.connection);
|
|
|
|
|
}
|
|
|
|
|
if (connection) {
|
|
|
|
|
GWeakRef *wptr;
|
|
|
|
|
|
|
|
|
|
wptr = g_slice_new (GWeakRef);
|
|
|
|
|
g_weak_ref_init (wptr, self);
|
|
|
|
|
priv->prop_filter.id = g_dbus_connection_add_filter (connection, prop_filter, wptr, _set_prop_filter_free);
|
|
|
|
|
priv->prop_filter.connection = g_object_ref (connection);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
2016-07-01 12:11:01 +02:00
|
|
|
static NMCheckpointManager *
|
|
|
|
|
_checkpoint_mgr_get (NMManager *self, gboolean create_as_needed)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (G_UNLIKELY (!priv->checkpoint_mgr) && create_as_needed)
|
|
|
|
|
priv->checkpoint_mgr = nm_checkpoint_manager_new (self);
|
|
|
|
|
return priv->checkpoint_mgr;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-01 17:57:13 +02:00
|
|
|
static void
|
|
|
|
|
checkpoint_auth_done_cb (NMAuthChain *chain,
|
|
|
|
|
GError *auth_error,
|
|
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (user_data);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2016-08-01 17:19:14 +02:00
|
|
|
char *op, *checkpoint_path = NULL, **devices;
|
2016-08-01 17:57:13 +02:00
|
|
|
NMCheckpoint *checkpoint;
|
|
|
|
|
NMAuthCallResult result;
|
|
|
|
|
guint32 timeout, flags;
|
|
|
|
|
GVariant *variant = NULL;
|
|
|
|
|
GError *error = NULL;
|
2016-08-01 17:19:14 +02:00
|
|
|
const char *arg = NULL;
|
2016-08-01 17:57:13 +02:00
|
|
|
|
2016-08-01 17:19:14 +02:00
|
|
|
op = nm_auth_chain_get_data (chain, "audit-op");
|
2016-08-01 17:57:13 +02:00
|
|
|
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
|
|
|
|
|
result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK);
|
|
|
|
|
|
2016-08-01 17:19:14 +02:00
|
|
|
if ( nm_streq0 (op, NM_AUDIT_OP_CHECKPOINT_DESTROY)
|
|
|
|
|
|| nm_streq0 (op, NM_AUDIT_OP_CHECKPOINT_ROLLBACK))
|
|
|
|
|
arg = checkpoint_path = nm_auth_chain_get_data (chain, "checkpoint_path");
|
|
|
|
|
|
2016-08-01 17:57:13 +02:00
|
|
|
if (auth_error) {
|
|
|
|
|
error = g_error_new (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"checkpoint check request failed: %s",
|
|
|
|
|
auth_error->message);
|
|
|
|
|
} else if (result != NM_AUTH_CALL_RESULT_YES) {
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Not authorized to checkpoint/rollback");
|
|
|
|
|
} else {
|
2016-08-01 17:19:14 +02:00
|
|
|
if (nm_streq0 (op, NM_AUDIT_OP_CHECKPOINT_CREATE)) {
|
2016-08-01 17:57:13 +02:00
|
|
|
timeout = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "timeout"));
|
|
|
|
|
flags = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "flags"));
|
|
|
|
|
devices = nm_auth_chain_get_data (chain, "devices");
|
|
|
|
|
|
|
|
|
|
checkpoint = nm_checkpoint_manager_create (_checkpoint_mgr_get (self, TRUE),
|
|
|
|
|
(const char *const *) devices,
|
|
|
|
|
timeout,
|
|
|
|
|
(NMCheckpointCreateFlags) flags,
|
|
|
|
|
&error);
|
|
|
|
|
if (checkpoint) {
|
2016-08-01 17:19:14 +02:00
|
|
|
arg = nm_exported_object_get_path (NM_EXPORTED_OBJECT (checkpoint));
|
|
|
|
|
variant = g_variant_new ("(o)", arg);
|
2016-08-01 17:57:13 +02:00
|
|
|
}
|
2016-08-01 17:19:14 +02:00
|
|
|
} else if (nm_streq0 (op, NM_AUDIT_OP_CHECKPOINT_DESTROY)) {
|
2016-08-01 17:57:13 +02:00
|
|
|
nm_checkpoint_manager_destroy (_checkpoint_mgr_get (self, TRUE),
|
|
|
|
|
checkpoint_path, &error);
|
2016-08-01 17:19:14 +02:00
|
|
|
} else if (nm_streq0 (op, NM_AUDIT_OP_CHECKPOINT_ROLLBACK)) {
|
2016-08-01 17:57:13 +02:00
|
|
|
nm_checkpoint_manager_rollback (_checkpoint_mgr_get (self, TRUE),
|
|
|
|
|
checkpoint_path, &variant, &error);
|
|
|
|
|
} else
|
|
|
|
|
g_return_if_reached ();
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-01 17:19:14 +02:00
|
|
|
nm_audit_log_checkpoint_op (op, arg ?: "", !error, nm_auth_chain_get_subject (chain),
|
|
|
|
|
error ? error->message : NULL);
|
|
|
|
|
|
2016-08-01 17:57:13 +02:00
|
|
|
if (error)
|
|
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
|
|
|
|
else
|
|
|
|
|
g_dbus_method_invocation_return_value (context, variant);
|
|
|
|
|
|
2016-08-01 17:19:14 +02:00
|
|
|
|
2016-08-01 17:57:13 +02:00
|
|
|
nm_auth_chain_unref (chain);
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-01 12:11:01 +02:00
|
|
|
static void
|
|
|
|
|
impl_manager_checkpoint_create (NMManager *self,
|
|
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
const char *const *devices,
|
|
|
|
|
guint32 rollback_timeout,
|
|
|
|
|
guint32 flags)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv;
|
2016-08-01 17:57:13 +02:00
|
|
|
NMAuthChain *chain;
|
2016-07-01 12:11:01 +02:00
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
G_STATIC_ASSERT_EXPR (sizeof (flags) <= sizeof (NMCheckpointCreateFlags));
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (self));
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
2016-08-01 17:57:13 +02:00
|
|
|
chain = nm_auth_chain_new_context (context, checkpoint_auth_done_cb, self);
|
|
|
|
|
if (!chain) {
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Unable to authenticate request.");
|
2016-07-01 12:11:01 +02:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-01 17:57:13 +02:00
|
|
|
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
2016-08-01 17:19:14 +02:00
|
|
|
nm_auth_chain_set_data (chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_CREATE, NULL);
|
2016-08-01 17:57:13 +02:00
|
|
|
nm_auth_chain_set_data (chain, "devices", g_strdupv ((char **) devices), (GDestroyNotify) g_strfreev);
|
|
|
|
|
nm_auth_chain_set_data (chain, "flags", GUINT_TO_POINTER (flags), NULL);
|
|
|
|
|
nm_auth_chain_set_data (chain, "timeout", GUINT_TO_POINTER (rollback_timeout), NULL);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE);
|
2016-07-01 12:11:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
impl_manager_checkpoint_destroy (NMManager *self,
|
|
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
const char *checkpoint_path)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv;
|
|
|
|
|
GError *error = NULL;
|
2016-08-01 17:57:13 +02:00
|
|
|
NMAuthChain *chain;
|
2016-07-01 12:11:01 +02:00
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (self));
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
2016-08-01 17:57:13 +02:00
|
|
|
chain = nm_auth_chain_new_context (context, checkpoint_auth_done_cb, self);
|
|
|
|
|
if (!chain) {
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Unable to authenticate request.");
|
2016-07-01 12:11:01 +02:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-01 17:57:13 +02:00
|
|
|
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
2016-08-01 17:19:14 +02:00
|
|
|
nm_auth_chain_set_data (chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_DESTROY, NULL);
|
2016-08-01 17:57:13 +02:00
|
|
|
nm_auth_chain_set_data (chain, "checkpoint_path", g_strdup (checkpoint_path), g_free);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE);
|
2016-07-01 12:11:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
impl_manager_checkpoint_rollback (NMManager *self,
|
|
|
|
|
GDBusMethodInvocation *context,
|
|
|
|
|
const char *checkpoint_path)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv;
|
|
|
|
|
GError *error = NULL;
|
2016-08-01 17:57:13 +02:00
|
|
|
NMAuthChain *chain;
|
2016-07-01 12:11:01 +02:00
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_MANAGER (self));
|
|
|
|
|
priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
2016-08-01 17:57:13 +02:00
|
|
|
chain = nm_auth_chain_new_context (context, checkpoint_auth_done_cb, self);
|
|
|
|
|
if (!chain) {
|
|
|
|
|
error = g_error_new_literal (NM_MANAGER_ERROR,
|
|
|
|
|
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
|
|
|
|
"Unable to authenticate request.");
|
2016-07-01 12:11:01 +02:00
|
|
|
g_dbus_method_invocation_take_error (context, error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-01 17:57:13 +02:00
|
|
|
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
2016-08-01 17:19:14 +02:00
|
|
|
nm_auth_chain_set_data (chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_ROLLBACK, NULL);
|
2016-08-01 17:57:13 +02:00
|
|
|
nm_auth_chain_set_data (chain, "checkpoint_path", g_strdup (checkpoint_path), g_free);
|
|
|
|
|
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE);
|
2016-07-01 12:11:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
static void
|
2016-07-01 14:25:34 +02:00
|
|
|
auth_mgr_changed (NMAuthManager *auth_manager, gpointer user_data)
|
2014-01-24 13:24:01 -06:00
|
|
|
{
|
|
|
|
|
/* Let clients know they should re-check their authorization */
|
|
|
|
|
g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define KERN_RFKILL_OP_CHANGE_ALL 3
|
|
|
|
|
#define KERN_RFKILL_TYPE_WLAN 1
|
2013-05-31 14:11:56 -05:00
|
|
|
#define KERN_RFKILL_TYPE_WWAN 5
|
2014-01-24 13:24:01 -06:00
|
|
|
struct rfkill_event {
|
|
|
|
|
__u32 idx;
|
|
|
|
|
__u8 type;
|
|
|
|
|
__u8 op;
|
|
|
|
|
__u8 soft, hard;
|
|
|
|
|
} __attribute__((packed));
|
|
|
|
|
|
|
|
|
|
static void
|
2016-04-27 18:26:39 +02:00
|
|
|
rfkill_change (NMManager *self, const char *desc, RfKillType rtype, gboolean enabled)
|
2014-01-24 13:24:01 -06:00
|
|
|
{
|
|
|
|
|
int fd;
|
|
|
|
|
struct rfkill_event event;
|
|
|
|
|
ssize_t len;
|
|
|
|
|
|
2013-05-31 14:11:56 -05:00
|
|
|
g_return_if_fail (rtype == RFKILL_TYPE_WLAN || rtype == RFKILL_TYPE_WWAN);
|
|
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
errno = 0;
|
|
|
|
|
fd = open ("/dev/rfkill", O_RDWR);
|
|
|
|
|
if (fd < 0) {
|
|
|
|
|
if (errno == EACCES)
|
2016-04-27 18:26:39 +02:00
|
|
|
_LOGW (LOGD_RFKILL, "(%s): failed to open killswitch device", desc);
|
2014-01-24 13:24:01 -06:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0) {
|
2016-04-27 18:26:39 +02:00
|
|
|
_LOGW (LOGD_RFKILL, "(%s): failed to set killswitch device for "
|
|
|
|
|
"non-blocking operation", desc);
|
2014-01-24 13:24:01 -06:00
|
|
|
close (fd);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset (&event, 0, sizeof (event));
|
|
|
|
|
event.op = KERN_RFKILL_OP_CHANGE_ALL;
|
2013-05-31 14:11:56 -05:00
|
|
|
switch (rtype) {
|
|
|
|
|
case RFKILL_TYPE_WLAN:
|
|
|
|
|
event.type = KERN_RFKILL_TYPE_WLAN;
|
|
|
|
|
break;
|
|
|
|
|
case RFKILL_TYPE_WWAN:
|
|
|
|
|
event.type = KERN_RFKILL_TYPE_WWAN;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
}
|
2014-01-24 13:24:01 -06:00
|
|
|
event.soft = enabled ? 0 : 1;
|
|
|
|
|
|
|
|
|
|
len = write (fd, &event, sizeof (event));
|
|
|
|
|
if (len < 0) {
|
2016-04-27 18:26:39 +02:00
|
|
|
_LOGW (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state: (%d) %s",
|
|
|
|
|
desc, errno, g_strerror (errno));
|
2014-01-24 13:24:01 -06:00
|
|
|
} else if (len == sizeof (event)) {
|
2016-04-27 18:26:39 +02:00
|
|
|
_LOGI (LOGD_RFKILL, "%s hardware radio set %s",
|
|
|
|
|
desc, enabled ? "enabled" : "disabled");
|
2014-01-24 13:24:01 -06:00
|
|
|
} else {
|
|
|
|
|
/* Failed to write full structure */
|
2016-04-27 18:26:39 +02:00
|
|
|
_LOGW (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state", desc);
|
2014-01-24 13:24:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
close (fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
manager_radio_user_toggled (NMManager *self,
|
|
|
|
|
RadioState *rstate,
|
|
|
|
|
gboolean enabled)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
gboolean old_enabled, new_enabled;
|
|
|
|
|
|
2013-05-31 14:11:56 -05:00
|
|
|
/* Don't touch devices if asleep/networking disabled */
|
|
|
|
|
if (manager_sleeping (self))
|
|
|
|
|
return;
|
|
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
if (rstate->desc) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_RFKILL, "(%s): setting radio %s by user",
|
|
|
|
|
rstate->desc,
|
|
|
|
|
enabled ? "enabled" : "disabled");
|
2014-01-24 13:24:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Update enabled key in state file */
|
2016-04-07 18:42:24 +02:00
|
|
|
nm_config_state_set (priv->config, TRUE, FALSE,
|
|
|
|
|
rstate->key, enabled);
|
2014-01-24 13:24:01 -06:00
|
|
|
|
|
|
|
|
/* When the user toggles the radio, their request should override any
|
|
|
|
|
* daemon (like ModemManager) enabled state that can be changed. For WWAN
|
|
|
|
|
* for example, we want the WwanEnabled property to reflect the daemon state
|
|
|
|
|
* too so that users can toggle the modem powered, but we don't want that
|
|
|
|
|
* daemon state to affect whether or not the user *can* turn it on, which is
|
|
|
|
|
* what the kernel rfkill state does. So we ignore daemon enabled state
|
|
|
|
|
* when determining what the new state should be since it shouldn't block
|
|
|
|
|
* the user's request.
|
|
|
|
|
*/
|
|
|
|
|
old_enabled = radio_enabled_for_rstate (rstate, TRUE);
|
|
|
|
|
rstate->user_enabled = enabled;
|
|
|
|
|
new_enabled = radio_enabled_for_rstate (rstate, FALSE);
|
|
|
|
|
if (new_enabled != old_enabled) {
|
2013-05-31 14:11:56 -05:00
|
|
|
/* Try to change the kernel rfkill state */
|
|
|
|
|
if (rstate->rtype == RFKILL_TYPE_WLAN || rstate->rtype == RFKILL_TYPE_WWAN)
|
2016-04-27 18:26:39 +02:00
|
|
|
rfkill_change (self, rstate->desc, rstate->rtype, new_enabled);
|
2014-01-24 13:24:01 -06:00
|
|
|
|
2013-05-31 14:11:56 -05:00
|
|
|
manager_update_radio_enabled (self, rstate, new_enabled);
|
2014-01-24 13:24:01 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
|
2015-07-14 16:53:24 +02:00
|
|
|
connection = nm_active_connection_get_settings_connection (ac);
|
2014-01-24 13:24:01 -06:00
|
|
|
nm_settings_connection_update_timestamp (connection, (guint64) time (NULL), FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2015-04-16 14:20:51 -04:00
|
|
|
dbus_connection_changed_cb (NMBusManager *dbus_mgr,
|
2015-04-15 14:53:30 -04:00
|
|
|
GDBusConnection *connection,
|
2014-01-24 13:24:01 -06:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2015-08-20 14:25:46 +02:00
|
|
|
_set_prop_filter (NM_MANAGER (user_data), connection);
|
2014-01-24 13:24:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**********************************************************************/
|
|
|
|
|
|
2016-09-15 23:34:24 +03:00
|
|
|
gboolean
|
|
|
|
|
nm_manager_check_capability (NMManager *self,
|
|
|
|
|
NMCapability cap)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < priv->capabilities->len; i++) {
|
|
|
|
|
NMCapability test = g_array_index (priv->capabilities, gint, i);
|
|
|
|
|
if (test == cap)
|
|
|
|
|
return TRUE;
|
|
|
|
|
if (test > cap)
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
cmp_caps (gconstpointer a, gconstpointer b)
|
|
|
|
|
{
|
|
|
|
|
return *(gint *)a - *(gint *)b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_manager_set_capability (NMManager *self,
|
|
|
|
|
NMCapability cap)
|
|
|
|
|
{
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (!nm_manager_check_capability (self, cap)) {
|
|
|
|
|
g_array_append_val (priv->capabilities, cap);
|
|
|
|
|
g_array_sort (priv->capabilities, cmp_caps);
|
|
|
|
|
_notify (self, PROP_CAPABILITIES);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**********************************************************************/
|
|
|
|
|
|
2015-08-10 16:38:26 +02:00
|
|
|
NM_DEFINE_SINGLETON_REGISTER (NMManager);
|
2011-09-26 11:30:24 -05:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
NMManager *
|
2011-09-26 11:30:24 -05:00
|
|
|
nm_manager_get (void)
|
|
|
|
|
{
|
2016-01-25 16:29:51 +01:00
|
|
|
g_return_val_if_fail (singleton_instance, NULL);
|
2015-08-03 09:26:31 -04:00
|
|
|
return singleton_instance;
|
2011-09-26 11:30:24 -05:00
|
|
|
}
|
|
|
|
|
|
2016-05-16 18:05:02 +02:00
|
|
|
NMSettings *
|
|
|
|
|
nm_settings_get (void)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (singleton_instance, NULL);
|
|
|
|
|
|
|
|
|
|
return NM_MANAGER_GET_PRIVATE (singleton_instance)->settings;
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-26 11:30:24 -05:00
|
|
|
NMManager *
|
2015-11-06 16:45:27 +01:00
|
|
|
nm_manager_setup (void)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
2015-08-03 09:26:31 -04:00
|
|
|
NMManager *self;
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2016-01-25 16:29:51 +01:00
|
|
|
g_return_val_if_fail (!singleton_instance, singleton_instance);
|
2016-01-18 14:22:50 +01:00
|
|
|
|
2015-11-06 16:45:27 +01:00
|
|
|
self = g_object_new (NM_TYPE_MANAGER, NULL);
|
2016-01-18 14:22:50 +01:00
|
|
|
nm_assert (NM_IS_MANAGER (self));
|
|
|
|
|
singleton_instance = self;
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2016-01-18 14:18:50 +01:00
|
|
|
nm_singleton_instance_register ();
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "setup %s singleton (%p)", "NMManager", singleton_instance);
|
2016-01-18 14:18:50 +01:00
|
|
|
|
|
|
|
|
nm_exported_object_export ((NMExportedObject *) self);
|
|
|
|
|
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
constructed (GObject *object)
|
|
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (object);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
|
|
|
|
NMConfigData *config_data;
|
2016-04-07 18:42:24 +02:00
|
|
|
const NMConfigState *state;
|
2016-01-18 14:18:50 +01:00
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (nm_manager_parent_class)->constructed (object);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2016-09-15 23:34:24 +03:00
|
|
|
priv->capabilities = g_array_new (FALSE, FALSE, sizeof (gint));
|
|
|
|
|
|
2015-08-20 14:25:46 +02:00
|
|
|
_set_prop_filter (self, nm_bus_manager_get_connection (priv->dbus_mgr));
|
2014-01-24 12:49:57 -06:00
|
|
|
|
2015-08-03 09:26:31 -04:00
|
|
|
priv->settings = nm_settings_new ();
|
|
|
|
|
g_signal_connect (priv->settings, "notify::" NM_SETTINGS_STARTUP_COMPLETE,
|
|
|
|
|
G_CALLBACK (settings_startup_complete_changed), self);
|
|
|
|
|
g_signal_connect (priv->settings, "notify::" NM_SETTINGS_UNMANAGED_SPECS,
|
|
|
|
|
G_CALLBACK (system_unmanaged_devices_changed_cb), self);
|
|
|
|
|
g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME,
|
|
|
|
|
G_CALLBACK (system_hostname_changed_cb), self);
|
|
|
|
|
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
|
2016-04-13 16:03:06 +02:00
|
|
|
G_CALLBACK (connection_added_cb), self);
|
|
|
|
|
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
|
|
|
|
|
G_CALLBACK (connection_updated_cb), self);
|
|
|
|
|
/*
|
|
|
|
|
* Do not delete existing virtual devices to keep connectivity up.
|
|
|
|
|
* Virtual devices are reused when NetworkManager is restarted.
|
|
|
|
|
* Hence, don't react on NM_SETTINGS_SIGNAL_CONNECTION_REMOVED.
|
|
|
|
|
*/
|
2015-08-03 09:26:31 -04:00
|
|
|
|
|
|
|
|
priv->policy = nm_policy_new (self, priv->settings);
|
2013-08-22 13:06:51 -04:00
|
|
|
g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_DEVICE,
|
2015-08-03 09:26:31 -04:00
|
|
|
G_CALLBACK (policy_default_device_changed), self);
|
2013-08-22 13:06:51 -04:00
|
|
|
g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_DEVICE,
|
2015-08-03 09:26:31 -04:00
|
|
|
G_CALLBACK (policy_default_device_changed), self);
|
2013-08-22 13:06:51 -04:00
|
|
|
g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_DEVICE,
|
2015-08-03 09:26:31 -04:00
|
|
|
G_CALLBACK (policy_activating_device_changed), self);
|
2013-08-22 13:06:51 -04:00
|
|
|
g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_DEVICE,
|
2015-08-03 09:26:31 -04:00
|
|
|
G_CALLBACK (policy_activating_device_changed), self);
|
2013-08-22 10:10:17 -04:00
|
|
|
|
2015-01-30 19:52:53 +01:00
|
|
|
priv->config = g_object_ref (nm_config_get ());
|
|
|
|
|
g_signal_connect (G_OBJECT (priv->config),
|
|
|
|
|
NM_CONFIG_SIGNAL_CONFIG_CHANGED,
|
|
|
|
|
G_CALLBACK (_config_changed_cb),
|
2015-08-03 09:26:31 -04:00
|
|
|
self);
|
2015-01-30 19:52:53 +01:00
|
|
|
|
|
|
|
|
config_data = nm_config_get_data (priv->config);
|
2015-01-29 15:28:03 +01:00
|
|
|
priv->connectivity = nm_connectivity_new (nm_config_data_get_connectivity_uri (config_data),
|
|
|
|
|
nm_config_data_get_connectivity_interval (config_data),
|
|
|
|
|
nm_config_data_get_connectivity_response (config_data));
|
2013-07-30 16:31:31 -04:00
|
|
|
g_signal_connect (priv->connectivity, "notify::" NM_CONNECTIVITY_STATE,
|
2015-08-03 09:26:31 -04:00
|
|
|
G_CALLBACK (connectivity_changed), self);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2016-04-07 18:42:24 +02:00
|
|
|
state = nm_config_state_get (priv->config);
|
2015-11-06 16:45:27 +01:00
|
|
|
|
2016-04-07 18:42:24 +02:00
|
|
|
priv->net_enabled = state->net_enabled;
|
2015-11-06 16:45:27 +01:00
|
|
|
|
2016-04-07 18:42:24 +02:00
|
|
|
priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = state->wifi_enabled;
|
|
|
|
|
priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = state->wwan_enabled;
|
2015-11-06 16:45:27 +01:00
|
|
|
|
2013-05-09 10:24:08 -04:00
|
|
|
priv->rfkill_mgr = nm_rfkill_manager_new ();
|
|
|
|
|
g_signal_connect (priv->rfkill_mgr,
|
2016-08-23 11:45:51 +02:00
|
|
|
NM_RFKILL_MANAGER_SIGNAL_RFKILL_CHANGED,
|
2013-05-09 10:24:08 -04:00
|
|
|
G_CALLBACK (rfkill_manager_rfkill_changed_cb),
|
2015-08-03 09:26:31 -04:00
|
|
|
self);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2013-05-31 14:11:56 -05:00
|
|
|
/* Force kernel WiFi/WWAN rfkill state to follow NM saved WiFi/WWAN state
|
|
|
|
|
* in case the BIOS doesn't save rfkill state, and to be consistent with user
|
|
|
|
|
* changes to the WirelessEnabled/WWANEnabled properties which toggle kernel
|
|
|
|
|
* rfkill.
|
2013-02-06 12:59:50 -06:00
|
|
|
*/
|
2016-04-27 18:26:39 +02:00
|
|
|
rfkill_change (self, priv->radio_states[RFKILL_TYPE_WLAN].desc, RFKILL_TYPE_WLAN, priv->radio_states[RFKILL_TYPE_WLAN].user_enabled);
|
|
|
|
|
rfkill_change (self, priv->radio_states[RFKILL_TYPE_WWAN].desc, RFKILL_TYPE_WWAN, priv->radio_states[RFKILL_TYPE_WWAN].user_enabled);
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
|
2011-07-01 14:16:52 -05:00
|
|
|
static void
|
2016-03-02 11:38:26 +01:00
|
|
|
nm_manager_init (NMManager *self)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
2016-03-02 11:38:26 +01:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2014-01-24 13:24:01 -06:00
|
|
|
guint i;
|
|
|
|
|
GFile *file;
|
2010-05-28 18:23:00 -07:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
/* Initialize rfkill structures and states */
|
|
|
|
|
memset (priv->radio_states, 0, sizeof (priv->radio_states));
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = TRUE;
|
2016-04-07 18:42:24 +02:00
|
|
|
priv->radio_states[RFKILL_TYPE_WLAN].key = NM_CONFIG_STATE_PROPERTY_WIFI_ENABLED;
|
2014-01-24 13:24:01 -06:00
|
|
|
priv->radio_states[RFKILL_TYPE_WLAN].prop = NM_MANAGER_WIRELESS_ENABLED;
|
|
|
|
|
priv->radio_states[RFKILL_TYPE_WLAN].hw_prop = NM_MANAGER_WIRELESS_HARDWARE_ENABLED;
|
|
|
|
|
priv->radio_states[RFKILL_TYPE_WLAN].desc = "WiFi";
|
|
|
|
|
priv->radio_states[RFKILL_TYPE_WLAN].rtype = RFKILL_TYPE_WLAN;
|
2012-08-22 17:11:31 -05:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = TRUE;
|
2016-04-07 18:42:24 +02:00
|
|
|
priv->radio_states[RFKILL_TYPE_WWAN].key = NM_CONFIG_STATE_PROPERTY_WWAN_ENABLED;
|
2014-01-24 13:24:01 -06:00
|
|
|
priv->radio_states[RFKILL_TYPE_WWAN].prop = NM_MANAGER_WWAN_ENABLED;
|
|
|
|
|
priv->radio_states[RFKILL_TYPE_WWAN].hw_prop = NM_MANAGER_WWAN_HARDWARE_ENABLED;
|
|
|
|
|
priv->radio_states[RFKILL_TYPE_WWAN].desc = "WWAN";
|
|
|
|
|
priv->radio_states[RFKILL_TYPE_WWAN].rtype = RFKILL_TYPE_WWAN;
|
2012-08-22 17:11:31 -05:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
for (i = 0; i < RFKILL_TYPE_MAX; i++)
|
|
|
|
|
priv->radio_states[i].hw_enabled = TRUE;
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
priv->sleeping = FALSE;
|
|
|
|
|
priv->state = NM_STATE_DISCONNECTED;
|
|
|
|
|
priv->startup = TRUE;
|
2013-08-22 10:10:17 -04:00
|
|
|
|
2015-08-20 14:26:39 +02:00
|
|
|
priv->dbus_mgr = g_object_ref (nm_bus_manager_get ());
|
2014-01-24 13:24:01 -06:00
|
|
|
g_signal_connect (priv->dbus_mgr,
|
2015-04-16 14:20:51 -04:00
|
|
|
NM_BUS_MANAGER_DBUS_CONNECTION_CHANGED,
|
2014-01-24 13:24:01 -06:00
|
|
|
G_CALLBACK (dbus_connection_changed_cb),
|
2016-03-02 11:38:26 +01:00
|
|
|
self);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
/* sleep/wake handling */
|
2016-04-28 13:45:49 +02:00
|
|
|
priv->sleep_monitor = nm_sleep_monitor_new ();
|
2015-01-05 16:37:45 +01:00
|
|
|
g_signal_connect (priv->sleep_monitor, NM_SLEEP_MONITOR_SLEEPING,
|
2016-03-02 11:38:26 +01:00
|
|
|
G_CALLBACK (sleeping_cb), self);
|
2011-04-22 14:56:31 -05:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
/* Listen for authorization changes */
|
2016-07-01 14:25:34 +02:00
|
|
|
priv->auth_mgr = g_object_ref (nm_auth_manager_get ());
|
|
|
|
|
g_signal_connect (priv->auth_mgr,
|
2014-08-14 13:34:57 +02:00
|
|
|
NM_AUTH_MANAGER_SIGNAL_CHANGED,
|
2016-07-01 14:25:34 +02:00
|
|
|
G_CALLBACK (auth_mgr_changed),
|
2016-03-02 11:38:26 +01:00
|
|
|
self);
|
2014-08-14 13:34:57 +02:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
/* Monitor the firmware directory */
|
|
|
|
|
if (strlen (KERNEL_FIRMWARE_DIR)) {
|
|
|
|
|
file = g_file_new_for_path (KERNEL_FIRMWARE_DIR "/");
|
|
|
|
|
priv->fw_monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
|
|
|
|
|
g_object_unref (file);
|
2011-04-22 14:56:31 -05:00
|
|
|
}
|
|
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
if (priv->fw_monitor) {
|
|
|
|
|
g_signal_connect (priv->fw_monitor, "changed",
|
|
|
|
|
G_CALLBACK (firmware_dir_changed),
|
2016-03-02 11:38:26 +01:00
|
|
|
self);
|
|
|
|
|
_LOGI (LOGD_CORE, "monitoring kernel firmware directory '%s'.",
|
2014-01-24 13:24:01 -06:00
|
|
|
KERNEL_FIRMWARE_DIR);
|
2011-04-22 14:56:31 -05:00
|
|
|
} else {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGW (LOGD_CORE, "failed to monitor kernel firmware directory '%s'.",
|
|
|
|
|
KERNEL_FIRMWARE_DIR);
|
2011-04-22 14:56:31 -05:00
|
|
|
}
|
2010-09-01 17:08:10 -05:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
/* Update timestamps in active connections */
|
2016-03-02 11:38:26 +01:00
|
|
|
priv->timestamp_update_id = g_timeout_add_seconds (300, (GSourceFunc) periodic_update_active_connection_timestamps, self);
|
2015-06-03 09:15:24 +02:00
|
|
|
|
|
|
|
|
priv->metered = NM_METERED_UNKNOWN;
|
2016-05-05 14:14:40 +02:00
|
|
|
priv->sleep_devices = g_hash_table_new (g_direct_hash, g_direct_equal);
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
|
2014-09-24 16:58:07 -05:00
|
|
|
static gboolean
|
|
|
|
|
device_is_real (GObject *device, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
return nm_device_is_real (NM_DEVICE (device));
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
static void
|
|
|
|
|
get_property (GObject *object, guint prop_id,
|
2015-09-15 11:34:00 +02:00
|
|
|
GValue *value, GParamSpec *pspec)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
|
|
|
|
NMManager *self = NM_MANAGER (object);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2015-07-03 11:06:39 +02:00
|
|
|
NMConfigData *config_data;
|
|
|
|
|
const NMGlobalDnsConfig *dns_config;
|
2014-10-23 13:56:52 -04:00
|
|
|
const char *type;
|
2009-06-11 00:39:12 -04:00
|
|
|
|
|
|
|
|
switch (prop_id) {
|
2010-09-27 10:34:56 +02:00
|
|
|
case PROP_VERSION:
|
|
|
|
|
g_value_set_string (value, VERSION);
|
|
|
|
|
break;
|
2016-09-15 23:34:24 +03:00
|
|
|
case PROP_CAPABILITIES:
|
|
|
|
|
g_value_set_variant (value, g_variant_new_fixed_array (G_VARIANT_TYPE ("i"),
|
|
|
|
|
priv->capabilities->data,
|
|
|
|
|
priv->capabilities->len,
|
|
|
|
|
sizeof(gint)));
|
|
|
|
|
break;
|
2009-06-11 00:39:12 -04:00
|
|
|
case PROP_STATE:
|
|
|
|
|
nm_manager_update_state (self);
|
|
|
|
|
g_value_set_uint (value, priv->state);
|
|
|
|
|
break;
|
2013-08-13 17:45:34 -04:00
|
|
|
case PROP_STARTUP:
|
|
|
|
|
g_value_set_boolean (value, priv->startup);
|
|
|
|
|
break;
|
2010-05-22 08:55:30 -07:00
|
|
|
case PROP_NETWORKING_ENABLED:
|
|
|
|
|
g_value_set_boolean (value, priv->net_enabled);
|
|
|
|
|
break;
|
2009-06-11 00:39:12 -04:00
|
|
|
case PROP_WIRELESS_ENABLED:
|
2011-04-13 21:58:25 -05:00
|
|
|
g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WLAN, TRUE));
|
2009-06-11 00:39:12 -04:00
|
|
|
break;
|
|
|
|
|
case PROP_WIRELESS_HARDWARE_ENABLED:
|
2009-12-23 00:03:45 -08:00
|
|
|
g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WLAN].hw_enabled);
|
2009-06-11 00:39:12 -04:00
|
|
|
break;
|
2009-12-23 00:18:18 -08:00
|
|
|
case PROP_WWAN_ENABLED:
|
2011-04-13 21:58:25 -05:00
|
|
|
g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WWAN, TRUE));
|
2009-12-23 00:18:18 -08:00
|
|
|
break;
|
|
|
|
|
case PROP_WWAN_HARDWARE_ENABLED:
|
|
|
|
|
g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].hw_enabled);
|
2009-06-11 00:39:12 -04:00
|
|
|
break;
|
2009-12-29 11:27:10 +02:00
|
|
|
case PROP_WIMAX_ENABLED:
|
2015-08-10 16:56:21 +02:00
|
|
|
g_value_set_boolean (value, FALSE);
|
2009-12-29 11:27:10 +02:00
|
|
|
break;
|
|
|
|
|
case PROP_WIMAX_HARDWARE_ENABLED:
|
2015-08-10 16:56:21 +02:00
|
|
|
g_value_set_boolean (value, FALSE);
|
2009-12-29 11:27:10 +02:00
|
|
|
break;
|
2009-06-11 00:39:12 -04:00
|
|
|
case PROP_ACTIVE_CONNECTIONS:
|
2015-08-06 10:29:29 +02:00
|
|
|
nm_utils_g_value_set_object_path_array (value, priv->active_connections, NULL, NULL);
|
2009-06-11 00:39:12 -04:00
|
|
|
break;
|
2013-07-30 16:31:31 -04:00
|
|
|
case PROP_CONNECTIVITY:
|
|
|
|
|
g_value_set_uint (value, nm_connectivity_get_state (priv->connectivity));
|
|
|
|
|
break;
|
2013-08-22 13:06:51 -04:00
|
|
|
case PROP_PRIMARY_CONNECTION:
|
2015-04-03 10:08:52 -04:00
|
|
|
nm_utils_g_value_set_object_path (value, priv->primary_connection);
|
2013-08-22 13:06:51 -04:00
|
|
|
break;
|
2014-10-23 13:56:52 -04:00
|
|
|
case PROP_PRIMARY_CONNECTION_TYPE:
|
2015-07-14 16:53:24 +02:00
|
|
|
type = NULL;
|
|
|
|
|
if (priv->primary_connection) {
|
|
|
|
|
NMConnection *con;
|
|
|
|
|
|
|
|
|
|
con = nm_active_connection_get_applied_connection (priv->primary_connection);
|
|
|
|
|
if (con)
|
|
|
|
|
type = nm_connection_get_connection_type (con);
|
|
|
|
|
}
|
2014-10-23 13:56:52 -04:00
|
|
|
g_value_set_string (value, type ? type : "");
|
|
|
|
|
break;
|
2013-08-22 13:06:51 -04:00
|
|
|
case PROP_ACTIVATING_CONNECTION:
|
2015-04-03 10:08:52 -04:00
|
|
|
nm_utils_g_value_set_object_path (value, priv->activating_connection);
|
2013-08-22 13:06:51 -04:00
|
|
|
break;
|
2009-06-11 00:39:12 -04:00
|
|
|
case PROP_HOSTNAME:
|
|
|
|
|
g_value_set_string (value, priv->hostname);
|
|
|
|
|
break;
|
2009-10-20 15:25:04 -07:00
|
|
|
case PROP_SLEEPING:
|
|
|
|
|
g_value_set_boolean (value, priv->sleeping);
|
|
|
|
|
break;
|
2014-01-08 12:18:33 -06:00
|
|
|
case PROP_DEVICES:
|
2014-09-24 16:58:07 -05:00
|
|
|
nm_utils_g_value_set_object_path_array (value, priv->devices, device_is_real, NULL);
|
2014-01-08 12:18:33 -06:00
|
|
|
break;
|
2015-06-03 09:15:24 +02:00
|
|
|
case PROP_METERED:
|
|
|
|
|
g_value_set_uint (value, priv->metered);
|
|
|
|
|
break;
|
2015-07-03 11:06:39 +02:00
|
|
|
case PROP_GLOBAL_DNS_CONFIGURATION:
|
|
|
|
|
config_data = nm_config_get_data (priv->config);
|
|
|
|
|
dns_config = nm_config_data_get_global_dns_config (config_data);
|
|
|
|
|
nm_global_dns_config_to_dbus (dns_config, value);
|
|
|
|
|
break;
|
2014-10-06 11:21:54 -05:00
|
|
|
case PROP_ALL_DEVICES:
|
|
|
|
|
nm_utils_g_value_set_object_path_array (value, priv->devices, NULL, NULL);
|
|
|
|
|
break;
|
2009-06-11 00:39:12 -04:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-20 08:51:08 -05:00
|
|
|
static void
|
2014-01-24 13:24:01 -06:00
|
|
|
set_property (GObject *object, guint prop_id,
|
2016-01-18 14:18:50 +01:00
|
|
|
const GValue *value, GParamSpec *pspec)
|
2013-03-20 08:51:08 -05:00
|
|
|
{
|
2014-01-24 13:24:01 -06:00
|
|
|
NMManager *self = NM_MANAGER (object);
|
|
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
2015-07-03 11:06:39 +02:00
|
|
|
NMGlobalDnsConfig *dns_config;
|
|
|
|
|
GError *error = NULL;
|
2013-03-20 08:51:08 -05:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
switch (prop_id) {
|
|
|
|
|
case PROP_WIRELESS_ENABLED:
|
2015-11-06 16:45:27 +01:00
|
|
|
manager_radio_user_toggled (NM_MANAGER (object),
|
|
|
|
|
&priv->radio_states[RFKILL_TYPE_WLAN],
|
|
|
|
|
g_value_get_boolean (value));
|
2014-01-24 13:24:01 -06:00
|
|
|
break;
|
|
|
|
|
case PROP_WWAN_ENABLED:
|
2015-11-06 16:45:27 +01:00
|
|
|
manager_radio_user_toggled (NM_MANAGER (object),
|
|
|
|
|
&priv->radio_states[RFKILL_TYPE_WWAN],
|
|
|
|
|
g_value_get_boolean (value));
|
2014-01-24 13:24:01 -06:00
|
|
|
break;
|
|
|
|
|
case PROP_WIMAX_ENABLED:
|
2015-08-10 16:56:21 +02:00
|
|
|
/* WIMAX is depreacted. This does nothing. */
|
2014-01-24 13:24:01 -06:00
|
|
|
break;
|
2015-07-03 11:06:39 +02:00
|
|
|
case PROP_GLOBAL_DNS_CONFIGURATION:
|
|
|
|
|
dns_config = nm_global_dns_config_from_dbus (value, &error);
|
|
|
|
|
if (!error)
|
|
|
|
|
nm_config_set_global_dns (priv->config, dns_config, &error);
|
|
|
|
|
|
|
|
|
|
nm_global_dns_config_free (dns_config);
|
|
|
|
|
|
|
|
|
|
if (error) {
|
2016-03-02 11:38:26 +01:00
|
|
|
_LOGD (LOGD_CORE, "set global DNS failed with error: %s", error->message);
|
2015-07-03 11:06:39 +02:00
|
|
|
g_error_free (error);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-01-24 13:24:01 -06:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
|
break;
|
2013-03-20 08:51:08 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 14:17:30 -05:00
|
|
|
static void
|
|
|
|
|
_deinit_device_factory (NMDeviceFactory *factory, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
g_signal_handlers_disconnect_matched (factory, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NM_MANAGER (user_data));
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
static void
|
2014-01-24 13:24:01 -06:00
|
|
|
dispose (GObject *object)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
2014-01-24 13:24:01 -06:00
|
|
|
NMManager *manager = NM_MANAGER (object);
|
2009-06-11 00:39:12 -04:00
|
|
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
2009-12-23 00:03:45 -08:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
g_slist_free_full (priv->auth_chains, (GDestroyNotify) nm_auth_chain_unref);
|
|
|
|
|
priv->auth_chains = NULL;
|
2009-12-23 00:03:45 -08:00
|
|
|
|
2016-07-01 12:11:01 +02:00
|
|
|
if (priv->checkpoint_mgr) {
|
|
|
|
|
nm_checkpoint_manager_destroy_all (priv->checkpoint_mgr, NULL);
|
|
|
|
|
g_clear_pointer (&priv->checkpoint_mgr, nm_checkpoint_manager_unref);
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-01 14:25:34 +02:00
|
|
|
if (priv->auth_mgr) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->auth_mgr,
|
|
|
|
|
G_CALLBACK (auth_mgr_changed),
|
|
|
|
|
manager);
|
|
|
|
|
g_clear_object (&priv->auth_mgr);
|
|
|
|
|
}
|
2009-12-23 00:18:18 -08:00
|
|
|
|
2014-10-29 09:12:18 -05:00
|
|
|
g_assert (priv->devices == NULL);
|
2010-04-08 18:23:43 -07:00
|
|
|
|
2016-01-04 09:46:22 +01:00
|
|
|
nm_clear_g_source (&priv->ac_cleanup_id);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
while (priv->active_connections)
|
|
|
|
|
active_connection_remove (manager, NM_ACTIVE_CONNECTION (priv->active_connections->data));
|
|
|
|
|
g_clear_pointer (&priv->active_connections, g_slist_free);
|
|
|
|
|
g_clear_object (&priv->primary_connection);
|
|
|
|
|
g_clear_object (&priv->activating_connection);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2015-01-30 19:52:53 +01:00
|
|
|
if (priv->config) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->config, _config_changed_cb, manager);
|
|
|
|
|
g_clear_object (&priv->config);
|
|
|
|
|
}
|
2015-01-29 15:28:03 +01:00
|
|
|
if (priv->connectivity) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->connectivity, connectivity_changed, manager);
|
|
|
|
|
g_clear_object (&priv->connectivity);
|
|
|
|
|
}
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
g_free (priv->hostname);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
if (priv->policy) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->policy, policy_default_device_changed, manager);
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->policy, policy_activating_device_changed, manager);
|
|
|
|
|
g_clear_object (&priv->policy);
|
|
|
|
|
}
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2015-09-21 14:30:02 +02:00
|
|
|
if (priv->settings) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->settings, settings_startup_complete_changed, manager);
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->settings, system_unmanaged_devices_changed_cb, manager);
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->settings, system_hostname_changed_cb, manager);
|
2016-04-13 16:03:06 +02:00
|
|
|
g_signal_handlers_disconnect_by_func (priv->settings, connection_added_cb, manager);
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->settings, connection_updated_cb, manager);
|
2015-09-21 14:30:02 +02:00
|
|
|
g_clear_object (&priv->settings);
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
g_clear_object (&priv->vpn_manager);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
/* Unregister property filter */
|
|
|
|
|
if (priv->dbus_mgr) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->dbus_mgr, dbus_connection_changed_cb, manager);
|
2015-08-20 14:26:39 +02:00
|
|
|
g_clear_object (&priv->dbus_mgr);
|
2014-01-24 13:24:01 -06:00
|
|
|
}
|
2015-08-20 14:25:46 +02:00
|
|
|
_set_prop_filter (manager, NULL);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2016-05-05 14:14:40 +02:00
|
|
|
sleep_devices_clear (manager);
|
|
|
|
|
g_clear_pointer (&priv->sleep_devices, g_hash_table_unref);
|
|
|
|
|
|
2015-01-05 16:37:45 +01:00
|
|
|
if (priv->sleep_monitor) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->sleep_monitor, sleeping_cb, manager);
|
|
|
|
|
g_clear_object (&priv->sleep_monitor);
|
|
|
|
|
}
|
2010-05-28 18:23:00 -07:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
if (priv->fw_monitor) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->fw_monitor, firmware_dir_changed, manager);
|
2010-08-31 15:45:55 -05:00
|
|
|
|
2016-01-04 09:46:22 +01:00
|
|
|
nm_clear_g_source (&priv->fw_changed_id);
|
2010-07-01 10:32:11 -07:00
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
g_file_monitor_cancel (priv->fw_monitor);
|
|
|
|
|
g_clear_object (&priv->fw_monitor);
|
2010-07-01 10:32:11 -07:00
|
|
|
}
|
|
|
|
|
|
2015-09-21 14:38:25 +02:00
|
|
|
if (priv->rfkill_mgr) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->rfkill_mgr, rfkill_manager_rfkill_changed_cb, manager);
|
|
|
|
|
g_clear_object (&priv->rfkill_mgr);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 14:17:30 -05:00
|
|
|
nm_device_factory_manager_for_each_factory (_deinit_device_factory, manager);
|
2016-01-18 14:18:50 +01:00
|
|
|
|
2016-01-04 09:46:22 +01:00
|
|
|
nm_clear_g_source (&priv->timestamp_update_id);
|
2012-02-05 23:18:32 -06:00
|
|
|
|
2016-09-15 23:34:24 +03:00
|
|
|
g_array_free (priv->capabilities, TRUE);
|
|
|
|
|
|
2014-01-24 13:24:01 -06:00
|
|
|
G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
nm_manager_class_init (NMManagerClass *manager_class)
|
|
|
|
|
{
|
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
|
2015-04-03 10:08:52 -04:00
|
|
|
NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (manager_class);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2015-04-03 10:08:52 -04:00
|
|
|
exported_object_class->export_path = NM_DBUS_PATH;
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
/* virtual methods */
|
2016-01-18 14:18:50 +01:00
|
|
|
object_class->constructed = constructed;
|
2009-06-11 00:39:12 -04:00
|
|
|
object_class->set_property = set_property;
|
|
|
|
|
object_class->get_property = get_property;
|
|
|
|
|
object_class->dispose = dispose;
|
|
|
|
|
|
|
|
|
|
/* properties */
|
2016-04-01 17:34:51 +02:00
|
|
|
obj_properties[PROP_VERSION] =
|
|
|
|
|
g_param_spec_string (NM_MANAGER_VERSION, "", "",
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
2016-09-15 23:34:24 +03:00
|
|
|
obj_properties[PROP_CAPABILITIES] =
|
|
|
|
|
g_param_spec_variant (NM_MANAGER_CAPABILITIES, "", "",
|
|
|
|
|
G_VARIANT_TYPE ("au"),
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
2016-04-01 17:34:51 +02:00
|
|
|
obj_properties[PROP_STATE] =
|
|
|
|
|
g_param_spec_uint (NM_MANAGER_STATE, "", "",
|
|
|
|
|
0, NM_STATE_DISCONNECTED, 0,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_STARTUP] =
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_STARTUP, "", "",
|
|
|
|
|
TRUE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_NETWORKING_ENABLED] =
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED, "", "",
|
|
|
|
|
TRUE,
|
2015-11-06 16:45:27 +01:00
|
|
|
G_PARAM_READABLE |
|
2016-04-01 17:34:51 +02:00
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_WIRELESS_ENABLED] =
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, "", "",
|
|
|
|
|
TRUE,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_WIRELESS_HARDWARE_ENABLED] =
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED, "", "",
|
|
|
|
|
TRUE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_WWAN_ENABLED] =
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED, "", "",
|
|
|
|
|
TRUE,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_WWAN_HARDWARE_ENABLED] =
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_WWAN_HARDWARE_ENABLED, "", "",
|
|
|
|
|
TRUE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_WIMAX_ENABLED] =
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED, "", "",
|
|
|
|
|
TRUE,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_WIMAX_HARDWARE_ENABLED] =
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED, "", "",
|
|
|
|
|
TRUE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_ACTIVE_CONNECTIONS] =
|
|
|
|
|
g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, "", "",
|
|
|
|
|
G_TYPE_STRV,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_CONNECTIVITY] =
|
|
|
|
|
g_param_spec_uint (NM_MANAGER_CONNECTIVITY, "", "",
|
|
|
|
|
NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_PRIMARY_CONNECTION] =
|
|
|
|
|
g_param_spec_string (NM_MANAGER_PRIMARY_CONNECTION, "", "",
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_PRIMARY_CONNECTION_TYPE] =
|
|
|
|
|
g_param_spec_string (NM_MANAGER_PRIMARY_CONNECTION_TYPE, "", "",
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_ACTIVATING_CONNECTION] =
|
|
|
|
|
g_param_spec_string (NM_MANAGER_ACTIVATING_CONNECTION, "", "",
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
2013-08-22 13:06:51 -04:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
/* Hostname is not exported over D-Bus */
|
2016-04-01 17:34:51 +02:00
|
|
|
obj_properties[PROP_HOSTNAME] =
|
|
|
|
|
g_param_spec_string (NM_MANAGER_HOSTNAME, "", "",
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2010-05-22 08:55:30 -07:00
|
|
|
/* Sleeping is not exported over D-Bus */
|
2016-04-01 17:34:51 +02:00
|
|
|
obj_properties[PROP_SLEEPING] =
|
|
|
|
|
g_param_spec_boolean (NM_MANAGER_SLEEPING, "", "",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
obj_properties[PROP_DEVICES] =
|
|
|
|
|
g_param_spec_boxed (NM_MANAGER_DEVICES, "", "",
|
|
|
|
|
G_TYPE_STRV,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
2014-01-08 12:18:33 -06:00
|
|
|
|
2015-06-03 09:15:24 +02:00
|
|
|
/**
|
|
|
|
|
* NMManager:metered:
|
|
|
|
|
*
|
|
|
|
|
* Whether the connectivity is metered.
|
|
|
|
|
*
|
|
|
|
|
* Since: 1.2
|
|
|
|
|
**/
|
2016-04-01 17:34:51 +02:00
|
|
|
obj_properties[PROP_METERED] =
|
|
|
|
|
g_param_spec_uint (NM_MANAGER_METERED, "", "",
|
|
|
|
|
0, G_MAXUINT32, NM_METERED_UNKNOWN,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
2015-06-03 09:15:24 +02:00
|
|
|
|
2015-07-03 11:06:39 +02:00
|
|
|
/**
|
|
|
|
|
* NMManager:global-dns-configuration:
|
|
|
|
|
*
|
|
|
|
|
* The global DNS configuration.
|
|
|
|
|
*
|
|
|
|
|
* Since: 1.2
|
|
|
|
|
**/
|
2016-04-01 17:34:51 +02:00
|
|
|
obj_properties[PROP_GLOBAL_DNS_CONFIGURATION] =
|
|
|
|
|
g_param_spec_variant (NM_MANAGER_GLOBAL_DNS_CONFIGURATION, "", "",
|
|
|
|
|
G_VARIANT_TYPE ("a{sv}"),
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
2015-07-03 11:06:39 +02:00
|
|
|
|
2014-10-06 11:21:54 -05:00
|
|
|
/**
|
|
|
|
|
* NMManager:all-devices:
|
|
|
|
|
*
|
|
|
|
|
* All devices, including those that are not realized.
|
|
|
|
|
*
|
|
|
|
|
* Since: 1.2
|
|
|
|
|
**/
|
2016-04-01 17:34:51 +02:00
|
|
|
obj_properties[PROP_ALL_DEVICES] =
|
|
|
|
|
g_param_spec_boxed (NM_MANAGER_ALL_DEVICES, "", "",
|
|
|
|
|
G_TYPE_STRV,
|
|
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
|
|
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
2014-10-06 11:21:54 -05:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
/* signals */
|
2014-10-06 11:21:54 -05:00
|
|
|
|
|
|
|
|
/* D-Bus exported; emitted only for realized devices */
|
2009-06-11 00:39:12 -04:00
|
|
|
signals[DEVICE_ADDED] =
|
2016-04-04 14:17:09 +02:00
|
|
|
g_signal_new (NM_MANAGER_DEVICE_ADDED,
|
2016-04-01 17:34:51 +02:00
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2016-04-28 14:05:11 +02:00
|
|
|
0, NULL, NULL, NULL,
|
2016-04-01 17:34:51 +02:00
|
|
|
G_TYPE_NONE, 1, NM_TYPE_DEVICE);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-10-06 11:21:54 -05:00
|
|
|
/* Emitted for both realized devices and placeholder devices */
|
|
|
|
|
signals[INTERNAL_DEVICE_ADDED] =
|
2016-04-04 14:17:09 +02:00
|
|
|
g_signal_new (NM_MANAGER_INTERNAL_DEVICE_ADDED,
|
2016-04-01 17:34:51 +02:00
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST, 0,
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
2014-10-06 11:21:54 -05:00
|
|
|
|
2016-09-14 14:15:24 +02:00
|
|
|
/* D-Bus exported; emitted only for realized devices when a device
|
|
|
|
|
* becomes unrealized or removed */
|
2009-06-11 00:39:12 -04:00
|
|
|
signals[DEVICE_REMOVED] =
|
2016-04-04 14:17:09 +02:00
|
|
|
g_signal_new (NM_MANAGER_DEVICE_REMOVED,
|
2016-04-01 17:34:51 +02:00
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2016-04-28 14:05:11 +02:00
|
|
|
0, NULL, NULL, NULL,
|
2016-04-01 17:34:51 +02:00
|
|
|
G_TYPE_NONE, 1, NM_TYPE_DEVICE);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-10-06 11:21:54 -05:00
|
|
|
/* Emitted for both realized devices and placeholder devices */
|
|
|
|
|
signals[INTERNAL_DEVICE_REMOVED] =
|
2016-04-04 14:17:09 +02:00
|
|
|
g_signal_new (NM_MANAGER_INTERNAL_DEVICE_REMOVED,
|
2016-04-01 17:34:51 +02:00
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST, 0,
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
2014-10-06 11:21:54 -05:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
signals[STATE_CHANGED] =
|
2016-04-01 17:34:51 +02:00
|
|
|
g_signal_new (NM_MANAGER_STATE_CHANGED,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
2016-04-28 14:05:11 +02:00
|
|
|
0, NULL, NULL, NULL,
|
2016-04-01 17:34:51 +02:00
|
|
|
G_TYPE_NONE, 1, G_TYPE_UINT);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2010-05-28 18:23:00 -07:00
|
|
|
signals[CHECK_PERMISSIONS] =
|
2016-04-04 14:17:09 +02:00
|
|
|
g_signal_new (NM_MANAGER_CHECK_PERMISSIONS,
|
2016-04-01 17:34:51 +02:00
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 0);
|
2010-05-28 18:23:00 -07:00
|
|
|
|
2012-08-22 18:33:17 -05:00
|
|
|
signals[ACTIVE_CONNECTION_ADDED] =
|
2016-04-01 17:34:51 +02:00
|
|
|
g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_ADDED,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION);
|
2012-08-22 18:33:17 -05:00
|
|
|
|
|
|
|
|
signals[ACTIVE_CONNECTION_REMOVED] =
|
2016-04-01 17:34:51 +02:00
|
|
|
g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_REMOVED,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION);
|
2012-08-22 18:33:17 -05:00
|
|
|
|
2014-10-29 09:12:18 -05:00
|
|
|
signals[CONFIGURE_QUIT] =
|
2016-04-01 17:34:51 +02:00
|
|
|
g_signal_new (NM_MANAGER_CONFIGURE_QUIT,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 0);
|
2014-10-29 09:12:18 -05:00
|
|
|
|
2015-04-13 13:31:42 -04:00
|
|
|
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (manager_class),
|
2015-04-15 14:53:30 -04:00
|
|
|
NMDBUS_TYPE_MANAGER_SKELETON,
|
2016-05-30 15:42:44 +02:00
|
|
|
"Reload", impl_manager_reload,
|
2015-04-15 14:53:30 -04:00
|
|
|
"GetDevices", impl_manager_get_devices,
|
2014-10-06 11:21:54 -05:00
|
|
|
"GetAllDevices", impl_manager_get_all_devices,
|
2015-04-15 14:53:30 -04:00
|
|
|
"GetDeviceByIpIface", impl_manager_get_device_by_ip_iface,
|
|
|
|
|
"ActivateConnection", impl_manager_activate_connection,
|
|
|
|
|
"AddAndActivateConnection", impl_manager_add_and_activate_connection,
|
|
|
|
|
"DeactivateConnection", impl_manager_deactivate_connection,
|
|
|
|
|
"Sleep", impl_manager_sleep,
|
|
|
|
|
"Enable", impl_manager_enable,
|
|
|
|
|
"GetPermissions", impl_manager_get_permissions,
|
|
|
|
|
"SetLogging", impl_manager_set_logging,
|
|
|
|
|
"GetLogging", impl_manager_get_logging,
|
|
|
|
|
"CheckConnectivity", impl_manager_check_connectivity,
|
|
|
|
|
"state", impl_manager_get_state,
|
2016-07-01 12:11:01 +02:00
|
|
|
"CheckpointCreate", impl_manager_checkpoint_create,
|
|
|
|
|
"CheckpointDestroy", impl_manager_checkpoint_destroy,
|
|
|
|
|
"CheckpointRollback", impl_manager_checkpoint_rollback,
|
2015-04-15 14:53:30 -04:00
|
|
|
NULL);
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|