NetworkManager/src/devices/nm-device.h

832 lines
38 KiB
C
Raw Normal View History

/* -*- 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.
*
* Copyright (C) 2005 - 2017 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
#ifndef __NETWORKMANAGER_DEVICE_H__
#define __NETWORKMANAGER_DEVICE_H__
#include <netinet/in.h>
#include "nm-setting-connection.h"
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API Previously, we used the generated GDBusInterfaceSkeleton types and glued them via the NMExportedObject base class to our NM types. We also used GDBusObjectManagerServer. Don't do that anymore. The resulting code was more complicated despite (or because?) using generated classes. It was hard to understand, complex, had ordering-issues, and had a runtime and memory overhead. This patch refactors this entirely and uses the lower layer API GDBusConnection directly. It replaces the generated code, GDBusInterfaceSkeleton, and GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager and static descriptor instances of type GDBusInterfaceInfo. This adds a net plus of more then 1300 lines of hand written code. I claim that this implementation is easier to understand. Note that previously we also required extensive and complex glue code to bind our objects to the generated skeleton objects. Instead, now glue our objects directly to GDBusConnection. The result is more immediate and gets rid of layers of code in between. Now that the D-Bus glue us more under our control, we can address issus and bottlenecks better, instead of adding code to bend the generated skeletons to our needs. Note that the current implementation now only supports one D-Bus connection. That was effectively the case already, although there were places (and still are) where the code pretends it could also support connections from a private socket. We dropped private socket support mainly because it was unused, untested and buggy, but also because GDBusObjectManagerServer could not export the same objects on multiple connections. Now, it would be rather straight forward to fix that and re-introduce ObjectManager on each private connection. But this commit doesn't do that yet, and the new code intentionally supports only one D-Bus connection. Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start() succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough for the moment. It could be easily extended later, for example with polling whether the system bus appears (like was done previously). Also, restart of D-Bus daemon isn't supported either -- just like before. Note how NMDBusManager now implements the ObjectManager D-Bus interface directly. Also, this fixes race issues in the server, by no longer delaying PropertiesChanged signals. NMExportedObject would collect changed properties and send the signal out in idle_emit_properties_changed() on idle. This messes up the ordering of change events w.r.t. other signals and events on the bus. Note that not only NMExportedObject messed up the ordering. Also the generated code would hook into notify() and process change events in and idle handle, exhibiting the same ordering issue too. No longer do that. PropertiesChanged signals will be sent right away by hooking into dispatch_properties_changed(). This means, changing a property in quick succession will no longer be combined and is guaranteed to emit signals for each individual state. Quite possibly we emit now more PropertiesChanged signals then before. However, we are now able to group a set of changes by using standard g_object_freeze_notify()/g_object_thaw_notify(). We probably should make more use of that. Also, now that our signals are all handled in the right order, we might find places where we still emit them in the wrong order. But that is then due to the order in which our GObjects emit signals, not due to an ill behavior of the D-Bus glue. Possibly we need to identify such ordering issues and fix them. Numbers (for contrib/rpm --without debug on x86_64): - the patch changes the code size of NetworkManager by - 2809360 bytes + 2537528 bytes (-9.7%) - Runtime measurements are harder because there is a large variance during testing. In other words, the numbers are not reproducible. Currently, the implementation performs no caching of GVariants at all, but it would be rather simple to add it, if that turns out to be useful. Anyway, without strong claim, it seems that the new form tends to perform slightly better. That would be no surprise. $ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done) - real 1m39.355s + real 1m37.432s $ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done) - real 0m26.843s + real 0m25.281s - Regarding RSS size, just looking at the processes in similar conditions, doesn't give a large difference. On my system they consume about 19MB RSS. It seems that the new version has a slightly smaller RSS size. - 19356 RSS + 18660 RSS
2018-02-26 13:51:52 +01:00
#include "nm-dbus-object.h"
#include "nm-dbus-interface.h"
2007-05-07 Tambet Ingo <tambet@ximian.com> * libnm-glib/Makefile.am: Link with libnm-util to gain access to NMConnection. * libnm-glib/nm-device-802-11-wireless.c: (nm_device_802_3_ethernet_activate): Remove. * libnm-glib/nm-device-802-3-ethernet.c (nm_device_802_3_ethernet_activate): Remove. * libnm-glib/nm-device.c (nm_device_activate): Implement. * src/nm-device-802-3-ethernet.c: Implement the new activation using NMConnection. * src/nm-device-802-11-wireless.c: Store an activation AP once the activation has started. Implement the new activation using NMConnection. * src/nm-activation-request.c: Store a generic connection object instead of a wireless-specific AP. * src/NetworkManagerPolicy.c (create_connection): Implement. Depending on device type, create a device specific connection object suitable for device activation. * src/nm-device.c (nm_device_activate): Re-implement. Call the device specific check to validate the connection and on success start the activation. * src/nm-device-interface.h: Add a activate virtual function to the interface definition. * src/nm-device-interface.c (nm_device_interface_activate): Implement. (impl_device_activate): Implement. * introspection/nm-device.xml: Add a generic device activation interface that accepts an abstract NMConnection structure that has device-specific information in it. * introspection/nm-device-802-3-ethernet.xml: Remove the wired-specific activation interface. * introspection/nm-device-802-11-wireless.xml: Remove the wireless-specific activation interface. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2569 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2007-05-07 15:17:45 +00:00
#include "nm-connection.h"
#include "nm-rfkill-manager.h"
#include "NetworkManagerUtils.h"
device: track system interface state in NMDevice When deciding whether to touch a device we sometimes look at whether the active connection is external/assumed. In many cases however, there is no active connection around (e.g. while moving the device from state unmanaged to disconnected before assuming). So in most cases we instead look at the device-state-reason to decide whether to touch the interface (see nm_device_state_reason_check()). Often it's desirable to have no state and passing data as function arguments. However, the state reason has to be passed along several hops (e.g. a queued state change). Or a change to a master/slave can affect the slave/master, where we pass on the state reason. Or an intermediate event might invalidate a previous state reason. Passing the state whether to touch a device or not as a state-reason is cumbersome and limited. Instead, the device should be aware of whats going on. Add a sys-iface-state with: - SYS_IFACE_STATE_EXTERNAL: meaning, NM should not touch it - SYS_IFACE_STATE_ASSUME: meaning, NM is gracefully taking over - SYS_IFACE_STATE_MANAGED: meaning, the device is managed by NM - SYS_IFACE_STATE_REMOVED: the device no longer exists This replaces most checks of nm_device_state_reason_check() and nm_active_connection_get_activation_type() by instead looking at the sys-iface-state of the device. This patch probably has still issues, but the previous behavior was not very clear either. We will need to identify those issues in future tests and tweak the behavior. At least, now there is one flag that describes how to behave.
2017-03-13 15:34:14 +01:00
typedef enum {
NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
NM_DEVICE_SYS_IFACE_STATE_ASSUME,
NM_DEVICE_SYS_IFACE_STATE_MANAGED,
/* the REMOVED state applies when the device is manually set to unmanaged
* or the link was externally removed. In both cases, we move the device
* to UNMANAGED state, without touching the link -- be it, because the link
* is already gone or because we want to release it (give it up).
*/
device: track system interface state in NMDevice When deciding whether to touch a device we sometimes look at whether the active connection is external/assumed. In many cases however, there is no active connection around (e.g. while moving the device from state unmanaged to disconnected before assuming). So in most cases we instead look at the device-state-reason to decide whether to touch the interface (see nm_device_state_reason_check()). Often it's desirable to have no state and passing data as function arguments. However, the state reason has to be passed along several hops (e.g. a queued state change). Or a change to a master/slave can affect the slave/master, where we pass on the state reason. Or an intermediate event might invalidate a previous state reason. Passing the state whether to touch a device or not as a state-reason is cumbersome and limited. Instead, the device should be aware of whats going on. Add a sys-iface-state with: - SYS_IFACE_STATE_EXTERNAL: meaning, NM should not touch it - SYS_IFACE_STATE_ASSUME: meaning, NM is gracefully taking over - SYS_IFACE_STATE_MANAGED: meaning, the device is managed by NM - SYS_IFACE_STATE_REMOVED: the device no longer exists This replaces most checks of nm_device_state_reason_check() and nm_active_connection_get_activation_type() by instead looking at the sys-iface-state of the device. This patch probably has still issues, but the previous behavior was not very clear either. We will need to identify those issues in future tests and tweak the behavior. At least, now there is one flag that describes how to behave.
2017-03-13 15:34:14 +01:00
NM_DEVICE_SYS_IFACE_STATE_REMOVED,
} NMDeviceSysIfaceState;
typedef enum {
NM_DEVICE_MTU_SOURCE_NONE,
NM_DEVICE_MTU_SOURCE_PARENT,
NM_DEVICE_MTU_SOURCE_IP_CONFIG,
NM_DEVICE_MTU_SOURCE_CONNECTION,
} NMDeviceMtuSource;
static inline NMDeviceStateReason
nm_device_state_reason_check (NMDeviceStateReason reason)
{
/* the device-state-reason serves mostly informational purpse during a state
* change. In some cases however, decisions are made based on the reason.
* I tend to think that interpreting the state reason to derive some behaviors
* is confusing, because the cause and effect are so far apart.
*
* This function is here to mark source that inspects the reason to make
* a decision -- contrary to places that set the reason. Thus, by grepping
* for nm_device_state_reason_check() you can find the "effect" to a certain
* reason.
*/
return reason;
}
#define NM_PENDING_ACTION_AUTOACTIVATE "autoactivate"
#define NM_PENDING_ACTION_DHCP4 "dhcp4"
#define NM_PENDING_ACTION_DHCP6 "dhcp6"
#define NM_PENDING_ACTION_AUTOCONF6 "autoconf6"
#define NM_PENDING_ACTION_RECHECK_AVAILABLE "recheck-available"
#define NM_PENDING_ACTION_CARRIER_WAIT "carrier-wait"
#define NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT "waiting-for-supplicant"
#define NM_PENDING_ACTION_WIFI_SCAN "wifi-scan"
#define NM_PENDING_ACTION_WAITING_FOR_COMPANION "waiting-for-companion"
#define NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "queued-state-change-"
#define NM_PENDING_ACTIONPREFIX_ACTIVATION "activation-"
/* Properties */
#define NM_DEVICE_UDI "udi"
#define NM_DEVICE_IFACE "interface"
#define NM_DEVICE_IP_IFACE "ip-interface"
#define NM_DEVICE_DRIVER "driver"
#define NM_DEVICE_DRIVER_VERSION "driver-version"
#define NM_DEVICE_FIRMWARE_VERSION "firmware-version"
#define NM_DEVICE_CAPABILITIES "capabilities"
#define NM_DEVICE_CARRIER "carrier"
#define NM_DEVICE_IP4_ADDRESS "ip4-address"
#define NM_DEVICE_IP4_CONFIG "ip4-config"
#define NM_DEVICE_DHCP4_CONFIG "dhcp4-config"
#define NM_DEVICE_IP6_CONFIG "ip6-config"
#define NM_DEVICE_DHCP6_CONFIG "dhcp6-config"
#define NM_DEVICE_STATE "state"
#define NM_DEVICE_STATE_REASON "state-reason"
#define NM_DEVICE_ACTIVE_CONNECTION "active-connection"
#define NM_DEVICE_DEVICE_TYPE "device-type" /* ugh */
#define NM_DEVICE_LINK_TYPE "link-type"
#define NM_DEVICE_MANAGED "managed"
#define NM_DEVICE_AUTOCONNECT "autoconnect"
#define NM_DEVICE_FIRMWARE_MISSING "firmware-missing"
#define NM_DEVICE_NM_PLUGIN_MISSING "nm-plugin-missing"
#define NM_DEVICE_AVAILABLE_CONNECTIONS "available-connections"
#define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id"
2013-12-16 15:16:43 +01:00
#define NM_DEVICE_MTU "mtu"
#define NM_DEVICE_HW_ADDRESS "hw-address"
/* "perm-hw-address" is exposed on D-Bus both for NMDeviceEthernet
* and NMDeviceWifi. */
#define NM_DEVICE_PERM_HW_ADDRESS "perm-hw-address"
#define NM_DEVICE_METERED "metered"
#define NM_DEVICE_LLDP_NEIGHBORS "lldp-neighbors"
#define NM_DEVICE_REAL "real"
/* "parent" is exposed on D-Bus by subclasses like NMDeviceIPTunnel */
#define NM_DEVICE_PARENT "parent"
/* the "slaves" property is internal in the parent class, but exposed
* by the derived classes NMDeviceBond, NMDeviceBridge, NMDeviceTeam,
* NMDeviceOvsBridge and NMDeviceOvsPort. */
#define NM_DEVICE_SLAVES "slaves" /* partially internal */
#define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */
#define NM_DEVICE_RFKILL_TYPE "rfkill-type" /* Internal only */
#define NM_DEVICE_IFINDEX "ifindex" /* Internal only */
#define NM_DEVICE_MASTER "master" /* Internal only */
#define NM_DEVICE_HAS_PENDING_ACTION "has-pending-action" /* Internal only */
/* Internal signals */
#define NM_DEVICE_AUTH_REQUEST "auth-request"
#define NM_DEVICE_IP4_CONFIG_CHANGED "ip4-config-changed"
#define NM_DEVICE_IP6_CONFIG_CHANGED "ip6-config-changed"
#define NM_DEVICE_IP6_PREFIX_DELEGATED "ip6-prefix-delegated"
#define NM_DEVICE_IP6_SUBNET_NEEDED "ip6-subnet-needed"
#define NM_DEVICE_REMOVED "removed"
#define NM_DEVICE_RECHECK_AUTO_ACTIVATE "recheck-auto-activate"
#define NM_DEVICE_RECHECK_ASSUME "recheck-assume"
#define NM_DEVICE_STATE_CHANGED "state-changed"
#define NM_DEVICE_LINK_INITIALIZED "link-initialized"
2016-09-12 12:29:34 +02:00
#define NM_DEVICE_AUTOCONNECT_ALLOWED "autoconnect-allowed"
#define NM_DEVICE_CONNECTIVITY_CHANGED "connectivity-changed"
#define NM_DEVICE_STATISTICS_REFRESH_RATE_MS "refresh-rate-ms"
#define NM_DEVICE_STATISTICS_TX_BYTES "tx-bytes"
#define NM_DEVICE_STATISTICS_RX_BYTES "rx-bytes"
#define NM_DEVICE_CONNECTIVITY "connectivity"
#define NM_TYPE_DEVICE (nm_device_get_type ())
#define NM_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE, NMDevice))
#define NM_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE, NMDeviceClass))
#define NM_IS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE))
#define NM_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE))
#define NM_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE, NMDeviceClass))
typedef enum NMActStageReturn NMActStageReturn;
/* These flags affect whether a connection is considered available on a device
* (check_connection_available()). The flags should have the meaning of relaxing
* a condition, so that adding a flag might make a connection available that would
* not be available otherwise. Adding a flag should never make a connection
* not available if it would be available otherwise. */
typedef enum { /*< skip >*/
NM_DEVICE_CHECK_CON_AVAILABLE_NONE = 0,
_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST = (1L << 0),
_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER = (1L << 1),
_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP = (1L << 2),
NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST = _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST
| _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER
| _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP,
NM_DEVICE_CHECK_CON_AVAILABLE_ALL = (1L << 3) - 1,
} NMDeviceCheckConAvailableFlags;
struct _NMDevicePrivate;
struct _NMDevice {
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API Previously, we used the generated GDBusInterfaceSkeleton types and glued them via the NMExportedObject base class to our NM types. We also used GDBusObjectManagerServer. Don't do that anymore. The resulting code was more complicated despite (or because?) using generated classes. It was hard to understand, complex, had ordering-issues, and had a runtime and memory overhead. This patch refactors this entirely and uses the lower layer API GDBusConnection directly. It replaces the generated code, GDBusInterfaceSkeleton, and GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager and static descriptor instances of type GDBusInterfaceInfo. This adds a net plus of more then 1300 lines of hand written code. I claim that this implementation is easier to understand. Note that previously we also required extensive and complex glue code to bind our objects to the generated skeleton objects. Instead, now glue our objects directly to GDBusConnection. The result is more immediate and gets rid of layers of code in between. Now that the D-Bus glue us more under our control, we can address issus and bottlenecks better, instead of adding code to bend the generated skeletons to our needs. Note that the current implementation now only supports one D-Bus connection. That was effectively the case already, although there were places (and still are) where the code pretends it could also support connections from a private socket. We dropped private socket support mainly because it was unused, untested and buggy, but also because GDBusObjectManagerServer could not export the same objects on multiple connections. Now, it would be rather straight forward to fix that and re-introduce ObjectManager on each private connection. But this commit doesn't do that yet, and the new code intentionally supports only one D-Bus connection. Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start() succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough for the moment. It could be easily extended later, for example with polling whether the system bus appears (like was done previously). Also, restart of D-Bus daemon isn't supported either -- just like before. Note how NMDBusManager now implements the ObjectManager D-Bus interface directly. Also, this fixes race issues in the server, by no longer delaying PropertiesChanged signals. NMExportedObject would collect changed properties and send the signal out in idle_emit_properties_changed() on idle. This messes up the ordering of change events w.r.t. other signals and events on the bus. Note that not only NMExportedObject messed up the ordering. Also the generated code would hook into notify() and process change events in and idle handle, exhibiting the same ordering issue too. No longer do that. PropertiesChanged signals will be sent right away by hooking into dispatch_properties_changed(). This means, changing a property in quick succession will no longer be combined and is guaranteed to emit signals for each individual state. Quite possibly we emit now more PropertiesChanged signals then before. However, we are now able to group a set of changes by using standard g_object_freeze_notify()/g_object_thaw_notify(). We probably should make more use of that. Also, now that our signals are all handled in the right order, we might find places where we still emit them in the wrong order. But that is then due to the order in which our GObjects emit signals, not due to an ill behavior of the D-Bus glue. Possibly we need to identify such ordering issues and fix them. Numbers (for contrib/rpm --without debug on x86_64): - the patch changes the code size of NetworkManager by - 2809360 bytes + 2537528 bytes (-9.7%) - Runtime measurements are harder because there is a large variance during testing. In other words, the numbers are not reproducible. Currently, the implementation performs no caching of GVariants at all, but it would be rather simple to add it, if that turns out to be useful. Anyway, without strong claim, it seems that the new form tends to perform slightly better. That would be no surprise. $ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done) - real 1m39.355s + real 1m37.432s $ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done) - real 0m26.843s + real 0m25.281s - Regarding RSS size, just looking at the processes in similar conditions, doesn't give a large difference. On my system they consume about 19MB RSS. It seems that the new version has a slightly smaller RSS size. - 19356 RSS + 18660 RSS
2018-02-26 13:51:52 +01:00
NMDBusObject parent;
2016-09-05 16:55:07 +02:00
struct _NMDevicePrivate *_priv;
core: track devices in manager via embedded CList Instead of using a GSList for tracking the devices, use a CList. I think a CList is in most cases the more suitable data structure then GSList: - you can find out in O(1) whether the object is linked. That is nice, for example to assert in NMDevice's destructor that the object was unlinked, and we will use that later in nm_manager_get_device_by_path(). - you can unlink the element in O(1) and you can unlink the element without having access to the link's head - Contrary to GSList, this does not require an extra slice allocation for the link node. It quite possibliy consumes slightly less memory because the CList structure is embedded in a struct that we already allocate. Even if slice allocation would be perfect to only consume 2*sizeof(gpointer) for the link note, it would at most be as-good as CList. Quite possibly, there is an overhead though. - CList possibly has better memory locality, because the link structure and the data are close to each other. Something which could be seen as disavantage, is that with CList one device can only be tracked in one NMManager instance at a time. But that is fine. There exists only one NMManager instance for now, and even if we would ever introduce multiple managers, we probably would not associate one NMDevice instance with multiple managers. The advantages are arguably not huge, but CList is IMHO clearly the more suited data structure. No need to stick to a suboptimal data structure for the job. Refactor it.
2018-03-23 21:51:07 +01:00
CList devices_lst;
};
/* The flags have an relaxing meaning, that means, specifying more flags, can make
* a device appear more available. It can never make a device less available. */
typedef enum { /*< skip >*/
NM_DEVICE_CHECK_DEV_AVAILABLE_NONE = 0,
_NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER = (1L << 0),
NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST = _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER,
NM_DEVICE_CHECK_DEV_AVAILABLE_ALL = (1L << 1) - 1,
} NMDeviceCheckDevAvailableFlags;
typedef struct _NMDeviceClass {
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API Previously, we used the generated GDBusInterfaceSkeleton types and glued them via the NMExportedObject base class to our NM types. We also used GDBusObjectManagerServer. Don't do that anymore. The resulting code was more complicated despite (or because?) using generated classes. It was hard to understand, complex, had ordering-issues, and had a runtime and memory overhead. This patch refactors this entirely and uses the lower layer API GDBusConnection directly. It replaces the generated code, GDBusInterfaceSkeleton, and GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager and static descriptor instances of type GDBusInterfaceInfo. This adds a net plus of more then 1300 lines of hand written code. I claim that this implementation is easier to understand. Note that previously we also required extensive and complex glue code to bind our objects to the generated skeleton objects. Instead, now glue our objects directly to GDBusConnection. The result is more immediate and gets rid of layers of code in between. Now that the D-Bus glue us more under our control, we can address issus and bottlenecks better, instead of adding code to bend the generated skeletons to our needs. Note that the current implementation now only supports one D-Bus connection. That was effectively the case already, although there were places (and still are) where the code pretends it could also support connections from a private socket. We dropped private socket support mainly because it was unused, untested and buggy, but also because GDBusObjectManagerServer could not export the same objects on multiple connections. Now, it would be rather straight forward to fix that and re-introduce ObjectManager on each private connection. But this commit doesn't do that yet, and the new code intentionally supports only one D-Bus connection. Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start() succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough for the moment. It could be easily extended later, for example with polling whether the system bus appears (like was done previously). Also, restart of D-Bus daemon isn't supported either -- just like before. Note how NMDBusManager now implements the ObjectManager D-Bus interface directly. Also, this fixes race issues in the server, by no longer delaying PropertiesChanged signals. NMExportedObject would collect changed properties and send the signal out in idle_emit_properties_changed() on idle. This messes up the ordering of change events w.r.t. other signals and events on the bus. Note that not only NMExportedObject messed up the ordering. Also the generated code would hook into notify() and process change events in and idle handle, exhibiting the same ordering issue too. No longer do that. PropertiesChanged signals will be sent right away by hooking into dispatch_properties_changed(). This means, changing a property in quick succession will no longer be combined and is guaranteed to emit signals for each individual state. Quite possibly we emit now more PropertiesChanged signals then before. However, we are now able to group a set of changes by using standard g_object_freeze_notify()/g_object_thaw_notify(). We probably should make more use of that. Also, now that our signals are all handled in the right order, we might find places where we still emit them in the wrong order. But that is then due to the order in which our GObjects emit signals, not due to an ill behavior of the D-Bus glue. Possibly we need to identify such ordering issues and fix them. Numbers (for contrib/rpm --without debug on x86_64): - the patch changes the code size of NetworkManager by - 2809360 bytes + 2537528 bytes (-9.7%) - Runtime measurements are harder because there is a large variance during testing. In other words, the numbers are not reproducible. Currently, the implementation performs no caching of GVariants at all, but it would be rather simple to add it, if that turns out to be useful. Anyway, without strong claim, it seems that the new form tends to perform slightly better. That would be no surprise. $ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done) - real 1m39.355s + real 1m37.432s $ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done) - real 0m26.843s + real 0m25.281s - Regarding RSS size, just looking at the processes in similar conditions, doesn't give a large difference. On my system they consume about 19MB RSS. It seems that the new version has a slightly smaller RSS size. - 19356 RSS + 18660 RSS
2018-02-26 13:51:52 +01:00
NMDBusObjectClass parent;
struct _NMDeviceClass *default_type_description_klass;
const char *default_type_description;
const char *connection_type_supported;
/* most device types, can only handle profiles of a particular type. This
* is the connection.type setting, as checked by nm_device_check_connection_compatible() */
const char *connection_type_check_compatible;
const NMLinkType *link_types;
/* Whether the device type is a master-type. This depends purely on the
* type (NMDeviceClass), not the actual device instance. */
bool is_master:1;
void (*state_changed) (NMDevice *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason);
void (* link_changed) (NMDevice *self,
const NMPlatformLink *pllink);
/**
* create_and_realize():
* @self: the #NMDevice
* @connection: the #NMConnection being activated
* @parent: the parent #NMDevice, if any
* @out_plink: on success, a backing kernel network device if one exists.
* The returned pointer is owned by platform and only valid until the
* next platform operation.
* @error: location to store error, or %NULL
*
* Create any backing resources (kernel devices, etc) required for this
* device to activate @connection. If the device is backed by a kernel
* network device, that device should be returned in @out_plink after
* being created.
*
* Returns: %TRUE on success, %FALSE on error
*/
gboolean (*create_and_realize) (NMDevice *self,
NMConnection *connection,
NMDevice *parent,
const NMPlatformLink **out_plink,
GError **error);
/**
* realize_start_notify():
* @self: the #NMDevice
* @pllink: the #NMPlatformLink if backed by a kernel netdevice
*
* Hook for derived classes to be notfied during realize_start_setup()
* and perform additional setup.
*
* The default implemention of NMDevice calls link_changed().
*/
void (*realize_start_notify) (NMDevice *self,
const NMPlatformLink *pllink);
/**
* unrealize():
* @self: the #NMDevice
*
* Remove the device backing resources.
*/
gboolean (*unrealize) (NMDevice *self, GError **error);
/**
* unrealize_notify():
* @self: the #NMDevice
*
* Hook for derived classes to clear any properties that depend on backing resources
* (kernel devices, etc). This is called by nm_device_unrealize() during unrealization.
*/
void (*unrealize_notify) (NMDevice *self);
/* Hardware state (IFF_UP) */
gboolean (*can_unmanaged_external_down) (NMDevice *self);
2008-04-28 Dan Williams <dcbw@redhat.com> Fix the device up/down ambiguities. Up/down state used to be a conglomeration of hardware state (IFF_UP) and any device-specific things (supplicant, periodic timers, etc) that the device used to indicate readiness. Unfortunately, if the hardware was already IFF_UP for some reason, then the device specific stuff wouldn't get run, and the device would be stuck. * src/nm-device.c src/nm-device.h - Create hw_is_up, hw_bring_up, and hw_take_down - Rename bring_down -> take_down - (real_hw_is_up): check interface flags for IFF_UP - (nm_device_hw_is_up): let subclasses figure out their own HW state - (nm_device_is_up): make static; only used locally - (nm_device_hw_bring_up): update the hardware and IPv4 addresses even if the device is already up; if the device isn't up, bring it up - (nm_device_hw_take_down): just take down hardware - (nm_device_bring_up): bring up HW first, then device specific stuff - (nm_device_take_down): always deactivate device when called; always try to take hardware down too - (nm_device_state_changed): take device down when entering unmanaged state from a higher state * src/nm-device-802-11-wireless.c - (real_hw_is_up, real_hw_bring_up, real_hw_take_down): implement; just check IFF_UP really - (real_take_down, supplicant_iface_state_cb_handler, supplicant_iface_connection_state_cb_handler, supplicant_mgr_state_cb_handler): fix some messages * src/nm-device-802-3-ethernet.c - (real_hw_is_up, real_hw_bring_up, real_hw_take_down): implement; just check IFF_UP really git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3618 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-29 15:36:29 +00:00
/* Carrier state (IFF_LOWER_UP) */
void (*carrier_changed_notify) (NMDevice *, gboolean carrier);
gboolean (* get_ip_iface_identifier) (NMDevice *self, NMUtilsIPv6IfaceId *out_iid);
NMDeviceCapabilities (* get_generic_capabilities) (NMDevice *self);
gboolean (* is_available) (NMDevice *self, NMDeviceCheckDevAvailableFlags flags);
2008-03-07 Dan Williams <dcbw@redhat.com> First pass of multiple active device support. Expect bugs. * src/nm-ip4-config.c src/nm-ip4-config.h - (nm_ip4_config_get_secondary, nm_ip4_config_set_secondary): remove; there are better ways to do this in the named manager * src/nm-device.c src/nm-device.h - (nm_device_can_activate): return whether the device can activate a connection right now; taking into account things like carrier state and rfkill state - (nm_device_get_best_auto_connection): renamed from nm_device_get_best_connection - (real_act_stage4_get_ip4_config): MTU stuff is now handled in the device subclasses themselves, so that each device can override the MTU from it's NMSetting subclass if needed - (nm_device_set_ip4_config): set MTU when setting up routes and stuff in NetworkManagerSystem.c, not here * src/named-manager/nm-named-manager.c src/named-manager/nm-named-manager.h - (nm_named_manager_name_owner_changed, nm_named_manager_dbus_connection_changed): fix for changes to rewrite_resolv_conf() - (compute_nameservers): don't need the NMNamedManager at all, remove from parameter list - (merge_one_ip4_config): new function; merge ip4 configs together - (rewrite_resolv_conf): write out resolv.conf from all the stored ip4 configs; the VPN config takes precedence, then the best device config, then the rest of the configs - (get_domain_for_config): take the NMNamedManager as an argument to check whether the config is the VPN config - (add_ip4_config_to_named): fixups for removal of the 'secondary' attribute from ip4 configs - (add_all_ip4_configs_to_named): add all the configs in priority order - (remove_ip4_config_from_named): fix for changes to get_domain_for_config() - (nm_named_manager_add_ip4_config): assign the config to the right slot based on its type; callers must pass in the type now - (get_last_default_domain): remove, unused - (nm_named_manager_remove_ip4_config): handle config slots correctly * src/nm-device-802-11-wireless.c - (real_can_activate): new function - (real_get_best_auto_connection): renamed from real_get_best_connection - (real_act_stage4_get_ip4_config): handle MTU override * src/nm-device-802-3-ethernet.c - (real_can_activate): new function - (real_get_best_auto_connection): renamed from real_get_best_connection - (real_act_stage4_get_ip4_config): new function; handle MTU override * src/vpn-manager/nm-vpn-connection.c - (nm_vpn_connection_ip4_config_get): don't need to set the 'secondary' attribute on the ip4 config * src/NetworkManagerPolicy.c - (nm_policy_auto_get_best_device): remove - (nm_policy_device_change_check): remove - (update_default_route): new function; set the default route via the specified device - (get_device_priority): new function; return the priority number of a device type WRT which one should have the default route. Order is (highest to lowest) wired, wireless, GSM, CDMA. - (update_routing_and_dns): new function; determine which device should have the default route, then update the routing table and DNS - (maybe_auto_activate_device): new function; if a device is now available for activation, find out what connection it would like to activate and do it - (schedule_activate_check): new function; if a device can be activated now, schedule the activation. Each device may have only one pending activation at a given time. - (device_state_changed): if activation was canceled, try again, possibly with another connection; if the device was activated, update routing and DNS; if the device was deactivated, try again with another connection - (device_carrier_changed): if there is no carrier, deactivate the device; otherwise schedule an activation check for the device - (wireless_networks_changed): schedule an activation check for the device - (device_added): keep track of the signal handler IDs so they can be removed when the device goes away - (device_removed): remove any signal handlers that might be attached to the device; update routing and DNS - (schedule_activate_all): new function - (connections_added, connection_added, connection_updated): when connections change, schedule all devices for an activation check - (connection_removed): when a device is deactivated because its connection was removed, schedule another activation check for it - (nm_policy_destroy): destroy pending activations and disconnect all device signal handlers * src/nm-manager.c - (nm_manager_activate_device): if the device was already actived, deactivate it - (deactivate_old_device): remove - (connection_added_default_handler, impl_manager_activate_device): don't deactivate other devices when activating this one * src/backends/NetworkManagerGentoo.c src/backends/NetworkManagerFrugalware.c src/backends/NetworkManagerPaldo.c src/backends/NetworkManagerRedHat.c src/backends/NetworkManagerSlackware.c src/backends/NetworkManagerArch.c src/backends/NetworkManagerSuSE.c src/backends/NetworkManagerDebian.c - (nm_system_get_mtu): remove; MTU should be provided through the distro's system settings service plugin instead - (nm_system_device_add_default_route_via_device): remove - (nm_system_device_add_default_route_via_device_with_iface): remove - (nm_system_device_replace_default_route): new function; call generic implementation * src/backends/NetworkManagerGeneric.c src/backends/NetworkManagerGeneric.h - (nm_generic_device_add_default_route_via_device, nm_generic_device_add_default_route_via_device_with_iface): remove - (nm_generic_device_replace_default_route): replace the default route with the given route via some gateway * src/NetworkManagerSystem.c src/NetworkManagerSystem.h - (nm_system_device_set_from_ip4_config): let the policy handle updates to routing and DNS; but set the MTU here - (nm_system_vpn_device_set_from_ip4_config): set the route with the ip_iface of the active device; use the standard MTU setting function - (nm_system_set_mtu): remove - (nm_system_device_set_mtu): consolidate MTU setting code in one place git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3391 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-03-07 19:41:32 +00:00
gboolean (* get_enabled) (NMDevice *self);
void (* set_enabled) (NMDevice *self, gboolean enabled);
/* allow derived classes to override the result of nm_device_autoconnect_allowed().
* If the value changes, the class should call nm_device_emit_recheck_auto_activate(),
* which emits NM_DEVICE_RECHECK_AUTO_ACTIVATE signal. */
gboolean (* get_autoconnect_allowed) (NMDevice *self);
gboolean (* can_auto_connect) (NMDevice *self,
NMConnection *connection,
char **specific_object);
guint32 (*get_configured_mtu) (NMDevice *self, NMDeviceMtuSource *out_source);
/* Checks whether the connection is compatible with the device using
* only the devices type and characteristics. Does not use any live
* network information like WiFi scan lists etc.
*/
gboolean (* check_connection_compatible) (NMDevice *self,
NMConnection *connection,
GError **error);
/* Checks whether the connection is likely available to be activated,
* including any live network information like scan lists. The connection
* is checked against the object defined by @specific_object, if given.
* Returns TRUE if the connection is available; FALSE if not.
*
* The passed @flags affect whether a connection is considered
* available or not. Adding more flags, means the connection is
* *more* available.
*
* Specifying @specific_object can only reduce the availability of a connection.
*/
gboolean (* check_connection_available) (NMDevice *self,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
const char *specific_object,
GError **error);
gboolean (* complete_connection) (NMDevice *self,
NMConnection *connection,
const char *specific_object,
NMConnection *const*existing_connections,
GError **error);
NMActStageReturn (* act_stage1_prepare) (NMDevice *self,
NMDeviceStateReason *out_failure_reason);
NMActStageReturn (* act_stage2_config) (NMDevice *self,
NMDeviceStateReason *out_failure_reason);
NMActStageReturn (* act_stage3_ip4_config_start) (NMDevice *self,
2016-01-11 14:25:22 +01:00
NMIP4Config **out_config,
NMDeviceStateReason *out_failure_reason);
NMActStageReturn (* act_stage3_ip6_config_start) (NMDevice *self,
2016-01-11 14:25:22 +01:00
NMIP6Config **out_config,
NMDeviceStateReason *out_failure_reason);
NMActStageReturn (* act_stage4_ip4_config_timeout) (NMDevice *self,
NMDeviceStateReason *out_failure_reason);
NMActStageReturn (* act_stage4_ip6_config_timeout) (NMDevice *self,
NMDeviceStateReason *out_failure_reason);
void (* ip4_config_pre_commit) (NMDevice *self, NMIP4Config *config);
/* Async deactivating (in the DEACTIVATING phase) */
void (* deactivate_async) (NMDevice *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (* deactivate_async_finish) (NMDevice *self,
GAsyncResult *res,
GError **error);
void (* deactivate_reset_hw_addr) (NMDevice *self);
/* Sync deactivating (in the DISCONNECTED phase) */
void (* deactivate) (NMDevice *self);
const char *(*get_type_description) (NMDevice *self);
const char *(*get_s390_subchannels) (NMDevice *self);
/* Update the connection with currently configured L2 settings */
void (* update_connection) (NMDevice *device, NMConnection *connection);
gboolean (*master_update_slave_connection) (NMDevice *self,
NMDevice *slave,
NMConnection *connection,
GError **error);
gboolean (* enslave_slave) (NMDevice *self,
NMDevice *slave,
NMConnection *connection,
gboolean configure);
void (* release_slave) (NMDevice *self,
NMDevice *slave,
gboolean configure);
void (* parent_changed_notify) (NMDevice *self,
int old_ifindex,
NMDevice *old_parent,
int new_ifindex,
NMDevice *new_parent);
/**
* component_added:
* @self: the #NMDevice
* @component: the component (device, modem, etc) which was added
*
* Notifies @self that a new component that a device might be interested
* in was detected by some device factory. It may include an object of
* %GObject subclass to help the devices decide whether it claims that
* particular object itself and the emitting factory should not.
*
* Returns: %TRUE if the component was claimed exclusively and no further
* devices should be notified of the new component. %FALSE to indicate
* that the component was not exclusively claimed and other devices should
* be notified.
*/
gboolean (* component_added) (NMDevice *self, GObject *component);
gboolean (* owns_iface) (NMDevice *self, const char *iface);
NMConnection * (* new_default_connection) (NMDevice *self);
gboolean (* unmanaged_on_quit) (NMDevice *self);
gboolean (* can_reapply_change) (NMDevice *self,
const char *setting_name,
NMSetting *s_old,
NMSetting *s_new,
GHashTable *diffs,
GError **error);
void (* reapply_connection) (NMDevice *self,
NMConnection *con_old,
NMConnection *con_new);
guint32 (* get_dhcp_timeout) (NMDevice *self,
int addr_family);
2009-07-07 14:34:01 -04:00
} NMDeviceClass;
typedef void (*NMDeviceAuthRequestFunc) (NMDevice *device,
GDBusMethodInvocation *context,
2015-07-14 10:19:19 +02:00
NMAuthSubject *subject,
GError *error,
gpointer user_data);
GType nm_device_get_type (void);
struct _NMDedupMultiIndex *nm_device_get_multi_index (NMDevice *self);
NMNetns *nm_device_get_netns (NMDevice *self);
NMPlatform *nm_device_get_platform (NMDevice *self);
const char * nm_device_get_udi (NMDevice *dev);
const char * nm_device_get_iface (NMDevice *dev);
static inline const char *
_nm_device_get_iface (NMDevice *device)
{
/* like nm_device_get_iface(), but gracefully accept NULL without
* asserting. */
return device ? nm_device_get_iface (device) : NULL;
}
int nm_device_get_ifindex (NMDevice *dev);
gboolean nm_device_is_software (NMDevice *dev);
gboolean nm_device_is_real (NMDevice *dev);
const char * nm_device_get_ip_iface (NMDevice *dev);
int nm_device_get_ip_ifindex (const NMDevice *dev);
const char * nm_device_get_driver (NMDevice *dev);
const char * nm_device_get_driver_version (NMDevice *dev);
const char * nm_device_get_type_desc (NMDevice *dev);
const char * nm_device_get_type_description (NMDevice *dev);
NMDeviceType nm_device_get_device_type (NMDevice *dev);
NMLinkType nm_device_get_link_type (NMDevice *dev);
NMMetered nm_device_get_metered (NMDevice *dev);
guint32 nm_device_get_route_table (NMDevice *self, int addr_family, gboolean fallback_main);
guint32 nm_device_get_route_metric (NMDevice *dev, int addr_family);
guint32 nm_device_get_route_metric_default (NMDeviceType device_type);
const char * nm_device_get_hw_address (NMDevice *dev);
const char * nm_device_get_permanent_hw_address (NMDevice *self);
const char * nm_device_get_permanent_hw_address_full (NMDevice *self,
device: delay capturing permanent MAC address until UDEV is settled The permanent MAC address of an NMDevice shall not change as long as the device is realized. That is, we read it only once and don't change it afterwards. There are two issues that this commit tries to mitigate: (1) users are advised to use UDEV to rename interfaces. As we lookup the permenent MAC address using ethtool (which uses the interface name), there is a race where we could read the permanent MAC address using the wrong interface name. We should wait until UDEV finished initializing the device and until the interface name is stable (see rh#1388286). This commit still cannot avoid the race of ethtool entirely. It only tries to avoid ethtool until UDEV has done its work. That is, until we expect the interface name no longer to change. (2) some device types, don't have a permanent MAC address so we fall back to use the currently set address (fake). Again, users are advised to use UDEV to configure the MAC addresses on such software devices. Thus, we should not get the fake MAC address until UDEV initialized the device. This patch actually doesn't solve the problem at all yet. The reason is that a regular caller of nm_device_get_permanent_hw_address() can not afford to wait until UDEV settled. Thus, any user who requests the permanent MAC address before the link is initialized, runs into the problems above. In a next step, we shall revisit such calls to nm_device_get_permanent_hw_address() and delay them until the link is initialized.
2016-10-24 12:50:17 +02:00
gboolean force_freeze,
gboolean *out_is_fake);
const char * nm_device_get_initial_hw_address (NMDevice *dev);
NMProxyConfig * nm_device_get_proxy_config (NMDevice *dev);
NMDhcp4Config * nm_device_get_dhcp4_config (NMDevice *dev);
NMDhcp6Config * nm_device_get_dhcp6_config (NMDevice *dev);
NMIP4Config * nm_device_get_ip4_config (NMDevice *dev);
void nm_device_replace_vpn4_config (NMDevice *dev,
NMIP4Config *old,
NMIP4Config *config);
NMIP6Config * nm_device_get_ip6_config (NMDevice *dev);
void nm_device_replace_vpn6_config (NMDevice *dev,
NMIP6Config *old,
NMIP6Config *config);
void nm_device_capture_initial_config (NMDevice *dev);
int nm_device_parent_get_ifindex (NMDevice *dev);
NMDevice *nm_device_parent_get_device (NMDevice *dev);
void nm_device_parent_set_ifindex (NMDevice *self,
int parent_ifindex);
gboolean nm_device_parent_notify_changed (NMDevice *self,
NMDevice *change_candidate,
gboolean device_removed);
2012-11-14 14:05:30 -06:00
/* Master */
gboolean nm_device_is_master (NMDevice *dev);
2012-11-14 14:05:30 -06:00
/* Slave */
NMDevice * nm_device_get_master (NMDevice *dev);
NMActRequest * nm_device_get_act_request (NMDevice *dev);
NMSettingsConnection *nm_device_get_settings_connection (NMDevice *dev);
NMConnection * nm_device_get_applied_connection (NMDevice *dev);
gboolean nm_device_has_unmodified_applied_connection (NMDevice *self,
NMSettingCompareFlags compare_flags);
NMSetting * nm_device_get_applied_setting (NMDevice *dev, GType setting_type);
void nm_device_removed (NMDevice *self, gboolean unconfigure_ip_config);
gboolean nm_device_ignore_carrier_by_default (NMDevice *self);
gboolean nm_device_is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags);
gboolean nm_device_has_carrier (NMDevice *dev);
2008-03-07 Dan Williams <dcbw@redhat.com> First pass of multiple active device support. Expect bugs. * src/nm-ip4-config.c src/nm-ip4-config.h - (nm_ip4_config_get_secondary, nm_ip4_config_set_secondary): remove; there are better ways to do this in the named manager * src/nm-device.c src/nm-device.h - (nm_device_can_activate): return whether the device can activate a connection right now; taking into account things like carrier state and rfkill state - (nm_device_get_best_auto_connection): renamed from nm_device_get_best_connection - (real_act_stage4_get_ip4_config): MTU stuff is now handled in the device subclasses themselves, so that each device can override the MTU from it's NMSetting subclass if needed - (nm_device_set_ip4_config): set MTU when setting up routes and stuff in NetworkManagerSystem.c, not here * src/named-manager/nm-named-manager.c src/named-manager/nm-named-manager.h - (nm_named_manager_name_owner_changed, nm_named_manager_dbus_connection_changed): fix for changes to rewrite_resolv_conf() - (compute_nameservers): don't need the NMNamedManager at all, remove from parameter list - (merge_one_ip4_config): new function; merge ip4 configs together - (rewrite_resolv_conf): write out resolv.conf from all the stored ip4 configs; the VPN config takes precedence, then the best device config, then the rest of the configs - (get_domain_for_config): take the NMNamedManager as an argument to check whether the config is the VPN config - (add_ip4_config_to_named): fixups for removal of the 'secondary' attribute from ip4 configs - (add_all_ip4_configs_to_named): add all the configs in priority order - (remove_ip4_config_from_named): fix for changes to get_domain_for_config() - (nm_named_manager_add_ip4_config): assign the config to the right slot based on its type; callers must pass in the type now - (get_last_default_domain): remove, unused - (nm_named_manager_remove_ip4_config): handle config slots correctly * src/nm-device-802-11-wireless.c - (real_can_activate): new function - (real_get_best_auto_connection): renamed from real_get_best_connection - (real_act_stage4_get_ip4_config): handle MTU override * src/nm-device-802-3-ethernet.c - (real_can_activate): new function - (real_get_best_auto_connection): renamed from real_get_best_connection - (real_act_stage4_get_ip4_config): new function; handle MTU override * src/vpn-manager/nm-vpn-connection.c - (nm_vpn_connection_ip4_config_get): don't need to set the 'secondary' attribute on the ip4 config * src/NetworkManagerPolicy.c - (nm_policy_auto_get_best_device): remove - (nm_policy_device_change_check): remove - (update_default_route): new function; set the default route via the specified device - (get_device_priority): new function; return the priority number of a device type WRT which one should have the default route. Order is (highest to lowest) wired, wireless, GSM, CDMA. - (update_routing_and_dns): new function; determine which device should have the default route, then update the routing table and DNS - (maybe_auto_activate_device): new function; if a device is now available for activation, find out what connection it would like to activate and do it - (schedule_activate_check): new function; if a device can be activated now, schedule the activation. Each device may have only one pending activation at a given time. - (device_state_changed): if activation was canceled, try again, possibly with another connection; if the device was activated, update routing and DNS; if the device was deactivated, try again with another connection - (device_carrier_changed): if there is no carrier, deactivate the device; otherwise schedule an activation check for the device - (wireless_networks_changed): schedule an activation check for the device - (device_added): keep track of the signal handler IDs so they can be removed when the device goes away - (device_removed): remove any signal handlers that might be attached to the device; update routing and DNS - (schedule_activate_all): new function - (connections_added, connection_added, connection_updated): when connections change, schedule all devices for an activation check - (connection_removed): when a device is deactivated because its connection was removed, schedule another activation check for it - (nm_policy_destroy): destroy pending activations and disconnect all device signal handlers * src/nm-manager.c - (nm_manager_activate_device): if the device was already actived, deactivate it - (deactivate_old_device): remove - (connection_added_default_handler, impl_manager_activate_device): don't deactivate other devices when activating this one * src/backends/NetworkManagerGentoo.c src/backends/NetworkManagerFrugalware.c src/backends/NetworkManagerPaldo.c src/backends/NetworkManagerRedHat.c src/backends/NetworkManagerSlackware.c src/backends/NetworkManagerArch.c src/backends/NetworkManagerSuSE.c src/backends/NetworkManagerDebian.c - (nm_system_get_mtu): remove; MTU should be provided through the distro's system settings service plugin instead - (nm_system_device_add_default_route_via_device): remove - (nm_system_device_add_default_route_via_device_with_iface): remove - (nm_system_device_replace_default_route): new function; call generic implementation * src/backends/NetworkManagerGeneric.c src/backends/NetworkManagerGeneric.h - (nm_generic_device_add_default_route_via_device, nm_generic_device_add_default_route_via_device_with_iface): remove - (nm_generic_device_replace_default_route): replace the default route with the given route via some gateway * src/NetworkManagerSystem.c src/NetworkManagerSystem.h - (nm_system_device_set_from_ip4_config): let the policy handle updates to routing and DNS; but set the MTU here - (nm_system_vpn_device_set_from_ip4_config): set the route with the ip_iface of the active device; use the standard MTU setting function - (nm_system_set_mtu): remove - (nm_system_device_set_mtu): consolidate MTU setting code in one place git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3391 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-03-07 19:41:32 +00:00
manager: fix preserving assume state during activation Originally 850c977 "device: track system interface state in NMDevice", intended that a connection can only be assumed initially when seeing a device for the first time. Assuming a connection later was to be prevented by setting device's sys-iface-state to MANAGED. That changed too much in behavior, because we used to assume external connections also when they are activated later on. So this was attempted to get fixed by - acf1067 nm-manager: try assuming connections on managed devices - b6b7d90 manager: avoid generating in memory connections during startup for managed devices It's probably just wrong to prevent assuming connections based on the sys-iface-state. So drop the check for sys-iface-state from recheck_assume_connection(). Now, we can assume anytime on managed, disconnected interfaces, like previously. Btw, note that priv->startup is totally wrong to check there, because priv->startup has the sole purpose of tracking startup-complete property. Startup, as far as NMManager is concerned, is platform_query_devices(). However, the problem is that we only assume connections (contrary to doing external activation) when we have a connection-uuid from the state file or with guess-assume during startup. When assuming a master device, it can fail with (nm-bond): ignoring generated connection (IPv6LL-only and not in master-slave relationship) thus, for internal reason the device cannot be assumed yet. Fix that by attatching the assume-state to the device, so that on multiple recheck_assume_connection() calls we still try to assume. Whenever we try to assume the connection and it fails due to external reasons (like, the connection no longer matching), we clear the assume state, so that we only try as long as there are internal reasons why assuming fails. https://bugzilla.redhat.com/show_bug.cgi?id=1452062
2017-06-07 17:34:47 +02:00
NMConnection * nm_device_generate_connection (NMDevice *self,
NMDevice *master,
gboolean *out_maybe_later,
GError **error);
gboolean nm_device_master_update_slave_connection (NMDevice *master,
NMDevice *slave,
NMConnection *connection,
GError **error);
gboolean nm_device_can_auto_connect (NMDevice *self,
NMConnection *connection,
char **specific_object);
gboolean nm_device_complete_connection (NMDevice *device,
NMConnection *connection,
const char *specific_object,
NMConnection *const*existing_connections,
GError **error);
gboolean nm_device_check_connection_compatible (NMDevice *device,
NMConnection *connection,
GError **error);
gboolean nm_device_check_slave_connection_compatible (NMDevice *device, NMConnection *connection);
gboolean nm_device_unmanage_on_quit (NMDevice *self);
gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs);
int nm_device_spec_match_list_full (NMDevice *self, const GSList *specs, int no_match_value);
gboolean nm_device_is_activating (NMDevice *dev);
gboolean nm_device_autoconnect_allowed (NMDevice *self);
NMDeviceState nm_device_get_state (NMDevice *device);
gboolean nm_device_get_enabled (NMDevice *device);
void nm_device_set_enabled (NMDevice *device, gboolean enabled);
RfKillType nm_device_get_rfkill_type (NMDevice *device);
/* IPv6 prefix delegation */
void nm_device_request_ip6_prefixes (NMDevice *self, int needed_prefixes);
gboolean nm_device_needs_ip6_subnet (NMDevice *self);
void nm_device_use_ip6_subnet (NMDevice *self, const NMPlatformIP6Address *subnet);
void nm_device_copy_ip6_dns_config (NMDevice *self, NMDevice *from_device);
/**
* NMUnmanagedFlags:
* @NM_UNMANAGED_NONE: placeholder value
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_UNMANAGED_SLEEPING: %TRUE when unmanaged because NM is sleeping.
* @NM_UNMANAGED_QUITTING: %TRUE when unmanaged because NM is shutting down.
* @NM_UNMANAGED_PARENT: %TRUE when unmanaged due to parent device being unmanaged
* @NM_UNMANAGED_LOOPBACK: %TRUE for unmanaging loopback device
* @NM_UNMANAGED_PLATFORM_INIT: %TRUE when unmanaged because platform link not
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
* yet initialized. Unrealized device are also unmanaged for this reason.
* @NM_UNMANAGED_USER_EXPLICIT: %TRUE when unmanaged by explicit user decision
* (e.g. via a D-Bus command)
* @NM_UNMANAGED_USER_SETTINGS: %TRUE when unmanaged by user decision via
* the settings plugin (for example keyfile.unmanaged-devices or ifcfg-rh's
* NM_CONTROLLED=no). Although this is user-configuration (provided from
* the settings plugins, such as NM_CONTROLLED=no in ifcfg-rh), it cannot
* be overruled and is authorative. That is because users may depend on
* dropping a ifcfg-rh file to ensure the device is unmanaged.
* @NM_UNMANAGED_USER_CONF: %TRUE when unmanaged by user decision via
* the NetworkManager.conf ("unmanaged" in the [device] section).
* Contray to @NM_UNMANAGED_USER_SETTINGS, this can be overwritten via
* D-Bus.
* @NM_UNMANAGED_BY_DEFAULT: %TRUE for certain device types where we unmanage
* them by default
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_UNMANAGED_USER_UDEV: %TRUE when unmanaged by user decision (via UDev rule)
* @NM_UNMANAGED_EXTERNAL_DOWN: %TRUE when unmanaged because !IFF_UP and not created by NM
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_UNMANAGED_IS_SLAVE: indicates that the device is enslaved. Note that
* setting the NM_UNMANAGED_IS_SLAVE to %TRUE makes no sense, this flag has only
* meaning to set a slave device as managed if the parent is managed too.
*/
typedef enum { /*< skip >*/
NM_UNMANAGED_NONE = 0,
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
/* these flags are authorative. If one of them is set,
* the device cannot be managed. */
NM_UNMANAGED_SLEEPING = (1LL << 0),
NM_UNMANAGED_QUITTING = (1LL << 1),
NM_UNMANAGED_PARENT = (1LL << 2),
NM_UNMANAGED_LOOPBACK = (1LL << 3),
NM_UNMANAGED_PLATFORM_INIT = (1LL << 4),
NM_UNMANAGED_USER_EXPLICIT = (1LL << 5),
NM_UNMANAGED_USER_SETTINGS = (1LL << 6),
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
/* These flags can be non-effective and be overwritten
* by other flags. */
NM_UNMANAGED_BY_DEFAULT = (1LL << 8),
NM_UNMANAGED_USER_CONF = (1LL << 9),
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_UNMANAGED_USER_UDEV = (1LL << 10),
NM_UNMANAGED_EXTERNAL_DOWN = (1LL << 11),
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_UNMANAGED_IS_SLAVE = (1LL << 12),
} NMUnmanagedFlags;
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
typedef enum {
NM_UNMAN_FLAG_OP_SET_MANAGED = FALSE,
NM_UNMAN_FLAG_OP_SET_UNMANAGED = TRUE,
NM_UNMAN_FLAG_OP_FORGET = 2,
} NMUnmanFlagOp;
const char *nm_unmanaged_flags2str (NMUnmanagedFlags flags, char *buf, gsize len);
gboolean nm_device_get_managed (NMDevice *device, gboolean for_user_request);
NMUnmanagedFlags nm_device_get_unmanaged_mask (NMDevice *device, NMUnmanagedFlags flag);
NMUnmanagedFlags nm_device_get_unmanaged_flags (NMDevice *device, NMUnmanagedFlags flag);
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
void nm_device_set_unmanaged_flags (NMDevice *device,
NMUnmanagedFlags flags,
NMUnmanFlagOp set_op);
void nm_device_set_unmanaged_by_flags (NMDevice *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
NMUnmanagedFlags flags,
NMUnmanFlagOp set_op,
NMDeviceStateReason reason);
void nm_device_set_unmanaged_by_flags_queue (NMDevice *self,
NMUnmanagedFlags flags,
NMUnmanFlagOp set_op,
NMDeviceStateReason reason);
void nm_device_set_unmanaged_by_user_settings (NMDevice *self);
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
void nm_device_set_unmanaged_by_user_udev (NMDevice *self);
void nm_device_set_unmanaged_by_user_conf (NMDevice *self);
void nm_device_set_unmanaged_by_quitting (NMDevice *device);
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
gboolean nm_device_is_nm_owned (NMDevice *device);
gboolean nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps);
manager: fix preserving assume state during activation Originally 850c977 "device: track system interface state in NMDevice", intended that a connection can only be assumed initially when seeing a device for the first time. Assuming a connection later was to be prevented by setting device's sys-iface-state to MANAGED. That changed too much in behavior, because we used to assume external connections also when they are activated later on. So this was attempted to get fixed by - acf1067 nm-manager: try assuming connections on managed devices - b6b7d90 manager: avoid generating in memory connections during startup for managed devices It's probably just wrong to prevent assuming connections based on the sys-iface-state. So drop the check for sys-iface-state from recheck_assume_connection(). Now, we can assume anytime on managed, disconnected interfaces, like previously. Btw, note that priv->startup is totally wrong to check there, because priv->startup has the sole purpose of tracking startup-complete property. Startup, as far as NMManager is concerned, is platform_query_devices(). However, the problem is that we only assume connections (contrary to doing external activation) when we have a connection-uuid from the state file or with guess-assume during startup. When assuming a master device, it can fail with (nm-bond): ignoring generated connection (IPv6LL-only and not in master-slave relationship) thus, for internal reason the device cannot be assumed yet. Fix that by attatching the assume-state to the device, so that on multiple recheck_assume_connection() calls we still try to assume. Whenever we try to assume the connection and it fails due to external reasons (like, the connection no longer matching), we clear the assume state, so that we only try as long as there are internal reasons why assuming fails. https://bugzilla.redhat.com/show_bug.cgi?id=1452062
2017-06-07 17:34:47 +02:00
/*****************************************************************************/
void nm_device_assume_state_get (NMDevice *self,
gboolean *out_assume_state_guess_assume,
const char **out_assume_state_connection_uuid);
void nm_device_assume_state_reset (NMDevice *self);
/*****************************************************************************/
gboolean nm_device_realize_start (NMDevice *device,
const NMPlatformLink *plink,
manager: fix preserving assume state during activation Originally 850c977 "device: track system interface state in NMDevice", intended that a connection can only be assumed initially when seeing a device for the first time. Assuming a connection later was to be prevented by setting device's sys-iface-state to MANAGED. That changed too much in behavior, because we used to assume external connections also when they are activated later on. So this was attempted to get fixed by - acf1067 nm-manager: try assuming connections on managed devices - b6b7d90 manager: avoid generating in memory connections during startup for managed devices It's probably just wrong to prevent assuming connections based on the sys-iface-state. So drop the check for sys-iface-state from recheck_assume_connection(). Now, we can assume anytime on managed, disconnected interfaces, like previously. Btw, note that priv->startup is totally wrong to check there, because priv->startup has the sole purpose of tracking startup-complete property. Startup, as far as NMManager is concerned, is platform_query_devices(). However, the problem is that we only assume connections (contrary to doing external activation) when we have a connection-uuid from the state file or with guess-assume during startup. When assuming a master device, it can fail with (nm-bond): ignoring generated connection (IPv6LL-only and not in master-slave relationship) thus, for internal reason the device cannot be assumed yet. Fix that by attatching the assume-state to the device, so that on multiple recheck_assume_connection() calls we still try to assume. Whenever we try to assume the connection and it fails due to external reasons (like, the connection no longer matching), we clear the assume state, so that we only try as long as there are internal reasons why assuming fails. https://bugzilla.redhat.com/show_bug.cgi?id=1452062
2017-06-07 17:34:47 +02:00
gboolean assume_state_guess_assume,
const char *assume_state_connection_uuid,
gboolean set_nm_owned,
NMUnmanFlagOp unmanaged_user_explicit,
gboolean *out_compatible,
GError **error);
void nm_device_realize_finish (NMDevice *self,
const NMPlatformLink *plink);
gboolean nm_device_create_and_realize (NMDevice *self,
NMConnection *connection,
NMDevice *parent,
GError **error);
gboolean nm_device_unrealize (NMDevice *device,
gboolean remove_resources,
GError **error);
void nm_device_update_from_platform_link (NMDevice *self,
const NMPlatformLink *plink);
typedef enum {
NM_DEVICE_AUTOCONNECT_BLOCKED_NONE = 0,
NM_DEVICE_AUTOCONNECT_BLOCKED_USER = (1LL << 0),
NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN = (1LL << 1),
NM_DEVICE_AUTOCONNECT_BLOCKED_MANUAL_DISCONNECT = (1LL << 2),
_NM_DEVICE_AUTOCONNECT_BLOCKED_LAST,
NM_DEVICE_AUTOCONNECT_BLOCKED_ALL = (((_NM_DEVICE_AUTOCONNECT_BLOCKED_LAST - 1) << 1) - 1),
NM_DEVICE_AUTOCONNECT_BLOCKED_INTERNAL = NM_DEVICE_AUTOCONNECT_BLOCKED_ALL & ~NM_DEVICE_AUTOCONNECT_BLOCKED_USER,
} NMDeviceAutoconnectBlockedFlags;
NMDeviceAutoconnectBlockedFlags nm_device_autoconnect_blocked_get (NMDevice *device, NMDeviceAutoconnectBlockedFlags mask);
void nm_device_autoconnect_blocked_set_full (NMDevice *device, NMDeviceAutoconnectBlockedFlags mask, NMDeviceAutoconnectBlockedFlags values);
static inline void
nm_device_autoconnect_blocked_set (NMDevice *device, NMDeviceAutoconnectBlockedFlags mask)
{
nm_device_autoconnect_blocked_set_full (device, mask, mask);
}
static inline void
nm_device_autoconnect_blocked_unset (NMDevice *device, NMDeviceAutoconnectBlockedFlags mask)
{
nm_device_autoconnect_blocked_set_full (device, mask, NM_DEVICE_AUTOCONNECT_BLOCKED_NONE);
}
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
void nm_device_emit_recheck_auto_activate (NMDevice *device);
device: track system interface state in NMDevice When deciding whether to touch a device we sometimes look at whether the active connection is external/assumed. In many cases however, there is no active connection around (e.g. while moving the device from state unmanaged to disconnected before assuming). So in most cases we instead look at the device-state-reason to decide whether to touch the interface (see nm_device_state_reason_check()). Often it's desirable to have no state and passing data as function arguments. However, the state reason has to be passed along several hops (e.g. a queued state change). Or a change to a master/slave can affect the slave/master, where we pass on the state reason. Or an intermediate event might invalidate a previous state reason. Passing the state whether to touch a device or not as a state-reason is cumbersome and limited. Instead, the device should be aware of whats going on. Add a sys-iface-state with: - SYS_IFACE_STATE_EXTERNAL: meaning, NM should not touch it - SYS_IFACE_STATE_ASSUME: meaning, NM is gracefully taking over - SYS_IFACE_STATE_MANAGED: meaning, the device is managed by NM - SYS_IFACE_STATE_REMOVED: the device no longer exists This replaces most checks of nm_device_state_reason_check() and nm_active_connection_get_activation_type() by instead looking at the sys-iface-state of the device. This patch probably has still issues, but the previous behavior was not very clear either. We will need to identify those issues in future tests and tweak the behavior. At least, now there is one flag that describes how to behave.
2017-03-13 15:34:14 +01:00
NMDeviceSysIfaceState nm_device_sys_iface_state_get (NMDevice *device);
gboolean nm_device_sys_iface_state_is_external (NMDevice *self);
gboolean nm_device_sys_iface_state_is_external_or_assume (NMDevice *self);
void nm_device_sys_iface_state_set (NMDevice *device, NMDeviceSysIfaceState sys_iface_state);
void nm_device_state_changed (NMDevice *device,
NMDeviceState state,
NMDeviceStateReason reason);
void nm_device_queue_state (NMDevice *self,
NMDeviceState state,
NMDeviceStateReason reason);
gboolean nm_device_get_firmware_missing (NMDevice *self);
void nm_device_disconnect_active_connection (NMActiveConnection *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
void nm_device_queue_activation (NMDevice *device, NMActRequest *req);
gboolean nm_device_supports_vlans (NMDevice *device);
gboolean nm_device_add_pending_action (NMDevice *device, const char *action, gboolean assert_not_yet_pending);
gboolean nm_device_remove_pending_action (NMDevice *device, const char *action, gboolean assert_is_pending);
gboolean nm_device_has_pending_action (NMDevice *device);
NMSettingsConnection *nm_device_get_best_connection (NMDevice *device,
const char *specific_object,
GError **error);
device: eliminate direct calls to check_connection_available() in favor of nm_device_check_connection_available() It was confusing to understand the difference between calling nm_device_connection_is_available() and check_connection_available(), they behaved similar, but not really the same. Especially nm_device_connection_is_available() would look first into @available_connetions, and might call check_connection_available() itself. Whereas @available_connetions was also populated by testing check_connection_available(). This interrelation makes it hard to understand when nm_device_connection_is_available() returned true. Rename nm_device_connection_is_available() to nm_device_check_connection_available() and remove all direct calls of check_connection_available() in favor of the wrapper nm_device_check_connection_available(). Now we only call nm_device_check_connection_available() with different parameters (@flags and @specific_object). We also have the additional guarantee that specifying more @flags will widen the result and making a connection "more" available, while specifying a @specific_object will restrict it. This also changes behavior in several cases. For example before nm_device_connection_is_available() for user-requests would always declare matching connections available on Wi-Fi devices (only) regardless of the device state. Now the device state gets consistently considered. For default-unmanaged devices it also changes behavior in complicated ways, because before we would put connections into @available_connetions for every device-state, but nm_device_connection_is_available() had a special over-ride only for unmanaged-state. This also fixes a bug, that user can activate an unavailable Wi-Fi device: nmcli radio wifi off nmcli connection up wlan0
2015-01-16 16:43:48 +01:00
gboolean nm_device_check_connection_available (NMDevice *device,
NMConnection *connection,
NMDeviceCheckConAvailableFlags flags,
const char *specific_object,
GError **error);
gboolean nm_device_notify_component_added (NMDevice *device, GObject *component);
gboolean nm_device_owns_iface (NMDevice *device, const char *iface);
NMConnection *nm_device_new_default_connection (NMDevice *self);
const NMPObject *nm_device_get_best_default_route (NMDevice *self,
int addr_family);
void nm_device_spawn_iface_helper (NMDevice *self);
gboolean nm_device_reapply (NMDevice *self,
NMConnection *connection,
GError **error);
void nm_device_reapply_settings_immediately (NMDevice *self);
void nm_device_update_firewall_zone (NMDevice *self);
void nm_device_update_metered (NMDevice *self);
void nm_device_reactivate_ip4_config (NMDevice *device,
NMSettingIPConfig *s_ip4_old,
NMSettingIPConfig *s_ip4_new);
void nm_device_reactivate_ip6_config (NMDevice *device,
NMSettingIPConfig *s_ip6_old,
NMSettingIPConfig *s_ip6_new);
gboolean nm_device_update_hw_address (NMDevice *self);
void nm_device_update_initial_hw_address (NMDevice *self);
device: delay capturing permanent MAC address until UDEV is settled The permanent MAC address of an NMDevice shall not change as long as the device is realized. That is, we read it only once and don't change it afterwards. There are two issues that this commit tries to mitigate: (1) users are advised to use UDEV to rename interfaces. As we lookup the permenent MAC address using ethtool (which uses the interface name), there is a race where we could read the permanent MAC address using the wrong interface name. We should wait until UDEV finished initializing the device and until the interface name is stable (see rh#1388286). This commit still cannot avoid the race of ethtool entirely. It only tries to avoid ethtool until UDEV has done its work. That is, until we expect the interface name no longer to change. (2) some device types, don't have a permanent MAC address so we fall back to use the currently set address (fake). Again, users are advised to use UDEV to configure the MAC addresses on such software devices. Thus, we should not get the fake MAC address until UDEV initialized the device. This patch actually doesn't solve the problem at all yet. The reason is that a regular caller of nm_device_get_permanent_hw_address() can not afford to wait until UDEV settled. Thus, any user who requests the permanent MAC address before the link is initialized, runs into the problems above. In a next step, we shall revisit such calls to nm_device_get_permanent_hw_address() and delay them until the link is initialized.
2016-10-24 12:50:17 +02:00
void nm_device_update_permanent_hw_address (NMDevice *self, gboolean force_freeze);
void nm_device_update_dynamic_ip_setup (NMDevice *self);
guint nm_device_get_supplicant_timeout (NMDevice *self);
gboolean nm_device_auth_retries_try_next (NMDevice *self);
gboolean nm_device_hw_addr_get_cloned (NMDevice *self,
NMConnection *connection,
gboolean is_wifi,
char **hwaddr,
gboolean *preserve,
GError **error);
connectivity: rework async connectivity check requests An asynchronous request should either be cancellable or not keep the target object alive. Preferably both. Otherwise, it is impossible to do a controlled shutdown when terminating NetworkManager. Currently, when NetworkManager is about to terminate, it just quits the mainloop and essentially leaks everything. That is a bug. If we ever want to fix that, every asynchronous request must be cancellable in a controlled way (or it must not prevent objects from getting disposed, where disposing the object automatically cancels the callback). Rework the asynchronous request for connectivity check to - return a handle that can be used to cancel the operation. Cancelling is optional. The caller may choose to ignore the handle because the asynchronous operation does not keep the target object alive. That means, it is still possible to shutdown, by everybody giving up their reference to the target object. In which case the callback will be invoked during dispose() of the target object. - also, the callback will always be invoked exactly once, and never synchronously from within the asynchronous start call. But during cancel(), the callback is invoked synchronously from within cancel(). Note that it's only allowed to cancel an action at most once, and never after the callback is invoked (also not from within the callback itself). - also, NMConnectivity already supports a fake handler, in case connectivity check is disabled via configuration. Hence, reuse the same code paths also when compiling without --enable-concheck. That means, instead of having #if WITH_CONCHECK at various callers, move them into NMConnectivity. The downside is, that if you build without concheck, there is a small overhead compared to before. The upside is, we reuse the same code paths when compiling with or without concheck. - also, the patch synchronizes the connecitivty states. For example, previously `nmcli networking connectivity check` would schedule requests in parallel, and return the accumulated result of the individual requests. However, the global connectivity state of the manager might have have been the same as the answer to the explicit connecitivity check, because while the answer for the manual check is waiting for all pending checks to complete, the global connectivity state could already change. That is just wrong. There are not multiple global connectivity states at the same time, there is just one. A manual connectivity check should have the meaning of ensure that the global state is up to date, but it still should return the global connectivity state -- not the answers for several connectivity checks issued in parallel. This is related to commit b799de281bc01073c31dd2c86171b29c8132441c (libnm: update property in the manager after connectivity check), which tries to address a similar problem client side. Similarly, each device has a connectivity state. While there might be several connectivity checks per device pending, whenever a check completes, it can update the per-device state (and return that device state as result), but the immediate answer of the individual check might not matter. This is especially the case, when a later request returns earlier and obsoletes all earlier requests. In that case, earlier requests return with the result of the currend devices connectivity state. This patch cleans up the internal API and gives a better defined behavior to the user (thus, the simple API which simplifies implementation for the caller). However, the implementation of getting this API right and properly handle cancel and destruction of the target object is more complicated and complex. But this but is not just for the sake of a nicer API. This fixes actual issues explained above. Also, get rid of GAsyncResult to track information about the pending request. Instead, allocate our own handle structure, which ends up to be nicer because it's strongly typed and has exactly the properties that are useful to track the request. Also, it gets rid of the awkward _finish() API by passing the relevant arguments to the callback directly.
2018-01-05 17:46:49 +01:00
typedef struct _NMDeviceConnectivityHandle NMDeviceConnectivityHandle;
typedef void (*NMDeviceConnectivityCallback) (NMDevice *self,
connectivity: rework async connectivity check requests An asynchronous request should either be cancellable or not keep the target object alive. Preferably both. Otherwise, it is impossible to do a controlled shutdown when terminating NetworkManager. Currently, when NetworkManager is about to terminate, it just quits the mainloop and essentially leaks everything. That is a bug. If we ever want to fix that, every asynchronous request must be cancellable in a controlled way (or it must not prevent objects from getting disposed, where disposing the object automatically cancels the callback). Rework the asynchronous request for connectivity check to - return a handle that can be used to cancel the operation. Cancelling is optional. The caller may choose to ignore the handle because the asynchronous operation does not keep the target object alive. That means, it is still possible to shutdown, by everybody giving up their reference to the target object. In which case the callback will be invoked during dispose() of the target object. - also, the callback will always be invoked exactly once, and never synchronously from within the asynchronous start call. But during cancel(), the callback is invoked synchronously from within cancel(). Note that it's only allowed to cancel an action at most once, and never after the callback is invoked (also not from within the callback itself). - also, NMConnectivity already supports a fake handler, in case connectivity check is disabled via configuration. Hence, reuse the same code paths also when compiling without --enable-concheck. That means, instead of having #if WITH_CONCHECK at various callers, move them into NMConnectivity. The downside is, that if you build without concheck, there is a small overhead compared to before. The upside is, we reuse the same code paths when compiling with or without concheck. - also, the patch synchronizes the connecitivty states. For example, previously `nmcli networking connectivity check` would schedule requests in parallel, and return the accumulated result of the individual requests. However, the global connectivity state of the manager might have have been the same as the answer to the explicit connecitivity check, because while the answer for the manual check is waiting for all pending checks to complete, the global connectivity state could already change. That is just wrong. There are not multiple global connectivity states at the same time, there is just one. A manual connectivity check should have the meaning of ensure that the global state is up to date, but it still should return the global connectivity state -- not the answers for several connectivity checks issued in parallel. This is related to commit b799de281bc01073c31dd2c86171b29c8132441c (libnm: update property in the manager after connectivity check), which tries to address a similar problem client side. Similarly, each device has a connectivity state. While there might be several connectivity checks per device pending, whenever a check completes, it can update the per-device state (and return that device state as result), but the immediate answer of the individual check might not matter. This is especially the case, when a later request returns earlier and obsoletes all earlier requests. In that case, earlier requests return with the result of the currend devices connectivity state. This patch cleans up the internal API and gives a better defined behavior to the user (thus, the simple API which simplifies implementation for the caller). However, the implementation of getting this API right and properly handle cancel and destruction of the target object is more complicated and complex. But this but is not just for the sake of a nicer API. This fixes actual issues explained above. Also, get rid of GAsyncResult to track information about the pending request. Instead, allocate our own handle structure, which ends up to be nicer because it's strongly typed and has exactly the properties that are useful to track the request. Also, it gets rid of the awkward _finish() API by passing the relevant arguments to the callback directly.
2018-01-05 17:46:49 +01:00
NMDeviceConnectivityHandle *handle,
NMConnectivityState state,
connectivity: rework async connectivity check requests An asynchronous request should either be cancellable or not keep the target object alive. Preferably both. Otherwise, it is impossible to do a controlled shutdown when terminating NetworkManager. Currently, when NetworkManager is about to terminate, it just quits the mainloop and essentially leaks everything. That is a bug. If we ever want to fix that, every asynchronous request must be cancellable in a controlled way (or it must not prevent objects from getting disposed, where disposing the object automatically cancels the callback). Rework the asynchronous request for connectivity check to - return a handle that can be used to cancel the operation. Cancelling is optional. The caller may choose to ignore the handle because the asynchronous operation does not keep the target object alive. That means, it is still possible to shutdown, by everybody giving up their reference to the target object. In which case the callback will be invoked during dispose() of the target object. - also, the callback will always be invoked exactly once, and never synchronously from within the asynchronous start call. But during cancel(), the callback is invoked synchronously from within cancel(). Note that it's only allowed to cancel an action at most once, and never after the callback is invoked (also not from within the callback itself). - also, NMConnectivity already supports a fake handler, in case connectivity check is disabled via configuration. Hence, reuse the same code paths also when compiling without --enable-concheck. That means, instead of having #if WITH_CONCHECK at various callers, move them into NMConnectivity. The downside is, that if you build without concheck, there is a small overhead compared to before. The upside is, we reuse the same code paths when compiling with or without concheck. - also, the patch synchronizes the connecitivty states. For example, previously `nmcli networking connectivity check` would schedule requests in parallel, and return the accumulated result of the individual requests. However, the global connectivity state of the manager might have have been the same as the answer to the explicit connecitivity check, because while the answer for the manual check is waiting for all pending checks to complete, the global connectivity state could already change. That is just wrong. There are not multiple global connectivity states at the same time, there is just one. A manual connectivity check should have the meaning of ensure that the global state is up to date, but it still should return the global connectivity state -- not the answers for several connectivity checks issued in parallel. This is related to commit b799de281bc01073c31dd2c86171b29c8132441c (libnm: update property in the manager after connectivity check), which tries to address a similar problem client side. Similarly, each device has a connectivity state. While there might be several connectivity checks per device pending, whenever a check completes, it can update the per-device state (and return that device state as result), but the immediate answer of the individual check might not matter. This is especially the case, when a later request returns earlier and obsoletes all earlier requests. In that case, earlier requests return with the result of the currend devices connectivity state. This patch cleans up the internal API and gives a better defined behavior to the user (thus, the simple API which simplifies implementation for the caller). However, the implementation of getting this API right and properly handle cancel and destruction of the target object is more complicated and complex. But this but is not just for the sake of a nicer API. This fixes actual issues explained above. Also, get rid of GAsyncResult to track information about the pending request. Instead, allocate our own handle structure, which ends up to be nicer because it's strongly typed and has exactly the properties that are useful to track the request. Also, it gets rid of the awkward _finish() API by passing the relevant arguments to the callback directly.
2018-01-05 17:46:49 +01:00
GError *error,
gpointer user_data);
connectivity: rework async connectivity check requests An asynchronous request should either be cancellable or not keep the target object alive. Preferably both. Otherwise, it is impossible to do a controlled shutdown when terminating NetworkManager. Currently, when NetworkManager is about to terminate, it just quits the mainloop and essentially leaks everything. That is a bug. If we ever want to fix that, every asynchronous request must be cancellable in a controlled way (or it must not prevent objects from getting disposed, where disposing the object automatically cancels the callback). Rework the asynchronous request for connectivity check to - return a handle that can be used to cancel the operation. Cancelling is optional. The caller may choose to ignore the handle because the asynchronous operation does not keep the target object alive. That means, it is still possible to shutdown, by everybody giving up their reference to the target object. In which case the callback will be invoked during dispose() of the target object. - also, the callback will always be invoked exactly once, and never synchronously from within the asynchronous start call. But during cancel(), the callback is invoked synchronously from within cancel(). Note that it's only allowed to cancel an action at most once, and never after the callback is invoked (also not from within the callback itself). - also, NMConnectivity already supports a fake handler, in case connectivity check is disabled via configuration. Hence, reuse the same code paths also when compiling without --enable-concheck. That means, instead of having #if WITH_CONCHECK at various callers, move them into NMConnectivity. The downside is, that if you build without concheck, there is a small overhead compared to before. The upside is, we reuse the same code paths when compiling with or without concheck. - also, the patch synchronizes the connecitivty states. For example, previously `nmcli networking connectivity check` would schedule requests in parallel, and return the accumulated result of the individual requests. However, the global connectivity state of the manager might have have been the same as the answer to the explicit connecitivity check, because while the answer for the manual check is waiting for all pending checks to complete, the global connectivity state could already change. That is just wrong. There are not multiple global connectivity states at the same time, there is just one. A manual connectivity check should have the meaning of ensure that the global state is up to date, but it still should return the global connectivity state -- not the answers for several connectivity checks issued in parallel. This is related to commit b799de281bc01073c31dd2c86171b29c8132441c (libnm: update property in the manager after connectivity check), which tries to address a similar problem client side. Similarly, each device has a connectivity state. While there might be several connectivity checks per device pending, whenever a check completes, it can update the per-device state (and return that device state as result), but the immediate answer of the individual check might not matter. This is especially the case, when a later request returns earlier and obsoletes all earlier requests. In that case, earlier requests return with the result of the currend devices connectivity state. This patch cleans up the internal API and gives a better defined behavior to the user (thus, the simple API which simplifies implementation for the caller). However, the implementation of getting this API right and properly handle cancel and destruction of the target object is more complicated and complex. But this but is not just for the sake of a nicer API. This fixes actual issues explained above. Also, get rid of GAsyncResult to track information about the pending request. Instead, allocate our own handle structure, which ends up to be nicer because it's strongly typed and has exactly the properties that are useful to track the request. Also, it gets rid of the awkward _finish() API by passing the relevant arguments to the callback directly.
2018-01-05 17:46:49 +01:00
connectivity: schedule connectivity timers per-device and probe for short outages It might happen, that connectivitiy is lost only for a moment and returns soon after. Based on that assumption, when we loose connectivity we want to have a probe interval where we check for returning connectivity more frequently. For that, we handle tracking of the timeouts per-device. The intervall shall start with 1 seconds, and double the interval time until the full interval is reached. Actually, due to the implementation, it's unlikely that we already perform the second check 1 second later. That is because commonly the first check returns before the one second timeout is reached and bumps the interval to 2 seconds right away. Also, we go through extra lengths so that manual connectivity check delay the periodic checks. By being more smart about that, we can reduce the number of connectivity checks, but still keeping the promise to check at least within the requested interval. The complexity of book keeping the timeouts is remarkable. But I think it is worth the effort and we should try hard to - have a connectivity state as accurate as possible. Clearly, connectivity checking means that we probing, so being more intelligent about timeout and backoff timers can result in a better connectivity state. The connectivity state is important because we use it for the default-route penaly and the GUI indicates bad connectivity. - be intelligent about avoiding redundant connectivity checks. While we want to check often to get an accurate connectivity state, we also want to minimize the number of HTTP requests, in case the connectivity is established and suppossedly stable. Also, perform connectivity checks in every state of the device. Even if a device is disconnected, it still might have connectivity, for example if the user externally adds an IP address on an unmanaged device. https://bugzilla.gnome.org/show_bug.cgi?id=792240
2018-02-20 21:41:14 +01:00
void nm_device_check_connectivity_update_interval (NMDevice *self);
connectivity: rework async connectivity check requests An asynchronous request should either be cancellable or not keep the target object alive. Preferably both. Otherwise, it is impossible to do a controlled shutdown when terminating NetworkManager. Currently, when NetworkManager is about to terminate, it just quits the mainloop and essentially leaks everything. That is a bug. If we ever want to fix that, every asynchronous request must be cancellable in a controlled way (or it must not prevent objects from getting disposed, where disposing the object automatically cancels the callback). Rework the asynchronous request for connectivity check to - return a handle that can be used to cancel the operation. Cancelling is optional. The caller may choose to ignore the handle because the asynchronous operation does not keep the target object alive. That means, it is still possible to shutdown, by everybody giving up their reference to the target object. In which case the callback will be invoked during dispose() of the target object. - also, the callback will always be invoked exactly once, and never synchronously from within the asynchronous start call. But during cancel(), the callback is invoked synchronously from within cancel(). Note that it's only allowed to cancel an action at most once, and never after the callback is invoked (also not from within the callback itself). - also, NMConnectivity already supports a fake handler, in case connectivity check is disabled via configuration. Hence, reuse the same code paths also when compiling without --enable-concheck. That means, instead of having #if WITH_CONCHECK at various callers, move them into NMConnectivity. The downside is, that if you build without concheck, there is a small overhead compared to before. The upside is, we reuse the same code paths when compiling with or without concheck. - also, the patch synchronizes the connecitivty states. For example, previously `nmcli networking connectivity check` would schedule requests in parallel, and return the accumulated result of the individual requests. However, the global connectivity state of the manager might have have been the same as the answer to the explicit connecitivity check, because while the answer for the manual check is waiting for all pending checks to complete, the global connectivity state could already change. That is just wrong. There are not multiple global connectivity states at the same time, there is just one. A manual connectivity check should have the meaning of ensure that the global state is up to date, but it still should return the global connectivity state -- not the answers for several connectivity checks issued in parallel. This is related to commit b799de281bc01073c31dd2c86171b29c8132441c (libnm: update property in the manager after connectivity check), which tries to address a similar problem client side. Similarly, each device has a connectivity state. While there might be several connectivity checks per device pending, whenever a check completes, it can update the per-device state (and return that device state as result), but the immediate answer of the individual check might not matter. This is especially the case, when a later request returns earlier and obsoletes all earlier requests. In that case, earlier requests return with the result of the currend devices connectivity state. This patch cleans up the internal API and gives a better defined behavior to the user (thus, the simple API which simplifies implementation for the caller). However, the implementation of getting this API right and properly handle cancel and destruction of the target object is more complicated and complex. But this but is not just for the sake of a nicer API. This fixes actual issues explained above. Also, get rid of GAsyncResult to track information about the pending request. Instead, allocate our own handle structure, which ends up to be nicer because it's strongly typed and has exactly the properties that are useful to track the request. Also, it gets rid of the awkward _finish() API by passing the relevant arguments to the callback directly.
2018-01-05 17:46:49 +01:00
NMDeviceConnectivityHandle *nm_device_check_connectivity (NMDevice *self,
NMDeviceConnectivityCallback callback,
gpointer user_data);
void nm_device_check_connectivity_cancel (NMDeviceConnectivityHandle *handle);
NMConnectivityState nm_device_get_connectivity_state (NMDevice *self);
typedef struct _NMBtVTableNetworkServer NMBtVTableNetworkServer;
struct _NMBtVTableNetworkServer {
gboolean (*is_available) (const NMBtVTableNetworkServer *vtable,
const char *addr);
gboolean (*register_bridge) (const NMBtVTableNetworkServer *vtable,
const char *addr,
NMDevice *device);
gboolean (*unregister_bridge) (const NMBtVTableNetworkServer *vtable,
NMDevice *device);
};
const char *nm_device_state_to_str (NMDeviceState state);
const char *nm_device_state_reason_to_str (NMDeviceStateReason reason);
#endif /* __NETWORKMANAGER_DEVICE_H__ */