2008-07-09 14:05:49 +00:00
|
|
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
2005-12-31 08:21:24 +00:00
|
|
|
/* 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.
|
|
|
|
|
*
|
2008-06-26 18:31:52 +00:00
|
|
|
* 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.
|
2005-12-31 08:21:24 +00:00
|
|
|
*
|
2013-12-16 15:16:43 +01:00
|
|
|
* Copyright (C) 2005 - 2013 Red Hat, Inc.
|
2008-11-03 04:13:42 +00:00
|
|
|
* Copyright (C) 2006 - 2008 Novell, Inc.
|
2005-12-31 08:21:24 +00:00
|
|
|
*/
|
|
|
|
|
|
2010-10-08 22:45:35 -05:00
|
|
|
#include <config.h>
|
2005-12-31 08:21:24 +00:00
|
|
|
#include <glib.h>
|
|
|
|
|
#include <glib/gi18n.h>
|
|
|
|
|
#include <dbus/dbus.h>
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
#include <string.h>
|
2008-03-14 20:37:48 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <errno.h>
|
2012-06-01 16:48:57 +02:00
|
|
|
#include <linux/sockios.h>
|
|
|
|
|
#include <linux/ethtool.h>
|
2008-03-14 20:37:48 +00:00
|
|
|
#include <sys/ioctl.h>
|
2008-07-09 14:05:49 +00:00
|
|
|
#include <signal.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/wait.h>
|
|
|
|
|
#include <arpa/inet.h>
|
2008-08-15 15:34:28 +00:00
|
|
|
#include <fcntl.h>
|
2014-01-03 17:03:35 +01:00
|
|
|
#include <netlink/route/addr.h>
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-07-15 19:30:33 +02:00
|
|
|
#include "gsystem-local-alloc.h"
|
2008-12-31 18:57:36 -05:00
|
|
|
#include "nm-glib-compat.h"
|
2007-05-07 15:17:45 +00:00
|
|
|
#include "nm-device.h"
|
2005-12-31 08:21:24 +00:00
|
|
|
#include "nm-device-private.h"
|
|
|
|
|
#include "NetworkManagerUtils.h"
|
2013-10-18 12:32:01 +02:00
|
|
|
#include "nm-manager.h"
|
2013-01-21 15:12:24 +01:00
|
|
|
#include "nm-platform.h"
|
2013-05-30 16:53:23 +02:00
|
|
|
#include "nm-rdisc.h"
|
|
|
|
|
#include "nm-lndp-rdisc.h"
|
2005-12-31 08:21:24 +00:00
|
|
|
#include "nm-dhcp-manager.h"
|
2007-02-12 09:23:43 +00:00
|
|
|
#include "nm-dbus-manager.h"
|
2005-12-31 08:21:24 +00:00
|
|
|
#include "nm-utils.h"
|
2010-04-07 12:31:39 -07:00
|
|
|
#include "nm-logging.h"
|
2014-07-17 17:06:44 -04:00
|
|
|
#include "nm-activation-request.h"
|
2007-11-07 16:06:43 +00:00
|
|
|
#include "nm-setting-ip4-config.h"
|
2014-07-17 17:06:44 -04:00
|
|
|
#include "nm-ip4-config.h"
|
2009-07-29 12:12:41 -04:00
|
|
|
#include "nm-setting-ip6-config.h"
|
2014-07-17 17:06:44 -04:00
|
|
|
#include "nm-ip6-config.h"
|
2007-12-31 17:05:25 +00:00
|
|
|
#include "nm-setting-connection.h"
|
2008-05-29 20:58:52 +00:00
|
|
|
#include "nm-dnsmasq-manager.h"
|
2008-07-17 17:04:13 +00:00
|
|
|
#include "nm-dhcp4-config.h"
|
2014-07-17 17:06:44 -04:00
|
|
|
#include "nm-dhcp6-config.h"
|
2013-05-09 10:24:08 -04:00
|
|
|
#include "nm-rfkill-manager.h"
|
2011-10-07 15:58:08 +02:00
|
|
|
#include "nm-firewall-manager.h"
|
2011-11-18 00:34:08 -06:00
|
|
|
#include "nm-properties-changed-signal.h"
|
2012-02-08 12:56:52 -05:00
|
|
|
#include "nm-enum-types.h"
|
2012-02-09 16:32:48 -06:00
|
|
|
#include "nm-settings-connection.h"
|
2012-05-02 10:28:16 -05:00
|
|
|
#include "nm-connection-provider.h"
|
2012-05-21 14:10:05 +02:00
|
|
|
#include "nm-posix-signals.h"
|
2012-06-01 16:53:23 -05:00
|
|
|
#include "nm-manager-auth.h"
|
2012-08-01 11:16:48 -06:00
|
|
|
#include "nm-dbus-glib-types.h"
|
2012-06-03 19:32:16 -05:00
|
|
|
#include "nm-dispatcher.h"
|
2013-03-19 10:24:35 -04:00
|
|
|
#include "nm-config.h"
|
2013-12-17 16:57:47 -05:00
|
|
|
#include "nm-dns-manager.h"
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-08-02 14:52:49 +02:00
|
|
|
#include "nm-device-logging.h"
|
|
|
|
|
_LOG_DECLARE_SELF (NMDevice);
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
static void impl_device_disconnect (NMDevice *self, DBusGMethodInvocation *context);
|
|
|
|
|
static void impl_device_delete (NMDevice *self, DBusGMethodInvocation *context);
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2013-05-08 16:52:36 -04:00
|
|
|
#include "nm-device-glue.h"
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-07-17 16:24:17 -04:00
|
|
|
G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, G_TYPE_OBJECT)
|
2011-11-18 00:05:37 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
#define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate))
|
2011-11-18 00:05:37 -06:00
|
|
|
|
2009-07-15 17:22:10 -04:00
|
|
|
enum {
|
2011-11-18 00:09:37 -06:00
|
|
|
STATE_CHANGED,
|
2009-07-15 17:22:10 -04:00
|
|
|
AUTOCONNECT_ALLOWED,
|
2012-06-01 15:27:39 -05:00
|
|
|
AUTH_REQUEST,
|
2012-05-29 09:56:50 -05:00
|
|
|
IP4_CONFIG_CHANGED,
|
|
|
|
|
IP6_CONFIG_CHANGED,
|
2014-02-10 08:49:47 -06:00
|
|
|
REMOVED,
|
2014-02-24 18:10:18 -06:00
|
|
|
RECHECK_AUTO_ACTIVATE,
|
2014-05-28 10:18:34 -04:00
|
|
|
RECHECK_ASSUME,
|
2009-07-15 17:22:10 -04:00
|
|
|
LAST_SIGNAL,
|
|
|
|
|
};
|
|
|
|
|
static guint signals[LAST_SIGNAL] = { 0 };
|
|
|
|
|
|
2011-11-18 00:34:08 -06:00
|
|
|
enum {
|
|
|
|
|
PROP_0,
|
2013-05-29 12:57:13 -03:00
|
|
|
PROP_PLATFORM_DEVICE,
|
2011-11-18 00:34:08 -06:00
|
|
|
PROP_UDI,
|
|
|
|
|
PROP_IFACE,
|
|
|
|
|
PROP_IP_IFACE,
|
|
|
|
|
PROP_DRIVER,
|
2012-06-01 16:48:57 +02:00
|
|
|
PROP_DRIVER_VERSION,
|
|
|
|
|
PROP_FIRMWARE_VERSION,
|
2011-11-18 00:34:08 -06:00
|
|
|
PROP_CAPABILITIES,
|
2013-05-07 10:23:44 -04:00
|
|
|
PROP_CARRIER,
|
2013-12-16 15:16:43 +01:00
|
|
|
PROP_MTU,
|
2011-11-18 00:34:08 -06:00
|
|
|
PROP_IP4_ADDRESS,
|
|
|
|
|
PROP_IP4_CONFIG,
|
|
|
|
|
PROP_DHCP4_CONFIG,
|
|
|
|
|
PROP_IP6_CONFIG,
|
|
|
|
|
PROP_DHCP6_CONFIG,
|
|
|
|
|
PROP_STATE,
|
2012-01-29 22:40:37 +01:00
|
|
|
PROP_STATE_REASON,
|
2011-11-18 00:34:08 -06:00
|
|
|
PROP_ACTIVE_CONNECTION,
|
|
|
|
|
PROP_DEVICE_TYPE,
|
|
|
|
|
PROP_MANAGED,
|
2012-05-14 15:32:54 +02:00
|
|
|
PROP_AUTOCONNECT,
|
2011-11-18 00:34:08 -06:00
|
|
|
PROP_FIRMWARE_MISSING,
|
|
|
|
|
PROP_TYPE_DESC,
|
|
|
|
|
PROP_RFKILL_TYPE,
|
|
|
|
|
PROP_IFINDEX,
|
2012-08-01 11:16:48 -06:00
|
|
|
PROP_AVAILABLE_CONNECTIONS,
|
2013-10-11 14:59:26 -04:00
|
|
|
PROP_PHYSICAL_PORT_ID,
|
2013-01-24 17:47:59 -06:00
|
|
|
PROP_IS_MASTER,
|
2014-01-02 14:46:02 -05:00
|
|
|
PROP_MASTER,
|
2013-05-01 09:28:16 -04:00
|
|
|
PROP_HW_ADDRESS,
|
2013-08-13 17:45:34 -04:00
|
|
|
PROP_HAS_PENDING_ACTION,
|
2011-11-18 00:34:08 -06:00
|
|
|
LAST_PROP
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/***********************************************************/
|
|
|
|
|
|
2014-04-14 17:57:56 +02:00
|
|
|
#define PENDING_ACTION_DHCP4 "dhcp4"
|
|
|
|
|
#define PENDING_ACTION_DHCP6 "dhcp6"
|
|
|
|
|
#define PENDING_ACTION_AUTOCONF6 "autoconf6"
|
|
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
typedef enum {
|
|
|
|
|
IP_NONE = 0,
|
2012-11-15 17:52:24 -06:00
|
|
|
IP_WAIT,
|
2011-10-09 23:48:13 -05:00
|
|
|
IP_CONF,
|
2013-06-27 17:51:24 +02:00
|
|
|
IP_DONE,
|
|
|
|
|
IP_FAIL
|
2011-10-09 23:48:13 -05:00
|
|
|
} IpState;
|
|
|
|
|
|
2011-12-08 11:46:58 -06:00
|
|
|
typedef struct {
|
|
|
|
|
NMDeviceState state;
|
|
|
|
|
NMDeviceStateReason reason;
|
|
|
|
|
guint id;
|
|
|
|
|
} QueuedState;
|
|
|
|
|
|
2012-11-14 14:05:30 -06:00
|
|
|
typedef struct {
|
|
|
|
|
NMDevice *slave;
|
|
|
|
|
gboolean enslaved;
|
2013-11-07 01:08:02 -06:00
|
|
|
gboolean configure;
|
2012-11-14 14:05:30 -06:00
|
|
|
guint watch_id;
|
|
|
|
|
} SlaveInfo;
|
|
|
|
|
|
2013-06-11 17:05:49 -05:00
|
|
|
typedef struct {
|
|
|
|
|
guint log_domain;
|
|
|
|
|
guint timeout;
|
|
|
|
|
guint watch;
|
|
|
|
|
GPid pid;
|
|
|
|
|
} PingInfo;
|
|
|
|
|
|
2014-03-05 22:20:14 +01:00
|
|
|
typedef struct {
|
|
|
|
|
NMDevice *device;
|
|
|
|
|
guint idle_add_id;
|
|
|
|
|
int ifindex;
|
|
|
|
|
} DeleteOnDeactivateData;
|
|
|
|
|
|
2009-07-07 14:34:01 -04:00
|
|
|
typedef struct {
|
2013-05-20 16:15:37 -03:00
|
|
|
gboolean in_state_changed;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-02-05 12:14:09 +00:00
|
|
|
NMDeviceState state;
|
2012-01-29 22:40:37 +01:00
|
|
|
NMDeviceStateReason state_reason;
|
2011-12-08 11:46:58 -06:00
|
|
|
QueuedState queued_state;
|
2013-04-04 10:20:24 -04:00
|
|
|
guint queued_ip_config_id;
|
2013-12-16 16:52:36 +01:00
|
|
|
GSList *pending_actions;
|
2007-02-05 12:14:09 +00:00
|
|
|
|
2009-07-07 14:34:01 -04:00
|
|
|
char * udi;
|
|
|
|
|
char * path;
|
|
|
|
|
char * iface; /* may change, could be renamed by user */
|
2010-04-21 14:58:25 -07:00
|
|
|
int ifindex;
|
2013-08-22 19:15:05 +02:00
|
|
|
gboolean is_software;
|
2009-07-07 14:34:01 -04:00
|
|
|
char * ip_iface;
|
2010-04-21 14:58:25 -07:00
|
|
|
int ip_ifindex;
|
2009-07-07 14:34:01 -04:00
|
|
|
NMDeviceType type;
|
|
|
|
|
char * type_desc;
|
|
|
|
|
guint32 capabilities;
|
|
|
|
|
char * driver;
|
2012-06-01 16:48:57 +02:00
|
|
|
char * driver_version;
|
|
|
|
|
char * firmware_version;
|
2010-03-25 11:36:19 -07:00
|
|
|
RfKillType rfkill_type;
|
2010-05-25 10:52:25 -07:00
|
|
|
gboolean firmware_missing;
|
2012-08-01 11:16:48 -06:00
|
|
|
GHashTable * available_connections;
|
2014-06-21 12:44:56 -04:00
|
|
|
char * hw_addr;
|
2013-05-01 09:28:16 -04:00
|
|
|
guint hw_addr_len;
|
2013-10-11 14:59:26 -04:00
|
|
|
char * physical_port_id;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-03-31 21:45:54 -05:00
|
|
|
NMUnmanagedFlags unmanaged_flags;
|
|
|
|
|
gboolean is_nm_owned; /* whether the device is a device owned and created by NM */
|
2014-03-05 22:20:14 +01:00
|
|
|
DeleteOnDeactivateData *delete_on_deactivate_data; /* data for scheduled cleanup when deleting link (g_idle_add) */
|
2013-04-24 10:40:58 -04:00
|
|
|
|
2009-07-07 14:34:01 -04:00
|
|
|
guint32 ip4_address;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
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
|
|
|
NMActRequest * queued_act_request;
|
2009-07-07 14:34:01 -04:00
|
|
|
NMActRequest * act_request;
|
2007-01-04 12:06:26 +00:00
|
|
|
guint act_source_id;
|
2009-07-07 14:34:01 -04:00
|
|
|
gpointer act_source_func;
|
2009-07-29 12:12:41 -04:00
|
|
|
guint act_source6_id;
|
|
|
|
|
gpointer act_source6_func;
|
2014-05-28 10:18:34 -04:00
|
|
|
guint recheck_assume_id;
|
2014-06-12 14:20:14 +02:00
|
|
|
struct {
|
|
|
|
|
guint call_id;
|
|
|
|
|
NMDeviceState post_state;
|
|
|
|
|
NMDeviceStateReason post_state_reason;
|
|
|
|
|
} dispatcher;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2013-05-07 10:23:44 -04:00
|
|
|
/* Link stuff */
|
|
|
|
|
guint link_connected_id;
|
|
|
|
|
guint link_disconnected_id;
|
|
|
|
|
guint carrier_defer_id;
|
|
|
|
|
gboolean carrier;
|
2013-12-09 16:32:36 -06:00
|
|
|
guint carrier_wait_id;
|
2013-05-07 10:23:44 -04:00
|
|
|
gboolean ignore_carrier;
|
2013-12-16 15:16:43 +01:00
|
|
|
guint32 mtu;
|
2013-05-07 10:23:44 -04:00
|
|
|
|
2010-01-13 18:06:05 -08:00
|
|
|
/* Generic DHCP stuff */
|
|
|
|
|
guint32 dhcp_timeout;
|
2014-07-30 10:57:45 -04:00
|
|
|
char * dhcp_anycast_address;
|
2010-01-13 17:59:54 -08:00
|
|
|
|
2009-07-29 12:12:41 -04:00
|
|
|
/* IP4 configuration info */
|
2013-08-01 10:34:46 -05:00
|
|
|
NMIP4Config * ip4_config; /* Combined config from VPN, settings, and device */
|
2011-10-09 23:48:13 -05:00
|
|
|
IpState ip4_state;
|
2013-08-01 10:34:46 -05:00
|
|
|
NMIP4Config * dev_ip4_config; /* Config from DHCP, PPP, LLv4, etc */
|
2013-08-01 15:44:53 -05:00
|
|
|
NMIP4Config * ext_ip4_config; /* Stuff added outside NM */
|
2014-07-15 17:16:56 -05:00
|
|
|
NMIP4Config * wwan_ip4_config; /* WWAN configuration */
|
2013-08-01 10:34:46 -05:00
|
|
|
|
|
|
|
|
/* DHCPv4 tracking */
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
NMDhcpClient * dhcp4_client;
|
2010-01-13 18:06:05 -08:00
|
|
|
gulong dhcp4_state_sigid;
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
NMDhcp4Config * dhcp4_config;
|
2013-08-01 10:59:42 -05:00
|
|
|
NMIP4Config * vpn4_config; /* routes added by a VPN which uses this device */
|
2008-05-29 20:58:52 +00:00
|
|
|
|
2014-03-19 12:39:38 -04:00
|
|
|
guint arp_round2_id;
|
2013-06-11 17:05:49 -05:00
|
|
|
PingInfo gw_ping;
|
|
|
|
|
|
2008-07-09 14:05:49 +00:00
|
|
|
/* dnsmasq stuff for shared connections */
|
2009-07-07 14:34:01 -04:00
|
|
|
NMDnsMasqManager *dnsmasq_manager;
|
|
|
|
|
gulong dnsmasq_state_id;
|
2008-07-09 14:05:49 +00:00
|
|
|
|
2014-07-02 15:19:58 +02:00
|
|
|
/* Firewall */
|
2011-10-07 15:58:08 +02:00
|
|
|
DBusGProxyCall *fw_call;
|
|
|
|
|
|
2008-07-09 14:05:49 +00:00
|
|
|
/* avahi-autoipd stuff */
|
2009-07-07 14:34:01 -04:00
|
|
|
GPid aipd_pid;
|
|
|
|
|
guint aipd_watch;
|
|
|
|
|
guint aipd_timeout;
|
2009-07-29 12:12:41 -04:00
|
|
|
|
|
|
|
|
/* IP6 configuration info */
|
2009-07-30 13:50:42 -04:00
|
|
|
NMIP6Config * ip6_config;
|
2011-10-09 23:48:13 -05:00
|
|
|
IpState ip6_state;
|
2013-08-01 10:59:42 -05:00
|
|
|
NMIP6Config * vpn6_config; /* routes added by a VPN which uses this device */
|
2013-10-15 21:03:42 -05:00
|
|
|
NMIP6Config * wwan_ip6_config;
|
2013-08-15 12:55:56 -05:00
|
|
|
NMIP6Config * ext_ip6_config; /* Stuff added outside NM */
|
2014-07-24 17:14:30 -05:00
|
|
|
gboolean nm_ipv6ll; /* TRUE if NM handles the device's IPv6LL address */
|
2011-10-21 14:25:35 -05:00
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
NMRDisc * rdisc;
|
2014-08-13 09:40:08 -05:00
|
|
|
gulong rdisc_changed_id;
|
|
|
|
|
gulong rdisc_timeout_id;
|
2014-01-03 17:03:35 +01:00
|
|
|
NMSettingIP6ConfigPrivacy rdisc_use_tempaddr;
|
2011-10-21 14:25:35 -05:00
|
|
|
/* IP6 config from autoconf */
|
|
|
|
|
NMIP6Config * ac_ip6_config;
|
2009-09-16 13:18:24 +02:00
|
|
|
|
2013-11-07 22:59:43 +01:00
|
|
|
guint linklocal6_timeout_id;
|
|
|
|
|
|
2014-02-21 17:04:59 -05:00
|
|
|
GHashTable * ip6_saved_properties;
|
2012-02-21 15:44:19 +01:00
|
|
|
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
NMDhcpClient * dhcp6_client;
|
2013-05-30 16:53:23 +02:00
|
|
|
NMRDiscDHCPLevel dhcp6_mode;
|
2010-01-14 00:45:10 -08:00
|
|
|
gulong dhcp6_state_sigid;
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
NMDhcp6Config * dhcp6_config;
|
2011-10-21 14:25:35 -05:00
|
|
|
/* IP6 config from DHCP */
|
|
|
|
|
NMIP6Config * dhcp6_ip6_config;
|
2010-01-14 00:45:10 -08:00
|
|
|
|
2012-05-14 15:32:54 +02:00
|
|
|
/* allow autoconnect feature */
|
|
|
|
|
gboolean autoconnect;
|
2011-10-18 13:48:47 +02:00
|
|
|
|
2013-07-25 15:36:45 +02:00
|
|
|
/* master interface for bridge/bond/team slave */
|
2012-11-14 14:05:30 -06:00
|
|
|
NMDevice * master;
|
|
|
|
|
gboolean enslaved;
|
2013-09-11 09:21:17 -05:00
|
|
|
guint master_ready_id;
|
2012-11-14 14:05:30 -06:00
|
|
|
|
2013-01-24 17:47:59 -06:00
|
|
|
/* slave management */
|
|
|
|
|
gboolean is_master;
|
|
|
|
|
GSList * slaves; /* list of SlaveInfo */
|
2012-05-02 10:28:16 -05:00
|
|
|
|
|
|
|
|
NMConnectionProvider *con_provider;
|
2009-07-07 14:34:01 -04:00
|
|
|
} NMDevicePrivate;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
static gboolean nm_device_set_ip4_config (NMDevice *self,
|
2009-08-05 18:03:09 -04:00
|
|
|
NMIP4Config *config,
|
2013-06-26 00:16:45 +02:00
|
|
|
gboolean commit,
|
2009-08-05 18:03:09 -04:00
|
|
|
NMDeviceStateReason *reason);
|
2013-08-01 10:34:46 -05:00
|
|
|
static gboolean ip4_config_merge_and_apply (NMDevice *self,
|
|
|
|
|
NMIP4Config *config,
|
2013-08-01 15:44:53 -05:00
|
|
|
gboolean commit,
|
2013-08-01 10:34:46 -05:00
|
|
|
NMDeviceStateReason *out_reason);
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
static gboolean nm_device_set_ip6_config (NMDevice *self,
|
2009-08-05 18:03:09 -04:00
|
|
|
NMIP6Config *config,
|
2013-06-26 00:16:45 +02:00
|
|
|
gboolean commit,
|
2009-08-05 18:03:09 -04:00
|
|
|
NMDeviceStateReason *reason);
|
2008-11-07 13:57:39 +00:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
static gboolean nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure);
|
|
|
|
|
static void nm_device_slave_notify_enslave (NMDevice *self, gboolean success);
|
|
|
|
|
static void nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason);
|
2011-09-19 14:19:53 +02:00
|
|
|
|
2014-07-22 16:24:07 -05:00
|
|
|
static gboolean addrconf6_start_with_link_ready (NMDevice *self);
|
2013-06-11 17:05:49 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
static gboolean nm_device_get_default_unmanaged (NMDevice *self);
|
2014-05-20 16:39:57 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
static void _set_state_full (NMDevice *self,
|
2014-05-23 18:25:05 -05:00
|
|
|
NMDeviceState state,
|
|
|
|
|
NMDeviceStateReason reason,
|
|
|
|
|
gboolean quitting);
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
static void nm_device_update_hw_address (NMDevice *self);
|
2014-04-10 18:02:52 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/***********************************************************/
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static GQuark
|
|
|
|
|
nm_device_error_quark (void)
|
|
|
|
|
{
|
|
|
|
|
static GQuark quark = 0;
|
|
|
|
|
if (!quark)
|
|
|
|
|
quark = g_quark_from_static_string ("nm-device-error");
|
|
|
|
|
return quark;
|
|
|
|
|
}
|
2012-11-14 14:05:30 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
#define NM_DEVICE_ERROR (nm_device_error_quark ())
|
2012-11-12 13:29:06 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/***********************************************************/
|
2013-04-04 10:20:24 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
#define QUEUED_PREFIX "queued state change to "
|
2013-10-21 12:50:58 -04:00
|
|
|
|
2014-05-20 15:13:59 -05:00
|
|
|
static const char *state_table[] = {
|
|
|
|
|
[NM_DEVICE_STATE_UNKNOWN] = QUEUED_PREFIX "unknown",
|
|
|
|
|
[NM_DEVICE_STATE_UNMANAGED] = QUEUED_PREFIX "unmanaged",
|
|
|
|
|
[NM_DEVICE_STATE_UNAVAILABLE] = QUEUED_PREFIX "unavailable",
|
|
|
|
|
[NM_DEVICE_STATE_DISCONNECTED] = QUEUED_PREFIX "disconnected",
|
|
|
|
|
[NM_DEVICE_STATE_PREPARE] = QUEUED_PREFIX "prepare",
|
|
|
|
|
[NM_DEVICE_STATE_CONFIG] = QUEUED_PREFIX "config",
|
|
|
|
|
[NM_DEVICE_STATE_NEED_AUTH] = QUEUED_PREFIX "need-auth",
|
|
|
|
|
[NM_DEVICE_STATE_IP_CONFIG] = QUEUED_PREFIX "ip-config",
|
|
|
|
|
[NM_DEVICE_STATE_IP_CHECK] = QUEUED_PREFIX "ip-check",
|
|
|
|
|
[NM_DEVICE_STATE_SECONDARIES] = QUEUED_PREFIX "secondaries",
|
|
|
|
|
[NM_DEVICE_STATE_ACTIVATED] = QUEUED_PREFIX "activated",
|
|
|
|
|
[NM_DEVICE_STATE_DEACTIVATING] = QUEUED_PREFIX "deactivating",
|
|
|
|
|
[NM_DEVICE_STATE_FAILED] = QUEUED_PREFIX "failed",
|
|
|
|
|
};
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static const char *
|
|
|
|
|
queued_state_to_string (NMDeviceState state)
|
|
|
|
|
{
|
2014-07-26 21:41:41 +02:00
|
|
|
if ((gsize) state < G_N_ELEMENTS (state_table))
|
2014-05-20 15:13:59 -05:00
|
|
|
return state_table[state];
|
|
|
|
|
return state_table[NM_DEVICE_STATE_UNKNOWN];
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
2013-10-21 12:50:58 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static const char *
|
|
|
|
|
state_to_string (NMDeviceState state)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2014-05-20 15:03:27 -05:00
|
|
|
return queued_state_to_string (state) + strlen (QUEUED_PREFIX);
|
|
|
|
|
}
|
2009-07-07 14:34:01 -04:00
|
|
|
|
2014-05-20 15:13:59 -05:00
|
|
|
static const char *reason_table[] = {
|
|
|
|
|
[NM_DEVICE_STATE_REASON_NONE] = "none",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_NOW_MANAGED] = "managed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_NOW_UNMANAGED] = "unmanaged",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_CONFIG_FAILED] = "config-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE] = "ip-config-unavailable",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED] = "ip-config-expired",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_NO_SECRETS] = "no-secrets",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT] = "supplicant-disconnect",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED] = "supplicant-config-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED] = "supplicant-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT] = "supplicant-timeout",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_PPP_START_FAILED] = "ppp-start-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_PPP_DISCONNECT] = "ppp-disconnect",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_PPP_FAILED] = "ppp-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_DHCP_START_FAILED] = "dhcp-start-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_DHCP_ERROR] = "dhcp-error",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_DHCP_FAILED] = "dhcp-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_SHARED_START_FAILED] = "sharing-start-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_SHARED_FAILED] = "sharing-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED] = "autoip-start-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_AUTOIP_ERROR] = "autoip-error",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_AUTOIP_FAILED] = "autoip-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_MODEM_BUSY] = "modem-busy",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE] = "modem-no-dialtone",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER] = "modem-no-carrier",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT] = "modem-dial-timeout",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED] = "modem-dial-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED] = "modem-init-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_GSM_APN_FAILED] = "gsm-apn-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING] = "gsm-registration-idle",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED] = "gsm-registration-denied",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT] = "gsm-registration-timeout",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED] = "gsm-registration-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED] = "gsm-pin-check-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_FIRMWARE_MISSING] = "firmware-missing",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_REMOVED] = "removed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_SLEEPING] = "sleeping",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_CONNECTION_REMOVED] = "connection-removed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_USER_REQUESTED] = "user-requested",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_CARRIER] = "carrier-changed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED] = "connection-assumed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE] = "supplicant-available",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND] = "modem-not-found",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_BT_FAILED] = "bluetooth-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED] = "gsm-sim-not-inserted",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED] = "gsm-sim-pin-required",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED] = "gsm-sim-puk-required",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_GSM_SIM_WRONG] = "gsm-sim-wrong",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_INFINIBAND_MODE] = "infiniband-mode",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED] = "dependency-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_BR2684_FAILED] = "br2684-bridge-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE] = "modem-manager-unavailable",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_SSID_NOT_FOUND] = "ssid-not-found",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED] = "secondary-connection-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED] = "dcb-fcoe-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED] = "teamd-control-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_MODEM_FAILED] = "modem-failed",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_MODEM_AVAILABLE] = "modem-available",
|
|
|
|
|
[NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT] = "sim-pin-incorrect",
|
|
|
|
|
};
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static const char *
|
|
|
|
|
reason_to_string (NMDeviceStateReason reason)
|
|
|
|
|
{
|
2014-07-26 21:41:41 +02:00
|
|
|
if ((gsize) reason < G_N_ELEMENTS (reason_table))
|
2014-05-20 15:13:59 -05:00
|
|
|
return reason_table[reason];
|
|
|
|
|
return reason_table[NM_DEVICE_STATE_REASON_UNKNOWN];
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/***********************************************************/
|
|
|
|
|
|
2013-10-15 21:03:42 -05:00
|
|
|
gboolean
|
2014-02-21 17:04:59 -05:00
|
|
|
nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value)
|
|
|
|
|
{
|
2014-03-04 17:01:10 -05:00
|
|
|
return nm_platform_sysctl_set (nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property), value);
|
2010-05-03 03:42:43 -07:00
|
|
|
}
|
|
|
|
|
|
2012-06-01 16:48:57 +02:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
device_has_capability (NMDevice *self, NMDeviceCapabilities caps)
|
2012-06-01 16:48:57 +02:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
return !!(NM_DEVICE_GET_PRIVATE (self)->capabilities & caps);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
2012-06-01 16:48:57 +02:00
|
|
|
|
2014-05-20 16:09:22 -05:00
|
|
|
/***********************************************************/
|
2013-01-22 16:43:15 +01:00
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_dbus_export (NMDevice *self)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
2014-05-20 16:25:21 -05:00
|
|
|
static guint32 devcount = 0;
|
2009-07-07 14:34:01 -04:00
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
2009-07-07 14:34:01 -04:00
|
|
|
g_return_if_fail (priv->path == NULL);
|
|
|
|
|
|
2014-05-20 16:25:21 -05:00
|
|
|
priv->path = g_strdup_printf ("/org/freedesktop/NetworkManager/Devices/%d", devcount++);
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "exported as %s", priv->path);
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_dbus_manager_register_object (nm_dbus_manager_get (), priv->path, self);
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
nm_device_get_path (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
|
2009-07-07 14:34:01 -04:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->path;
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
nm_device_get_udi (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
|
2009-07-07 14:34:01 -04:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->udi;
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
nm_device_get_iface (NMDevice *self)
|
|
|
|
|
{
|
2014-08-02 15:14:26 +02:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), 0);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2009-07-07 14:34:01 -04:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->iface;
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2010-04-21 14:58:25 -07:00
|
|
|
int
|
|
|
|
|
nm_device_get_ifindex (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, 0);
|
|
|
|
|
|
|
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->ifindex;
|
|
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2013-08-22 19:15:05 +02:00
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_is_software (NMDevice *self)
|
2013-08-22 19:15:05 +02:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-08-22 19:15:05 +02:00
|
|
|
|
|
|
|
|
return priv->is_software;
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
const char *
|
2007-12-06 14:51:43 +00:00
|
|
|
nm_device_get_ip_iface (NMDevice *self)
|
|
|
|
|
{
|
2009-07-07 14:34:01 -04:00
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
|
2007-12-06 14:51:43 +00:00
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
|
2009-07-07 14:34:01 -04:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
2007-12-06 14:51:43 +00:00
|
|
|
/* If it's not set, default to iface */
|
2009-07-07 14:34:01 -04:00
|
|
|
return priv->ip_iface ? priv->ip_iface : priv->iface;
|
2007-12-06 14:51:43 +00:00
|
|
|
}
|
|
|
|
|
|
2010-04-21 14:58:25 -07:00
|
|
|
int
|
|
|
|
|
nm_device_get_ip_ifindex (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (self != NULL, 0);
|
|
|
|
|
|
|
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
/* If it's not set, default to iface */
|
|
|
|
|
return priv->ip_iface ? priv->ip_ifindex : priv->ifindex;
|
|
|
|
|
}
|
2007-12-06 14:51:43 +00:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_device_set_ip_iface (NMDevice *self, const char *iface)
|
|
|
|
|
{
|
2010-04-21 14:58:25 -07:00
|
|
|
NMDevicePrivate *priv;
|
2010-06-10 10:16:39 -07:00
|
|
|
char *old_ip_iface;
|
2010-04-21 14:58:25 -07:00
|
|
|
|
2007-12-06 14:51:43 +00:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
|
|
|
|
|
2010-04-21 14:58:25 -07:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-02-21 17:04:59 -05:00
|
|
|
if (!g_strcmp0 (iface, priv->ip_iface))
|
|
|
|
|
return;
|
|
|
|
|
|
2010-06-10 10:16:39 -07:00
|
|
|
old_ip_iface = priv->ip_iface;
|
2010-04-21 14:58:25 -07:00
|
|
|
priv->ip_ifindex = 0;
|
|
|
|
|
|
|
|
|
|
priv->ip_iface = g_strdup (iface);
|
|
|
|
|
if (priv->ip_iface) {
|
2013-01-21 15:12:24 +01:00
|
|
|
priv->ip_ifindex = nm_platform_link_get_ifindex (priv->ip_iface);
|
core: don't up devices during IP configuration stages
Assumed connections shouldn't require touching the device, and the
device should was already set IFF_UP during stage2 (which is
skipped for assumed connections). Instead, what the code was really
trying to do, was to ensure tha the IP interface the device was
going to use was up.
The only cases where the IP interface might *not* be up after stage2
is where the IP interface is different than the device's interface,
like for Bluetooth, ADSL, WWAN, and PPPoE. Move the call to
nm_platform_link_set_up() into nm_device_set_ip_iface() which all
those device types will call.
Thus, only the device types that really need to up their IP interface
will do so, but other devices (including when activating assumed
connections) that don't need to do this, won't do it.
2013-11-08 10:58:35 -06:00
|
|
|
if (priv->ip_ifindex > 0) {
|
2014-07-24 17:14:30 -05:00
|
|
|
if (nm_platform_check_support_user_ipv6ll ())
|
|
|
|
|
nm_platform_link_set_user_ipv6ll_enabled (priv->ip_ifindex, TRUE);
|
|
|
|
|
|
core: don't up devices during IP configuration stages
Assumed connections shouldn't require touching the device, and the
device should was already set IFF_UP during stage2 (which is
skipped for assumed connections). Instead, what the code was really
trying to do, was to ensure tha the IP interface the device was
going to use was up.
The only cases where the IP interface might *not* be up after stage2
is where the IP interface is different than the device's interface,
like for Bluetooth, ADSL, WWAN, and PPPoE. Move the call to
nm_platform_link_set_up() into nm_device_set_ip_iface() which all
those device types will call.
Thus, only the device types that really need to up their IP interface
will do so, but other devices (including when activating assumed
connections) that don't need to do this, won't do it.
2013-11-08 10:58:35 -06:00
|
|
|
if (!nm_platform_link_is_up (priv->ip_ifindex))
|
|
|
|
|
nm_platform_link_set_up (priv->ip_ifindex);
|
|
|
|
|
} else {
|
2012-05-15 09:44:49 -05:00
|
|
|
/* Device IP interface must always be a kernel network interface */
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_HW, "failed to look up interface index");
|
2010-04-21 14:58:25 -07:00
|
|
|
}
|
|
|
|
|
}
|
2010-06-10 10:16:39 -07:00
|
|
|
|
2014-02-21 17:04:59 -05:00
|
|
|
/* We don't care about any saved values from the old iface */
|
|
|
|
|
g_hash_table_remove_all (priv->ip6_saved_properties);
|
2013-10-24 13:55:06 -04:00
|
|
|
|
2010-06-10 10:16:39 -07:00
|
|
|
/* Emit change notification */
|
|
|
|
|
if (g_strcmp0 (old_ip_iface, priv->ip_iface))
|
2011-11-18 00:34:08 -06:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE);
|
2010-06-10 10:16:39 -07:00
|
|
|
g_free (old_ip_iface);
|
2007-12-06 14:51:43 +00:00
|
|
|
}
|
|
|
|
|
|
2014-04-10 15:29:45 -05:00
|
|
|
static gboolean
|
|
|
|
|
get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid)
|
|
|
|
|
{
|
|
|
|
|
NMLinkType link_type;
|
|
|
|
|
const guint8 *hwaddr = NULL;
|
|
|
|
|
size_t hwaddr_len = 0;
|
|
|
|
|
int ifindex;
|
|
|
|
|
gboolean success;
|
|
|
|
|
|
|
|
|
|
/* If we get here, we *must* have a kernel netdev, which implies an ifindex */
|
|
|
|
|
ifindex = nm_device_get_ip_ifindex (self);
|
|
|
|
|
g_assert (ifindex);
|
|
|
|
|
|
|
|
|
|
link_type = nm_platform_link_get_type (ifindex);
|
|
|
|
|
g_return_val_if_fail (link_type > NM_LINK_TYPE_UNKNOWN, 0);
|
|
|
|
|
|
|
|
|
|
hwaddr = nm_platform_link_get_address (ifindex, &hwaddr_len);
|
|
|
|
|
if (!hwaddr_len)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
success = nm_utils_get_ipv6_interface_identifier (link_type,
|
|
|
|
|
hwaddr,
|
|
|
|
|
hwaddr_len,
|
|
|
|
|
out_iid);
|
|
|
|
|
if (!success) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_HW, "failed to generate interface identifier "
|
|
|
|
|
"for link type %u hwaddr_len %zu", link_type, hwaddr_len);
|
2014-04-10 15:29:45 -05:00
|
|
|
}
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-24 17:14:30 -05:00
|
|
|
static gboolean
|
|
|
|
|
nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid)
|
|
|
|
|
{
|
|
|
|
|
return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid);
|
|
|
|
|
}
|
|
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
const char *
|
|
|
|
|
nm_device_get_driver (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
|
2009-07-07 14:34:01 -04:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->driver;
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2012-06-01 16:48:57 +02:00
|
|
|
const char *
|
|
|
|
|
nm_device_get_driver_version (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->driver_version;
|
|
|
|
|
}
|
|
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
NMDeviceType
|
|
|
|
|
nm_device_get_device_type (NMDevice *self)
|
|
|
|
|
{
|
2008-06-10 15:54:23 +00:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_TYPE_UNKNOWN);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2009-07-07 14:34:01 -04:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->type;
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-05-17 17:01:50 -05:00
|
|
|
/**
|
|
|
|
|
* nm_device_get_priority():
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the #NMDevice
|
2012-05-17 17:01:50 -05:00
|
|
|
*
|
|
|
|
|
* Returns: the device's routing priority. Lower numbers means a "better"
|
|
|
|
|
* device, eg higher priority.
|
|
|
|
|
*/
|
2008-09-30 15:04:10 +00:00
|
|
|
int
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_get_priority (NMDevice *self)
|
2008-09-30 15:04:10 +00:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), 100);
|
2012-05-17 17:01:50 -05:00
|
|
|
|
|
|
|
|
/* Device 'priority' is used for two things:
|
|
|
|
|
*
|
|
|
|
|
* a) two devices on the same IP subnet: the "better" (ie, lower number)
|
|
|
|
|
* device is the default outgoing device for that subnet
|
|
|
|
|
* b) default route: the "better" device gets the default route. This can
|
|
|
|
|
* always be modified by setting a connection to never-default=TRUE, in
|
|
|
|
|
* which case that device will never take the default route when
|
|
|
|
|
* it's using that connection.
|
|
|
|
|
*/
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
switch (nm_device_get_device_type (self)) {
|
2012-05-17 17:01:50 -05:00
|
|
|
case NM_DEVICE_TYPE_ETHERNET:
|
|
|
|
|
return 1;
|
|
|
|
|
case NM_DEVICE_TYPE_INFINIBAND:
|
|
|
|
|
return 2;
|
|
|
|
|
case NM_DEVICE_TYPE_ADSL:
|
|
|
|
|
return 3;
|
|
|
|
|
case NM_DEVICE_TYPE_WIMAX:
|
|
|
|
|
return 4;
|
|
|
|
|
case NM_DEVICE_TYPE_BOND:
|
|
|
|
|
return 5;
|
2013-07-25 15:36:45 +02:00
|
|
|
case NM_DEVICE_TYPE_TEAM:
|
2012-05-17 17:01:50 -05:00
|
|
|
return 6;
|
2013-07-25 15:36:45 +02:00
|
|
|
case NM_DEVICE_TYPE_VLAN:
|
2012-05-17 17:01:50 -05:00
|
|
|
return 7;
|
2013-07-25 15:36:45 +02:00
|
|
|
case NM_DEVICE_TYPE_MODEM:
|
2012-05-17 17:01:50 -05:00
|
|
|
return 8;
|
2013-07-25 15:36:45 +02:00
|
|
|
case NM_DEVICE_TYPE_BT:
|
2012-05-17 17:01:50 -05:00
|
|
|
return 9;
|
2013-07-25 15:36:45 +02:00
|
|
|
case NM_DEVICE_TYPE_WIFI:
|
2012-05-17 17:01:50 -05:00
|
|
|
return 10;
|
2013-07-25 15:36:45 +02:00
|
|
|
case NM_DEVICE_TYPE_OLPC_MESH:
|
|
|
|
|
return 11;
|
2012-05-17 17:01:50 -05:00
|
|
|
default:
|
|
|
|
|
return 20;
|
|
|
|
|
}
|
2008-09-30 15:04:10 +00:00
|
|
|
}
|
|
|
|
|
|
2009-07-07 14:24:12 -04:00
|
|
|
const char *
|
|
|
|
|
nm_device_get_type_desc (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
|
2009-07-07 14:34:01 -04:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->type_desc;
|
2009-07-07 14:24:12 -04:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 16:09:22 -05:00
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_has_carrier (NMDevice *self)
|
2014-05-20 16:09:22 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->carrier;
|
2014-05-20 16:09:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMActRequest *
|
|
|
|
|
nm_device_get_act_request (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->act_request;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NMConnection *
|
|
|
|
|
nm_device_get_connection (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
return priv->act_request ? nm_act_request_get_connection (priv->act_request) : NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RfKillType
|
|
|
|
|
nm_device_get_rfkill_type (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
|
|
|
|
|
|
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->rfkill_type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char *
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_get_physical_port_id (NMDevice *self)
|
2014-05-20 16:09:22 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->physical_port_id;
|
2014-05-20 16:09:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***********************************************************/
|
|
|
|
|
|
2014-05-27 16:42:19 -04:00
|
|
|
static gboolean
|
|
|
|
|
nm_device_uses_generated_connection (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
|
|
|
|
|
connection = nm_device_get_connection (self);
|
|
|
|
|
if (!connection)
|
|
|
|
|
return FALSE;
|
|
|
|
|
return nm_settings_connection_get_nm_generated (NM_SETTINGS_CONNECTION (connection));
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-14 14:05:30 -06:00
|
|
|
static SlaveInfo *
|
|
|
|
|
find_slave_info (NMDevice *self, NMDevice *slave)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
SlaveInfo *info;
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
|
|
for (iter = priv->slaves; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
info = iter->data;
|
|
|
|
|
if (info->slave == slave)
|
|
|
|
|
return info;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_slave_info (SlaveInfo *info)
|
|
|
|
|
{
|
|
|
|
|
g_signal_handler_disconnect (info->slave, info->watch_id);
|
|
|
|
|
g_clear_object (&info->slave);
|
|
|
|
|
memset (info, 0, sizeof (*info));
|
|
|
|
|
g_free (info);
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-28 18:35:30 -06:00
|
|
|
/**
|
|
|
|
|
* nm_device_enslave_slave:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the master device
|
2012-02-28 18:35:30 -06:00
|
|
|
* @slave: the slave device to enslave
|
2014-02-25 16:44:01 -05:00
|
|
|
* @connection: (allow-none): the slave device's connection
|
2012-02-28 18:35:30 -06:00
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* If @self is capable of enslaving other devices (ie it's a bridge, bond, team,
|
2013-07-25 15:36:45 +02:00
|
|
|
* etc) then this function enslaves @slave.
|
2012-02-28 18:35:30 -06:00
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success, %FALSE on failure or if this device cannot enslave
|
|
|
|
|
* other devices.
|
|
|
|
|
*/
|
2012-11-14 14:05:30 -06:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *connection)
|
2012-02-28 18:35:30 -06:00
|
|
|
{
|
2012-11-14 14:05:30 -06:00
|
|
|
SlaveInfo *info;
|
|
|
|
|
gboolean success = FALSE;
|
2014-02-25 16:44:01 -05:00
|
|
|
gboolean configure;
|
2012-11-14 14:05:30 -06:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (self != NULL, FALSE);
|
2012-02-28 18:35:30 -06:00
|
|
|
g_return_val_if_fail (slave != NULL, FALSE);
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE);
|
2012-02-28 18:35:30 -06:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
info = find_slave_info (self, slave);
|
2012-11-14 14:05:30 -06:00
|
|
|
if (!info)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2014-02-25 16:44:01 -05:00
|
|
|
if (info->enslaved)
|
|
|
|
|
success = TRUE;
|
|
|
|
|
else {
|
|
|
|
|
configure = (info->configure && connection != NULL);
|
|
|
|
|
if (configure)
|
|
|
|
|
g_return_val_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE);
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
success = NM_DEVICE_GET_CLASS (self)->enslave_slave (self, slave, connection, configure);
|
2014-02-25 16:44:01 -05:00
|
|
|
info->enslaved = success;
|
|
|
|
|
}
|
2013-10-21 12:50:58 -04:00
|
|
|
|
|
|
|
|
nm_device_slave_notify_enslave (info->slave, success);
|
2013-01-18 14:34:40 -06:00
|
|
|
|
|
|
|
|
/* Ensure the device's hardware address is up-to-date; it often changes
|
|
|
|
|
* when slaves change.
|
|
|
|
|
*/
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_update_hw_address (self);
|
2013-01-18 14:34:40 -06:00
|
|
|
|
2013-01-25 11:59:05 -06:00
|
|
|
/* Restart IP configuration if we're waiting for slaves. Do this
|
|
|
|
|
* after updating the hardware address as IP config may need the
|
|
|
|
|
* new address.
|
|
|
|
|
*/
|
|
|
|
|
if (success) {
|
2014-07-15 13:36:24 +02:00
|
|
|
if (NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT)
|
|
|
|
|
nm_device_activate_stage3_ip4_start (self);
|
2013-01-25 11:59:05 -06:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT)
|
|
|
|
|
nm_device_activate_stage3_ip6_start (self);
|
2013-01-25 11:59:05 -06:00
|
|
|
}
|
|
|
|
|
|
2012-11-14 14:05:30 -06:00
|
|
|
return success;
|
2012-02-28 18:35:30 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2012-11-14 14:05:30 -06:00
|
|
|
* nm_device_release_one_slave:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the master device
|
2012-02-28 18:35:30 -06:00
|
|
|
* @slave: the slave device to release
|
2014-07-15 13:36:24 +02:00
|
|
|
* @configure: whether @self needs to actually release @slave
|
device: fix warning releasing of slave when slave device gets removed
When the slave device gets removed, the master is not in a state-change when
calling nm_device_release_one_slave(). This triggers a warning [1].
[1] backtrace:
#0 0x0000003370c504e9 in g_logv (log_domain=0x4c144c "NetworkManager", log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, args=args@entry=0x7fff8b1d35b0) at gmessages.c:989
#1 0x0000003370c5063f in g_log (log_domain=log_domain@entry=0x4c144c "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_WARNING, format=format@entry=0x3370cc1fdc "%s") at gmessages.c:1025
#2 0x0000003370c50956 in g_warn_message (domain=domain@entry=0x4c144c "NetworkManager", file=file@entry=0x4b14d5 "devices/nm-device.c", line=line@entry=841, func=func@entry=0x4b48f0 <__FUNCTION__.35456> "nm_device_release_one_slave",
warnexpr=warnexpr@entry=0x0) at gmessages.c:1058
#3 0x0000000000436c30 in nm_device_release_one_slave (dev=dev@entry=0xd92540, slave=slave@entry=0xdb0e50, configure=configure@entry=1) at devices/nm-device.c:841
#4 0x000000000043a779 in slave_state_changed (slave=0xdb0e50, slave_new_state=NM_DEVICE_STATE_UNMANAGED, slave_old_state=NM_DEVICE_STATE_ACTIVATED, reason=<optimized out>, self=0xd92540) at devices/nm-device.c:1214
#5 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#6 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d3a00, fn=0x43a677 <slave_state_changed>, rvalue=0x7fff8b1d3970, avalue=avalue@entry=0x7fff8b1d38f0) at ../src/x86/ffi64.c:522
#7 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd76120, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#8 0x0000003371c10298 in g_closure_invoke (closure=0xd76120, return_value=return_value@entry=0x0, n_param_values=4, param_values=param_values@entry=0x7fff8b1d3c00, invocation_hint=invocation_hint@entry=0x7fff8b1d3ba0) at gclosure.c:777
#9 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xd9d850, detail=detail@entry=0, instance=instance@entry=0xdb0e50, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d3c00) at gsignal.c:3586
#10 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xdb0e50, signal_id=signal_id@entry=68, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d3e38) at gsignal.c:3330
#11 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xdb0e50, detailed_signal=detailed_signal@entry=0x4c3ce2 "state-changed") at gsignal.c:3426
#12 0x000000000043754f in _set_state_full (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:6689
#13 0x000000000043797c in nm_device_state_changed (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:6823
#14 0x0000000000439fe7 in nm_device_set_unmanaged (device=device@entry=0xdb0e50, flag=flag@entry=NM_UNMANAGED_INTERNAL, unmanaged=unmanaged@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:5983
#15 0x00000000004799c2 in remove_device (manager=manager@entry=0xd86150, device=0xdb0e50, quitting=quitting@entry=0) at nm-manager.c:769
#16 0x000000000047e3bf in platform_link_cb (platform=<optimized out>, ifindex=35, plink=<optimized out>, change_type=<optimized out>, reason=<optimized out>, user_data=<optimized out>) at nm-manager.c:2123
#17 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#18 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d4320, fn=0x47e34b <platform_link_cb>, rvalue=0x7fff8b1d4290, avalue=avalue@entry=0x7fff8b1d4210) at ../src/x86/ffi64.c:522
#19 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd32e40, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#20 0x0000003371c10298 in g_closure_invoke (closure=0xd32e40, return_value=return_value@entry=0x0, n_param_values=5, param_values=param_values@entry=0x7fff8b1d4520, invocation_hint=invocation_hint@entry=0x7fff8b1d44c0) at gclosure.c:777
#21 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xcf5780, detail=detail@entry=0, instance=instance@entry=0xcf78a0, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d4520) at gsignal.c:3586
#22 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xcf78a0, signal_id=signal_id@entry=2, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d4778) at gsignal.c:3330
#23 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xcf78a0, detailed_signal=detailed_signal@entry=0x4b183d "link-changed") at gsignal.c:3426
#24 0x000000000044c6f3 in announce_object (platform=platform@entry=0xcf78a0, object=0xde1720, change_type=change_type@entry=NM_PLATFORM_SIGNAL_REMOVED, reason=reason@entry=NM_PLATFORM_REASON_EXTERNAL)
at platform/nm-linux-platform.c:1572
#25 0x000000000044ec07 in event_notification (msg=<optimized out>, user_data=<optimized out>) at platform/nm-linux-platform.c:1886
#26 0x0000003844c1117f in nl_cb_call (msg=<optimized out>, type=<optimized out>, cb=<optimized out>) at ../include/netlink-private/netlink.h:141
#27 recvmsgs (cb=0xcf7240, sk=0xcf7330) at nl.c:952
#28 nl_recvmsgs_report (sk=0xcf7330, cb=0xcf7240) at nl.c:1003
#29 0x0000003844c11549 in nl_recvmsgs (sk=<optimized out>, cb=<optimized out>) at nl.c:1027
#30 0x0000003844c11569 in nl_recvmsgs_default (sk=<optimized out>) at nl.c:1041
#31 0x000000000044e955 in event_handler (channel=<optimized out>, io_condition=<optimized out>, user_data=0xcf78a0) at platform/nm-linux-platform.c:3804
#32 0x0000003370c492a6 in g_main_dispatch (context=0xcf5190) at gmain.c:3066
#33 g_main_context_dispatch (context=context@entry=0xcf5190) at gmain.c:3642
#34 0x0000003370c49628 in g_main_context_iterate (context=0xcf5190, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3713
#35 0x0000003370c49a3a in g_main_loop_run (loop=0xcf4e30) at gmain.c:3907
#36 0x0000000000429f15 in main (argc=1, argv=0x7fff8b1d4f38) at main.c:678
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-23 11:18:45 +02:00
|
|
|
* @reason: the state change reason for the @slave
|
2012-02-28 18:35:30 -06:00
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* If @self is capable of enslaving other devices (ie it's a bridge, bond, team,
|
2014-02-25 16:44:01 -05:00
|
|
|
* etc) then this function releases the previously enslaved @slave and/or
|
2014-07-15 13:36:24 +02:00
|
|
|
* updates the state of @self and @slave to reflect its release.
|
2012-02-28 18:35:30 -06:00
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success, %FALSE on failure, if this device cannot enslave
|
|
|
|
|
* other devices, or if @slave was never enslaved.
|
|
|
|
|
*/
|
2012-11-14 14:05:30 -06:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_release_one_slave (NMDevice *self, NMDevice *slave, gboolean configure, NMDeviceStateReason reason)
|
2012-11-14 14:05:30 -06:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2012-11-14 14:05:30 -06:00
|
|
|
SlaveInfo *info;
|
|
|
|
|
gboolean success = FALSE;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (slave != NULL, FALSE);
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->release_slave != NULL, FALSE);
|
2012-11-14 14:05:30 -06:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
info = find_slave_info (self, slave);
|
2012-11-14 14:05:30 -06:00
|
|
|
if (!info)
|
|
|
|
|
return FALSE;
|
2014-02-25 16:41:33 -05:00
|
|
|
priv->slaves = g_slist_remove (priv->slaves, info);
|
2012-11-14 14:05:30 -06:00
|
|
|
|
|
|
|
|
if (info->enslaved) {
|
2014-07-15 13:36:24 +02:00
|
|
|
success = NM_DEVICE_GET_CLASS (self)->release_slave (self, slave, configure);
|
2014-02-25 16:41:33 -05:00
|
|
|
/* The release_slave() implementation logs success/failure (in the
|
|
|
|
|
* correct device-specific log domain), so we don't have to do anything.
|
|
|
|
|
*/
|
2012-11-14 14:05:30 -06:00
|
|
|
}
|
2013-12-05 09:13:26 -05:00
|
|
|
|
device: fix warning releasing of slave when slave device gets removed
When the slave device gets removed, the master is not in a state-change when
calling nm_device_release_one_slave(). This triggers a warning [1].
[1] backtrace:
#0 0x0000003370c504e9 in g_logv (log_domain=0x4c144c "NetworkManager", log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, args=args@entry=0x7fff8b1d35b0) at gmessages.c:989
#1 0x0000003370c5063f in g_log (log_domain=log_domain@entry=0x4c144c "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_WARNING, format=format@entry=0x3370cc1fdc "%s") at gmessages.c:1025
#2 0x0000003370c50956 in g_warn_message (domain=domain@entry=0x4c144c "NetworkManager", file=file@entry=0x4b14d5 "devices/nm-device.c", line=line@entry=841, func=func@entry=0x4b48f0 <__FUNCTION__.35456> "nm_device_release_one_slave",
warnexpr=warnexpr@entry=0x0) at gmessages.c:1058
#3 0x0000000000436c30 in nm_device_release_one_slave (dev=dev@entry=0xd92540, slave=slave@entry=0xdb0e50, configure=configure@entry=1) at devices/nm-device.c:841
#4 0x000000000043a779 in slave_state_changed (slave=0xdb0e50, slave_new_state=NM_DEVICE_STATE_UNMANAGED, slave_old_state=NM_DEVICE_STATE_ACTIVATED, reason=<optimized out>, self=0xd92540) at devices/nm-device.c:1214
#5 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#6 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d3a00, fn=0x43a677 <slave_state_changed>, rvalue=0x7fff8b1d3970, avalue=avalue@entry=0x7fff8b1d38f0) at ../src/x86/ffi64.c:522
#7 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd76120, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#8 0x0000003371c10298 in g_closure_invoke (closure=0xd76120, return_value=return_value@entry=0x0, n_param_values=4, param_values=param_values@entry=0x7fff8b1d3c00, invocation_hint=invocation_hint@entry=0x7fff8b1d3ba0) at gclosure.c:777
#9 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xd9d850, detail=detail@entry=0, instance=instance@entry=0xdb0e50, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d3c00) at gsignal.c:3586
#10 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xdb0e50, signal_id=signal_id@entry=68, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d3e38) at gsignal.c:3330
#11 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xdb0e50, detailed_signal=detailed_signal@entry=0x4c3ce2 "state-changed") at gsignal.c:3426
#12 0x000000000043754f in _set_state_full (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:6689
#13 0x000000000043797c in nm_device_state_changed (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:6823
#14 0x0000000000439fe7 in nm_device_set_unmanaged (device=device@entry=0xdb0e50, flag=flag@entry=NM_UNMANAGED_INTERNAL, unmanaged=unmanaged@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:5983
#15 0x00000000004799c2 in remove_device (manager=manager@entry=0xd86150, device=0xdb0e50, quitting=quitting@entry=0) at nm-manager.c:769
#16 0x000000000047e3bf in platform_link_cb (platform=<optimized out>, ifindex=35, plink=<optimized out>, change_type=<optimized out>, reason=<optimized out>, user_data=<optimized out>) at nm-manager.c:2123
#17 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#18 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d4320, fn=0x47e34b <platform_link_cb>, rvalue=0x7fff8b1d4290, avalue=avalue@entry=0x7fff8b1d4210) at ../src/x86/ffi64.c:522
#19 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd32e40, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#20 0x0000003371c10298 in g_closure_invoke (closure=0xd32e40, return_value=return_value@entry=0x0, n_param_values=5, param_values=param_values@entry=0x7fff8b1d4520, invocation_hint=invocation_hint@entry=0x7fff8b1d44c0) at gclosure.c:777
#21 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xcf5780, detail=detail@entry=0, instance=instance@entry=0xcf78a0, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d4520) at gsignal.c:3586
#22 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xcf78a0, signal_id=signal_id@entry=2, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d4778) at gsignal.c:3330
#23 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xcf78a0, detailed_signal=detailed_signal@entry=0x4b183d "link-changed") at gsignal.c:3426
#24 0x000000000044c6f3 in announce_object (platform=platform@entry=0xcf78a0, object=0xde1720, change_type=change_type@entry=NM_PLATFORM_SIGNAL_REMOVED, reason=reason@entry=NM_PLATFORM_REASON_EXTERNAL)
at platform/nm-linux-platform.c:1572
#25 0x000000000044ec07 in event_notification (msg=<optimized out>, user_data=<optimized out>) at platform/nm-linux-platform.c:1886
#26 0x0000003844c1117f in nl_cb_call (msg=<optimized out>, type=<optimized out>, cb=<optimized out>) at ../include/netlink-private/netlink.h:141
#27 recvmsgs (cb=0xcf7240, sk=0xcf7330) at nl.c:952
#28 nl_recvmsgs_report (sk=0xcf7330, cb=0xcf7240) at nl.c:1003
#29 0x0000003844c11549 in nl_recvmsgs (sk=<optimized out>, cb=<optimized out>) at nl.c:1027
#30 0x0000003844c11569 in nl_recvmsgs_default (sk=<optimized out>) at nl.c:1041
#31 0x000000000044e955 in event_handler (channel=<optimized out>, io_condition=<optimized out>, user_data=0xcf78a0) at platform/nm-linux-platform.c:3804
#32 0x0000003370c492a6 in g_main_dispatch (context=0xcf5190) at gmain.c:3066
#33 g_main_context_dispatch (context=context@entry=0xcf5190) at gmain.c:3642
#34 0x0000003370c49628 in g_main_context_iterate (context=0xcf5190, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3713
#35 0x0000003370c49a3a in g_main_loop_run (loop=0xcf4e30) at gmain.c:3907
#36 0x0000000000429f15 in main (argc=1, argv=0x7fff8b1d4f38) at main.c:678
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-23 11:18:45 +02:00
|
|
|
if (!configure) {
|
|
|
|
|
g_warn_if_fail (reason == NM_DEVICE_STATE_REASON_NONE);
|
2014-02-25 16:44:01 -05:00
|
|
|
reason = NM_DEVICE_STATE_REASON_NONE;
|
device: fix warning releasing of slave when slave device gets removed
When the slave device gets removed, the master is not in a state-change when
calling nm_device_release_one_slave(). This triggers a warning [1].
[1] backtrace:
#0 0x0000003370c504e9 in g_logv (log_domain=0x4c144c "NetworkManager", log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, args=args@entry=0x7fff8b1d35b0) at gmessages.c:989
#1 0x0000003370c5063f in g_log (log_domain=log_domain@entry=0x4c144c "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_WARNING, format=format@entry=0x3370cc1fdc "%s") at gmessages.c:1025
#2 0x0000003370c50956 in g_warn_message (domain=domain@entry=0x4c144c "NetworkManager", file=file@entry=0x4b14d5 "devices/nm-device.c", line=line@entry=841, func=func@entry=0x4b48f0 <__FUNCTION__.35456> "nm_device_release_one_slave",
warnexpr=warnexpr@entry=0x0) at gmessages.c:1058
#3 0x0000000000436c30 in nm_device_release_one_slave (dev=dev@entry=0xd92540, slave=slave@entry=0xdb0e50, configure=configure@entry=1) at devices/nm-device.c:841
#4 0x000000000043a779 in slave_state_changed (slave=0xdb0e50, slave_new_state=NM_DEVICE_STATE_UNMANAGED, slave_old_state=NM_DEVICE_STATE_ACTIVATED, reason=<optimized out>, self=0xd92540) at devices/nm-device.c:1214
#5 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#6 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d3a00, fn=0x43a677 <slave_state_changed>, rvalue=0x7fff8b1d3970, avalue=avalue@entry=0x7fff8b1d38f0) at ../src/x86/ffi64.c:522
#7 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd76120, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#8 0x0000003371c10298 in g_closure_invoke (closure=0xd76120, return_value=return_value@entry=0x0, n_param_values=4, param_values=param_values@entry=0x7fff8b1d3c00, invocation_hint=invocation_hint@entry=0x7fff8b1d3ba0) at gclosure.c:777
#9 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xd9d850, detail=detail@entry=0, instance=instance@entry=0xdb0e50, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d3c00) at gsignal.c:3586
#10 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xdb0e50, signal_id=signal_id@entry=68, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d3e38) at gsignal.c:3330
#11 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xdb0e50, detailed_signal=detailed_signal@entry=0x4c3ce2 "state-changed") at gsignal.c:3426
#12 0x000000000043754f in _set_state_full (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:6689
#13 0x000000000043797c in nm_device_state_changed (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:6823
#14 0x0000000000439fe7 in nm_device_set_unmanaged (device=device@entry=0xdb0e50, flag=flag@entry=NM_UNMANAGED_INTERNAL, unmanaged=unmanaged@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:5983
#15 0x00000000004799c2 in remove_device (manager=manager@entry=0xd86150, device=0xdb0e50, quitting=quitting@entry=0) at nm-manager.c:769
#16 0x000000000047e3bf in platform_link_cb (platform=<optimized out>, ifindex=35, plink=<optimized out>, change_type=<optimized out>, reason=<optimized out>, user_data=<optimized out>) at nm-manager.c:2123
#17 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#18 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d4320, fn=0x47e34b <platform_link_cb>, rvalue=0x7fff8b1d4290, avalue=avalue@entry=0x7fff8b1d4210) at ../src/x86/ffi64.c:522
#19 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd32e40, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#20 0x0000003371c10298 in g_closure_invoke (closure=0xd32e40, return_value=return_value@entry=0x0, n_param_values=5, param_values=param_values@entry=0x7fff8b1d4520, invocation_hint=invocation_hint@entry=0x7fff8b1d44c0) at gclosure.c:777
#21 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xcf5780, detail=detail@entry=0, instance=instance@entry=0xcf78a0, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d4520) at gsignal.c:3586
#22 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xcf78a0, signal_id=signal_id@entry=2, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d4778) at gsignal.c:3330
#23 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xcf78a0, detailed_signal=detailed_signal@entry=0x4b183d "link-changed") at gsignal.c:3426
#24 0x000000000044c6f3 in announce_object (platform=platform@entry=0xcf78a0, object=0xde1720, change_type=change_type@entry=NM_PLATFORM_SIGNAL_REMOVED, reason=reason@entry=NM_PLATFORM_REASON_EXTERNAL)
at platform/nm-linux-platform.c:1572
#25 0x000000000044ec07 in event_notification (msg=<optimized out>, user_data=<optimized out>) at platform/nm-linux-platform.c:1886
#26 0x0000003844c1117f in nl_cb_call (msg=<optimized out>, type=<optimized out>, cb=<optimized out>) at ../include/netlink-private/netlink.h:141
#27 recvmsgs (cb=0xcf7240, sk=0xcf7330) at nl.c:952
#28 nl_recvmsgs_report (sk=0xcf7330, cb=0xcf7240) at nl.c:1003
#29 0x0000003844c11549 in nl_recvmsgs (sk=<optimized out>, cb=<optimized out>) at nl.c:1027
#30 0x0000003844c11569 in nl_recvmsgs_default (sk=<optimized out>) at nl.c:1041
#31 0x000000000044e955 in event_handler (channel=<optimized out>, io_condition=<optimized out>, user_data=0xcf78a0) at platform/nm-linux-platform.c:3804
#32 0x0000003370c492a6 in g_main_dispatch (context=0xcf5190) at gmain.c:3066
#33 g_main_context_dispatch (context=context@entry=0xcf5190) at gmain.c:3642
#34 0x0000003370c49628 in g_main_context_iterate (context=0xcf5190, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3713
#35 0x0000003370c49a3a in g_main_loop_run (loop=0xcf4e30) at gmain.c:3907
#36 0x0000000000429f15 in main (argc=1, argv=0x7fff8b1d4f38) at main.c:678
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-23 11:18:45 +02:00
|
|
|
} else if (reason == NM_DEVICE_STATE_REASON_NONE) {
|
2014-06-12 13:46:25 +02:00
|
|
|
g_warn_if_reached ();
|
|
|
|
|
reason = NM_DEVICE_STATE_REASON_UNKNOWN;
|
|
|
|
|
}
|
2013-12-05 09:13:26 -05:00
|
|
|
nm_device_slave_notify_release (info->slave, reason);
|
2012-11-14 14:05:30 -06:00
|
|
|
|
|
|
|
|
free_slave_info (info);
|
2013-01-18 14:34:40 -06:00
|
|
|
|
|
|
|
|
/* Ensure the device's hardware address is up-to-date; it often changes
|
|
|
|
|
* when slaves change.
|
|
|
|
|
*/
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_update_hw_address (self);
|
2013-01-18 14:34:40 -06:00
|
|
|
|
2012-11-14 14:05:30 -06:00
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-07 10:23:44 -04:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
carrier_changed (NMDevice *self, gboolean carrier)
|
2013-05-07 10:23:44 -04:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-05-07 10:23:44 -04:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (!nm_device_get_managed (self))
|
2013-05-07 10:23:44 -04:00
|
|
|
return;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_recheck_available_connections (self);
|
2013-11-04 19:51:28 -06:00
|
|
|
|
2014-04-02 09:15:54 -05:00
|
|
|
/* ignore-carrier devices ignore all carrier-down events */
|
|
|
|
|
if (priv->ignore_carrier && !carrier)
|
|
|
|
|
return;
|
2013-07-12 10:43:45 -04:00
|
|
|
|
2014-05-20 16:39:57 -05:00
|
|
|
if (priv->is_master) {
|
2013-07-25 15:36:45 +02:00
|
|
|
/* Bridge/bond/team carrier does not affect its own activation,
|
|
|
|
|
* but when carrier comes on, if there are slaves waiting,
|
|
|
|
|
* it will restart them.
|
2013-05-07 10:23:44 -04:00
|
|
|
*/
|
|
|
|
|
if (!carrier)
|
|
|
|
|
return;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (nm_device_activate_ip4_state_in_wait (self))
|
|
|
|
|
nm_device_activate_stage3_ip4_start (self);
|
|
|
|
|
if (nm_device_activate_ip6_state_in_wait (self))
|
|
|
|
|
nm_device_activate_stage3_ip6_start (self);
|
2013-05-07 10:23:44 -04:00
|
|
|
|
|
|
|
|
return;
|
2014-07-15 13:36:24 +02:00
|
|
|
} else if (nm_device_get_enslaved (self) && !carrier) {
|
2013-07-25 15:36:45 +02:00
|
|
|
/* Slaves don't deactivate when they lose carrier; for
|
|
|
|
|
* bonds/teams in particular that would be actively
|
|
|
|
|
* counterproductive.
|
2013-05-07 10:23:44 -04:00
|
|
|
*/
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (carrier) {
|
|
|
|
|
g_warn_if_fail (priv->state >= NM_DEVICE_STATE_UNAVAILABLE);
|
|
|
|
|
|
|
|
|
|
if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) {
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED,
|
2013-05-07 10:23:44 -04:00
|
|
|
NM_DEVICE_STATE_REASON_CARRIER);
|
2014-03-14 15:21:14 -05:00
|
|
|
} else if (priv->state == NM_DEVICE_STATE_DISCONNECTED) {
|
|
|
|
|
/* If the device is already in DISCONNECTED state without a carrier
|
|
|
|
|
* (probably because it is tagged for carrier ignore) ensure that
|
|
|
|
|
* when the carrier appears, auto connections are rechecked for
|
|
|
|
|
* the device.
|
|
|
|
|
*/
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_emit_recheck_auto_activate (self);
|
2013-05-07 10:23:44 -04:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
g_return_if_fail (priv->state >= NM_DEVICE_STATE_UNAVAILABLE);
|
|
|
|
|
|
|
|
|
|
if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) {
|
2014-07-15 13:36:24 +02:00
|
|
|
if (nm_device_queued_state_peek (self) >= NM_DEVICE_STATE_DISCONNECTED)
|
|
|
|
|
nm_device_queued_state_clear (self);
|
2013-05-07 10:23:44 -04:00
|
|
|
} else {
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_queue_state (self, NM_DEVICE_STATE_UNAVAILABLE,
|
2013-05-07 10:23:44 -04:00
|
|
|
NM_DEVICE_STATE_REASON_CARRIER);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define LINK_DISCONNECT_DELAY 4
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
link_disconnect_action_cb (gpointer user_data)
|
|
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-05-07 10:23:44 -04:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "link disconnected (calling deferred action) (id=%u)", priv->carrier_defer_id);
|
2014-03-06 15:09:57 +01:00
|
|
|
|
2013-05-07 10:23:44 -04:00
|
|
|
priv->carrier_defer_id = 0;
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "link disconnected (calling deferred action)");
|
2013-05-07 10:23:44 -04:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
NM_DEVICE_GET_CLASS (self)->carrier_changed (self, FALSE);
|
2013-05-07 10:23:44 -04:00
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-06 15:09:57 +01:00
|
|
|
static void
|
|
|
|
|
link_disconnect_action_cancel (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->carrier_defer_id) {
|
|
|
|
|
g_source_remove (priv->carrier_defer_id);
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "link disconnected (canceling deferred action) (id=%u)", priv->carrier_defer_id);
|
2014-03-06 15:09:57 +01:00
|
|
|
priv->carrier_defer_id = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-07 10:23:44 -04:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_carrier (NMDevice *self, gboolean carrier)
|
2013-05-07 10:23:44 -04:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
|
|
|
|
|
NMDeviceState state = nm_device_get_state (self);
|
2013-05-07 10:23:44 -04:00
|
|
|
|
|
|
|
|
if (priv->carrier == carrier)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
priv->carrier = carrier;
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_CARRIER);
|
2013-05-07 10:23:44 -04:00
|
|
|
|
|
|
|
|
if (priv->carrier) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "link connected");
|
2014-07-15 13:36:24 +02:00
|
|
|
link_disconnect_action_cancel (self);
|
|
|
|
|
klass->carrier_changed (self, TRUE);
|
2013-12-09 16:32:36 -06:00
|
|
|
|
|
|
|
|
if (priv->carrier_wait_id) {
|
|
|
|
|
g_source_remove (priv->carrier_wait_id);
|
|
|
|
|
priv->carrier_wait_id = 0;
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_remove_pending_action (self, "carrier wait", TRUE);
|
2013-12-09 16:32:36 -06:00
|
|
|
}
|
2013-05-07 10:23:44 -04:00
|
|
|
} else if (state <= NM_DEVICE_STATE_DISCONNECTED) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "link disconnected");
|
2014-07-15 13:36:24 +02:00
|
|
|
klass->carrier_changed (self, FALSE);
|
2013-05-07 10:23:44 -04:00
|
|
|
} else {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "link disconnected (deferring action for %d seconds)", LINK_DISCONNECT_DELAY);
|
2013-05-07 10:23:44 -04:00
|
|
|
priv->carrier_defer_id = g_timeout_add_seconds (LINK_DISCONNECT_DELAY,
|
2014-07-15 13:36:24 +02:00
|
|
|
link_disconnect_action_cb, self);
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "link disconnected (deferring action for %d seconds) (id=%u)",
|
|
|
|
|
LINK_DISCONNECT_DELAY, priv->carrier_defer_id);
|
2013-05-07 10:23:44 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
update_for_ip_ifname_change (NMDevice *self)
|
2013-05-07 10:23:44 -04:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-07-27 10:41:44 +02:00
|
|
|
|
2014-03-18 10:18:56 -04:00
|
|
|
g_hash_table_remove_all (priv->ip6_saved_properties);
|
2013-08-27 14:17:30 +02:00
|
|
|
|
2014-03-18 10:18:56 -04:00
|
|
|
if (priv->dhcp4_client) {
|
2014-07-15 13:36:24 +02:00
|
|
|
if (!nm_device_dhcp4_renew (self, FALSE)) {
|
|
|
|
|
nm_device_state_changed (self,
|
2014-03-18 10:18:56 -04:00
|
|
|
NM_DEVICE_STATE_FAILED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_DHCP_FAILED);
|
|
|
|
|
return;
|
2014-01-28 21:25:34 +01:00
|
|
|
}
|
2014-03-18 10:18:56 -04:00
|
|
|
}
|
|
|
|
|
if (priv->dhcp6_client) {
|
2014-07-15 13:36:24 +02:00
|
|
|
if (!nm_device_dhcp6_renew (self, FALSE)) {
|
|
|
|
|
nm_device_state_changed (self,
|
2014-03-18 10:18:56 -04:00
|
|
|
NM_DEVICE_STATE_FAILED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_DHCP_FAILED);
|
|
|
|
|
return;
|
2014-01-28 21:25:34 +01:00
|
|
|
}
|
2014-03-18 10:18:56 -04:00
|
|
|
}
|
|
|
|
|
if (priv->rdisc) {
|
|
|
|
|
/* FIXME: todo */
|
|
|
|
|
}
|
|
|
|
|
if (priv->dnsmasq_manager) {
|
|
|
|
|
/* FIXME: todo */
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-01-28 21:25:34 +01:00
|
|
|
|
2014-03-18 10:18:56 -04:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
device_link_changed (NMDevice *self, NMPlatformLink *info)
|
2014-03-18 10:18:56 -04:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-03-18 10:18:56 -04:00
|
|
|
gboolean ip_ifname_changed = FALSE;
|
2014-01-28 21:25:34 +01:00
|
|
|
|
2014-03-18 10:18:56 -04:00
|
|
|
if (info->udi && g_strcmp0 (info->udi, priv->udi)) {
|
|
|
|
|
/* Update UDI to what udev gives us */
|
|
|
|
|
g_free (priv->udi);
|
|
|
|
|
priv->udi = g_strdup (info->udi);
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_UDI);
|
2014-03-18 10:18:56 -04:00
|
|
|
}
|
2013-08-05 16:39:20 -05:00
|
|
|
|
2014-03-18 10:18:56 -04:00
|
|
|
/* Update MTU if it has changed. */
|
|
|
|
|
if (priv->mtu != info->mtu) {
|
|
|
|
|
priv->mtu = info->mtu;
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_MTU);
|
2014-03-18 10:18:56 -04:00
|
|
|
}
|
2014-01-28 21:25:34 +01:00
|
|
|
|
2014-03-18 10:18:56 -04:00
|
|
|
if (info->name[0] && strcmp (priv->iface, info->name) != 0) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'",
|
|
|
|
|
priv->ifindex, priv->iface, info->name);
|
2014-03-18 10:18:56 -04:00
|
|
|
g_free (priv->iface);
|
|
|
|
|
priv->iface = g_strdup (info->name);
|
2014-01-28 21:25:34 +01:00
|
|
|
|
2014-03-18 10:18:56 -04:00
|
|
|
/* If the device has no explicit ip_iface, then changing iface changes ip_iface too. */
|
|
|
|
|
ip_ifname_changed = !priv->ip_iface;
|
2014-01-28 21:25:34 +01:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_IFACE);
|
2014-03-18 10:18:56 -04:00
|
|
|
if (ip_ifname_changed)
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE);
|
2014-01-28 21:25:34 +01:00
|
|
|
|
2014-03-18 10:18:56 -04:00
|
|
|
/* Re-match available connections against the new interface name */
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_recheck_available_connections (self);
|
2014-01-28 21:25:34 +01:00
|
|
|
|
2014-03-18 10:18:56 -04:00
|
|
|
/* Let any connections that use the new interface name have a chance
|
|
|
|
|
* to auto-activate on the device.
|
|
|
|
|
*/
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_emit_recheck_auto_activate (self);
|
2013-12-16 15:16:43 +01:00
|
|
|
}
|
|
|
|
|
|
2014-02-25 16:44:01 -05:00
|
|
|
/* Update slave status for external changes */
|
|
|
|
|
if (info->master && !priv->enslaved) {
|
|
|
|
|
NMDevice *master;
|
|
|
|
|
|
|
|
|
|
master = nm_manager_get_device_by_ifindex (nm_manager_get (), info->master);
|
|
|
|
|
if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave) {
|
|
|
|
|
g_clear_object (&priv->master);
|
|
|
|
|
priv->master = g_object_ref (master);
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_master_add_slave (master, self, FALSE);
|
|
|
|
|
nm_device_enslave_slave (master, self, NULL);
|
2014-02-25 16:44:01 -05:00
|
|
|
} else if (master) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "enslaved to non-master-type device %s; ignoring",
|
|
|
|
|
nm_device_get_iface (master));
|
2014-02-25 16:44:01 -05:00
|
|
|
} else {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE, "enslaved to unknown device %d %s",
|
|
|
|
|
info->master,
|
|
|
|
|
nm_platform_link_get_name (info->master));
|
2014-02-25 16:44:01 -05:00
|
|
|
}
|
|
|
|
|
} else if (priv->enslaved && !info->master)
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_NONE);
|
2014-02-25 16:44:01 -05:00
|
|
|
|
2014-03-18 10:18:56 -04:00
|
|
|
if (klass->link_changed)
|
2014-07-15 13:36:24 +02:00
|
|
|
klass->link_changed (self, info);
|
2014-05-19 09:56:29 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Update DHCP, etc, if needed */
|
|
|
|
|
if (ip_ifname_changed)
|
2014-07-15 13:36:24 +02:00
|
|
|
update_for_ip_ifname_change (self);
|
2014-03-18 10:18:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
device_ip_link_changed (NMDevice *self, NMPlatformLink *info)
|
2014-03-18 10:18:56 -04:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-03-18 10:18:56 -04:00
|
|
|
|
|
|
|
|
if (info->name[0] && g_strcmp0 (priv->ip_iface, info->name)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "interface index %d renamed ip_iface (%d) from '%s' to '%s'",
|
|
|
|
|
priv->ifindex, nm_device_get_ip_ifindex (self),
|
|
|
|
|
priv->ip_iface, info->name);
|
2014-03-18 10:18:56 -04:00
|
|
|
g_free (priv->ip_iface);
|
|
|
|
|
priv->ip_iface = g_strdup (info->name);
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE);
|
|
|
|
|
update_for_ip_ifname_change (self);
|
2014-01-28 21:25:34 +01:00
|
|
|
}
|
2013-07-27 10:41:44 +02:00
|
|
|
}
|
|
|
|
|
|
2014-03-18 10:18:56 -04:00
|
|
|
static void
|
2014-07-24 17:14:30 -05:00
|
|
|
link_changed_cb (NMPlatform *platform,
|
|
|
|
|
int ifindex,
|
|
|
|
|
NMPlatformLink *info,
|
|
|
|
|
NMPlatformSignalChangeType change_type,
|
|
|
|
|
NMPlatformReason reason,
|
|
|
|
|
NMDevice *self)
|
2014-03-18 10:18:56 -04:00
|
|
|
{
|
|
|
|
|
if (change_type != NM_PLATFORM_SIGNAL_CHANGED)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* We don't filter by 'reason' because we are interested in *all* link
|
|
|
|
|
* changes. For example a call to nm_platform_link_set_up() may result
|
|
|
|
|
* in an internal carrier change (i.e. we ask the kernel to set IFF_UP
|
|
|
|
|
* and it results in also setting IFF_LOWER_UP.
|
|
|
|
|
*/
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (ifindex == nm_device_get_ifindex (self))
|
|
|
|
|
device_link_changed (self, info);
|
|
|
|
|
else if (ifindex == nm_device_get_ip_ifindex (self))
|
|
|
|
|
device_ip_link_changed (self, info);
|
2014-03-18 10:18:56 -04:00
|
|
|
}
|
|
|
|
|
|
2013-07-27 10:41:44 +02:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
link_changed (NMDevice *self, NMPlatformLink *info)
|
2013-07-27 10:41:44 +02:00
|
|
|
{
|
2013-08-27 14:17:30 +02:00
|
|
|
/* Update carrier from link event if applicable. */
|
2014-07-15 13:36:24 +02:00
|
|
|
if ( device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)
|
|
|
|
|
&& !device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER))
|
|
|
|
|
nm_device_set_carrier (self, info->connected);
|
2013-05-07 10:23:44 -04:00
|
|
|
}
|
|
|
|
|
|
2014-02-09 10:22:19 -06:00
|
|
|
/**
|
|
|
|
|
* nm_device_notify_component_added():
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the #NMDevice
|
2014-02-09 10:22:19 -06:00
|
|
|
* @component: the component being added by a plugin
|
|
|
|
|
*
|
|
|
|
|
* Called by the manager to notify the device that a new component has
|
|
|
|
|
* been found. The device implementation should return %TRUE if it
|
|
|
|
|
* wishes to claim the component, or %FALSE if it cannot.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE to claim the component, %FALSE if the component cannot be
|
|
|
|
|
* claimed.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_notify_component_added (NMDevice *self, GObject *component)
|
2014-02-09 10:22:19 -06:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
if (NM_DEVICE_GET_CLASS (self)->component_added)
|
|
|
|
|
return NM_DEVICE_GET_CLASS (self)->component_added (self, component);
|
2014-02-09 10:22:19 -06:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_owns_iface():
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the #NMDevice
|
2014-02-09 10:22:19 -06:00
|
|
|
* @iface: an interface name
|
|
|
|
|
*
|
|
|
|
|
* Called by the manager to ask if the device or any of its components owns
|
|
|
|
|
* @iface. For example, a WWAN implementation would return %TRUE for an
|
|
|
|
|
* ethernet interface name that was owned by the WWAN device's modem component,
|
|
|
|
|
* because that ethernet interface is controlled by the WWAN device and cannot
|
|
|
|
|
* be used independently of the WWAN device.
|
|
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* Returns: %TRUE if @self or it's components owns the interface name,
|
2014-02-09 10:22:19 -06:00
|
|
|
* %FALSE if not
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_owns_iface (NMDevice *self, const char *iface)
|
2014-02-09 10:22:19 -06:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
if (NM_DEVICE_GET_CLASS (self)->owns_iface)
|
|
|
|
|
return NM_DEVICE_GET_CLASS (self)->owns_iface (self, iface);
|
2014-02-09 10:22:19 -06:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-08 16:11:51 -05:00
|
|
|
NMConnection *
|
|
|
|
|
nm_device_new_default_connection (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
if (NM_DEVICE_GET_CLASS (self)->new_default_connection)
|
|
|
|
|
return NM_DEVICE_GET_CLASS (self)->new_default_connection (self);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-14 14:05:30 -06:00
|
|
|
static void
|
|
|
|
|
slave_state_changed (NMDevice *slave,
|
|
|
|
|
NMDeviceState slave_new_state,
|
|
|
|
|
NMDeviceState slave_old_state,
|
|
|
|
|
NMDeviceStateReason reason,
|
|
|
|
|
NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
gboolean release = FALSE;
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "slave %s state change %d (%s) -> %d (%s)",
|
|
|
|
|
nm_device_get_iface (slave),
|
|
|
|
|
slave_old_state,
|
|
|
|
|
state_to_string (slave_old_state),
|
|
|
|
|
slave_new_state,
|
|
|
|
|
state_to_string (slave_new_state));
|
2012-11-14 14:05:30 -06:00
|
|
|
|
|
|
|
|
/* Don't try to enslave slaves until the master is ready */
|
|
|
|
|
if (priv->state < NM_DEVICE_STATE_CONFIG)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (slave_new_state == NM_DEVICE_STATE_IP_CONFIG)
|
|
|
|
|
nm_device_enslave_slave (self, slave, nm_device_get_connection (slave));
|
|
|
|
|
else if (slave_new_state > NM_DEVICE_STATE_ACTIVATED)
|
|
|
|
|
release = TRUE;
|
|
|
|
|
else if ( slave_new_state <= NM_DEVICE_STATE_DISCONNECTED
|
|
|
|
|
&& slave_old_state > NM_DEVICE_STATE_DISCONNECTED) {
|
|
|
|
|
/* Catch failures due to unavailable or unmanaged */
|
|
|
|
|
release = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (release) {
|
device: fix warning releasing of slave when slave device gets removed
When the slave device gets removed, the master is not in a state-change when
calling nm_device_release_one_slave(). This triggers a warning [1].
[1] backtrace:
#0 0x0000003370c504e9 in g_logv (log_domain=0x4c144c "NetworkManager", log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, args=args@entry=0x7fff8b1d35b0) at gmessages.c:989
#1 0x0000003370c5063f in g_log (log_domain=log_domain@entry=0x4c144c "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_WARNING, format=format@entry=0x3370cc1fdc "%s") at gmessages.c:1025
#2 0x0000003370c50956 in g_warn_message (domain=domain@entry=0x4c144c "NetworkManager", file=file@entry=0x4b14d5 "devices/nm-device.c", line=line@entry=841, func=func@entry=0x4b48f0 <__FUNCTION__.35456> "nm_device_release_one_slave",
warnexpr=warnexpr@entry=0x0) at gmessages.c:1058
#3 0x0000000000436c30 in nm_device_release_one_slave (dev=dev@entry=0xd92540, slave=slave@entry=0xdb0e50, configure=configure@entry=1) at devices/nm-device.c:841
#4 0x000000000043a779 in slave_state_changed (slave=0xdb0e50, slave_new_state=NM_DEVICE_STATE_UNMANAGED, slave_old_state=NM_DEVICE_STATE_ACTIVATED, reason=<optimized out>, self=0xd92540) at devices/nm-device.c:1214
#5 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#6 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d3a00, fn=0x43a677 <slave_state_changed>, rvalue=0x7fff8b1d3970, avalue=avalue@entry=0x7fff8b1d38f0) at ../src/x86/ffi64.c:522
#7 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd76120, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#8 0x0000003371c10298 in g_closure_invoke (closure=0xd76120, return_value=return_value@entry=0x0, n_param_values=4, param_values=param_values@entry=0x7fff8b1d3c00, invocation_hint=invocation_hint@entry=0x7fff8b1d3ba0) at gclosure.c:777
#9 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xd9d850, detail=detail@entry=0, instance=instance@entry=0xdb0e50, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d3c00) at gsignal.c:3586
#10 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xdb0e50, signal_id=signal_id@entry=68, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d3e38) at gsignal.c:3330
#11 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xdb0e50, detailed_signal=detailed_signal@entry=0x4c3ce2 "state-changed") at gsignal.c:3426
#12 0x000000000043754f in _set_state_full (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:6689
#13 0x000000000043797c in nm_device_state_changed (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:6823
#14 0x0000000000439fe7 in nm_device_set_unmanaged (device=device@entry=0xdb0e50, flag=flag@entry=NM_UNMANAGED_INTERNAL, unmanaged=unmanaged@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:5983
#15 0x00000000004799c2 in remove_device (manager=manager@entry=0xd86150, device=0xdb0e50, quitting=quitting@entry=0) at nm-manager.c:769
#16 0x000000000047e3bf in platform_link_cb (platform=<optimized out>, ifindex=35, plink=<optimized out>, change_type=<optimized out>, reason=<optimized out>, user_data=<optimized out>) at nm-manager.c:2123
#17 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#18 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d4320, fn=0x47e34b <platform_link_cb>, rvalue=0x7fff8b1d4290, avalue=avalue@entry=0x7fff8b1d4210) at ../src/x86/ffi64.c:522
#19 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd32e40, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#20 0x0000003371c10298 in g_closure_invoke (closure=0xd32e40, return_value=return_value@entry=0x0, n_param_values=5, param_values=param_values@entry=0x7fff8b1d4520, invocation_hint=invocation_hint@entry=0x7fff8b1d44c0) at gclosure.c:777
#21 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xcf5780, detail=detail@entry=0, instance=instance@entry=0xcf78a0, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d4520) at gsignal.c:3586
#22 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xcf78a0, signal_id=signal_id@entry=2, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d4778) at gsignal.c:3330
#23 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xcf78a0, detailed_signal=detailed_signal@entry=0x4b183d "link-changed") at gsignal.c:3426
#24 0x000000000044c6f3 in announce_object (platform=platform@entry=0xcf78a0, object=0xde1720, change_type=change_type@entry=NM_PLATFORM_SIGNAL_REMOVED, reason=reason@entry=NM_PLATFORM_REASON_EXTERNAL)
at platform/nm-linux-platform.c:1572
#25 0x000000000044ec07 in event_notification (msg=<optimized out>, user_data=<optimized out>) at platform/nm-linux-platform.c:1886
#26 0x0000003844c1117f in nl_cb_call (msg=<optimized out>, type=<optimized out>, cb=<optimized out>) at ../include/netlink-private/netlink.h:141
#27 recvmsgs (cb=0xcf7240, sk=0xcf7330) at nl.c:952
#28 nl_recvmsgs_report (sk=0xcf7330, cb=0xcf7240) at nl.c:1003
#29 0x0000003844c11549 in nl_recvmsgs (sk=<optimized out>, cb=<optimized out>) at nl.c:1027
#30 0x0000003844c11569 in nl_recvmsgs_default (sk=<optimized out>) at nl.c:1041
#31 0x000000000044e955 in event_handler (channel=<optimized out>, io_condition=<optimized out>, user_data=0xcf78a0) at platform/nm-linux-platform.c:3804
#32 0x0000003370c492a6 in g_main_dispatch (context=0xcf5190) at gmain.c:3066
#33 g_main_context_dispatch (context=context@entry=0xcf5190) at gmain.c:3642
#34 0x0000003370c49628 in g_main_context_iterate (context=0xcf5190, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3713
#35 0x0000003370c49a3a in g_main_loop_run (loop=0xcf4e30) at gmain.c:3907
#36 0x0000000000429f15 in main (argc=1, argv=0x7fff8b1d4f38) at main.c:678
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-23 11:18:45 +02:00
|
|
|
nm_device_release_one_slave (self, slave, TRUE, reason);
|
2013-07-25 15:36:45 +02:00
|
|
|
/* Bridge/bond/team interfaces are left up until manually deactivated */
|
2014-02-12 23:54:26 +01:00
|
|
|
if (priv->slaves == NULL && priv->state == NM_DEVICE_STATE_ACTIVATED)
|
|
|
|
|
_LOGD (LOGD_DEVICE, "last slave removed; remaining activated");
|
2012-11-14 14:05:30 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_master_add_slave:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the master device
|
2012-11-14 14:05:30 -06:00
|
|
|
* @slave: the slave device to enslave
|
2013-11-07 01:08:02 -06:00
|
|
|
* @configure: pass %TRUE if the slave should be configured by the master, or
|
|
|
|
|
* %FALSE if it is already configured outside NetworkManager
|
2012-11-14 14:05:30 -06:00
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* If @self is capable of enslaving other devices (ie it's a bridge, bond, team,
|
2013-07-25 15:36:45 +02:00
|
|
|
* etc) then this function adds @slave to the slave list for later enslavement.
|
2012-11-14 14:05:30 -06:00
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success, %FALSE on failure
|
|
|
|
|
*/
|
2014-05-20 16:39:57 -05:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure)
|
2012-02-28 18:35:30 -06:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2012-11-14 14:05:30 -06:00
|
|
|
SlaveInfo *info;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (self != NULL, FALSE);
|
2012-02-28 18:35:30 -06:00
|
|
|
g_return_val_if_fail (slave != NULL, FALSE);
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE);
|
2012-11-14 14:05:30 -06:00
|
|
|
|
2014-02-25 16:44:01 -05:00
|
|
|
if (configure)
|
|
|
|
|
g_return_val_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE);
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (!find_slave_info (self, slave)) {
|
2012-11-14 14:05:30 -06:00
|
|
|
info = g_malloc0 (sizeof (SlaveInfo));
|
|
|
|
|
info->slave = g_object_ref (slave);
|
2013-11-07 01:08:02 -06:00
|
|
|
info->configure = configure;
|
2012-11-14 14:05:30 -06:00
|
|
|
info->watch_id = g_signal_connect (slave, "state-changed",
|
2014-07-15 13:36:24 +02:00
|
|
|
G_CALLBACK (slave_state_changed), self);
|
2014-02-25 15:55:28 -05:00
|
|
|
priv->slaves = g_slist_append (priv->slaves, info);
|
2012-11-14 14:05:30 -06:00
|
|
|
}
|
2012-02-28 18:35:30 -06:00
|
|
|
|
2012-11-14 14:05:30 -06:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_master_get_slaves:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the master device
|
2012-11-14 14:05:30 -06:00
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* Returns: any slaves of which @self is the master. Caller owns returned list.
|
2012-11-14 14:05:30 -06:00
|
|
|
*/
|
|
|
|
|
GSList *
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_master_get_slaves (NMDevice *self)
|
2012-11-14 14:05:30 -06:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2012-11-14 14:05:30 -06:00
|
|
|
GSList *slaves = NULL, *iter;
|
|
|
|
|
|
|
|
|
|
for (iter = priv->slaves; iter; iter = g_slist_next (iter))
|
|
|
|
|
slaves = g_slist_prepend (slaves, ((SlaveInfo *) iter->data)->slave);
|
|
|
|
|
|
|
|
|
|
return slaves;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-28 13:37:04 -06:00
|
|
|
/**
|
|
|
|
|
* nm_device_master_get_slave_by_ifindex:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the master device
|
2013-01-28 13:37:04 -06:00
|
|
|
* @ifindex: the slave's interface index
|
|
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* Returns: the slave with the given @ifindex of which @self is the master,
|
|
|
|
|
* or %NULL if no device with @ifindex is a slave of @self.
|
2013-01-28 13:37:04 -06:00
|
|
|
*/
|
|
|
|
|
NMDevice *
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_master_get_slave_by_ifindex (NMDevice *self, int ifindex)
|
2013-01-28 13:37:04 -06:00
|
|
|
{
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
for (iter = NM_DEVICE_GET_PRIVATE (self)->slaves; iter; iter = g_slist_next (iter)) {
|
2013-01-28 13:37:04 -06:00
|
|
|
SlaveInfo *info = iter->data;
|
|
|
|
|
|
|
|
|
|
if (nm_device_get_ip_ifindex (info->slave) == ifindex)
|
|
|
|
|
return info->slave;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-11 14:59:26 -04:00
|
|
|
/**
|
|
|
|
|
* nm_device_master_check_slave_physical_port:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the master device
|
2013-10-11 14:59:26 -04:00
|
|
|
* @slave: a slave device
|
|
|
|
|
* @log_domain: domain to log a warning in
|
|
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* Checks if @self already has a slave with the same #NMDevice:physical-port-id
|
2013-10-11 14:59:26 -04:00
|
|
|
* as @slave, and logs a warning if so.
|
|
|
|
|
*/
|
|
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_master_check_slave_physical_port (NMDevice *self, NMDevice *slave,
|
2013-10-11 14:59:26 -04:00
|
|
|
guint64 log_domain)
|
|
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-10-11 14:59:26 -04:00
|
|
|
const char *slave_physical_port_id, *existing_physical_port_id;
|
|
|
|
|
SlaveInfo *info;
|
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
|
|
slave_physical_port_id = nm_device_get_physical_port_id (slave);
|
|
|
|
|
if (!slave_physical_port_id)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (iter = priv->slaves; iter; iter = iter->next) {
|
|
|
|
|
info = iter->data;
|
|
|
|
|
if (info->slave == slave)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
existing_physical_port_id = nm_device_get_physical_port_id (info->slave);
|
|
|
|
|
if (!g_strcmp0 (slave_physical_port_id, existing_physical_port_id)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (log_domain, "slave %s shares a physical port with existing slave %s",
|
|
|
|
|
nm_device_get_ip_iface (slave),
|
|
|
|
|
nm_device_get_ip_iface (info->slave));
|
2013-10-11 14:59:26 -04:00
|
|
|
/* Since this function will get called for every slave, we only have
|
|
|
|
|
* to warn about the first match we find; if there are other matches
|
|
|
|
|
* later in the list, we will have already warned about them matching
|
|
|
|
|
* @existing earlier.
|
|
|
|
|
*/
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-14 14:05:30 -06:00
|
|
|
/* release all slaves */
|
|
|
|
|
static void
|
2013-12-05 09:13:26 -05:00
|
|
|
nm_device_master_release_slaves (NMDevice *self)
|
2012-11-14 14:05:30 -06:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
device: fix warning releasing of slave when slave device gets removed
When the slave device gets removed, the master is not in a state-change when
calling nm_device_release_one_slave(). This triggers a warning [1].
[1] backtrace:
#0 0x0000003370c504e9 in g_logv (log_domain=0x4c144c "NetworkManager", log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, args=args@entry=0x7fff8b1d35b0) at gmessages.c:989
#1 0x0000003370c5063f in g_log (log_domain=log_domain@entry=0x4c144c "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_WARNING, format=format@entry=0x3370cc1fdc "%s") at gmessages.c:1025
#2 0x0000003370c50956 in g_warn_message (domain=domain@entry=0x4c144c "NetworkManager", file=file@entry=0x4b14d5 "devices/nm-device.c", line=line@entry=841, func=func@entry=0x4b48f0 <__FUNCTION__.35456> "nm_device_release_one_slave",
warnexpr=warnexpr@entry=0x0) at gmessages.c:1058
#3 0x0000000000436c30 in nm_device_release_one_slave (dev=dev@entry=0xd92540, slave=slave@entry=0xdb0e50, configure=configure@entry=1) at devices/nm-device.c:841
#4 0x000000000043a779 in slave_state_changed (slave=0xdb0e50, slave_new_state=NM_DEVICE_STATE_UNMANAGED, slave_old_state=NM_DEVICE_STATE_ACTIVATED, reason=<optimized out>, self=0xd92540) at devices/nm-device.c:1214
#5 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#6 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d3a00, fn=0x43a677 <slave_state_changed>, rvalue=0x7fff8b1d3970, avalue=avalue@entry=0x7fff8b1d38f0) at ../src/x86/ffi64.c:522
#7 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd76120, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#8 0x0000003371c10298 in g_closure_invoke (closure=0xd76120, return_value=return_value@entry=0x0, n_param_values=4, param_values=param_values@entry=0x7fff8b1d3c00, invocation_hint=invocation_hint@entry=0x7fff8b1d3ba0) at gclosure.c:777
#9 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xd9d850, detail=detail@entry=0, instance=instance@entry=0xdb0e50, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d3c00) at gsignal.c:3586
#10 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xdb0e50, signal_id=signal_id@entry=68, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d3e38) at gsignal.c:3330
#11 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xdb0e50, detailed_signal=detailed_signal@entry=0x4c3ce2 "state-changed") at gsignal.c:3426
#12 0x000000000043754f in _set_state_full (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:6689
#13 0x000000000043797c in nm_device_state_changed (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:6823
#14 0x0000000000439fe7 in nm_device_set_unmanaged (device=device@entry=0xdb0e50, flag=flag@entry=NM_UNMANAGED_INTERNAL, unmanaged=unmanaged@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:5983
#15 0x00000000004799c2 in remove_device (manager=manager@entry=0xd86150, device=0xdb0e50, quitting=quitting@entry=0) at nm-manager.c:769
#16 0x000000000047e3bf in platform_link_cb (platform=<optimized out>, ifindex=35, plink=<optimized out>, change_type=<optimized out>, reason=<optimized out>, user_data=<optimized out>) at nm-manager.c:2123
#17 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#18 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d4320, fn=0x47e34b <platform_link_cb>, rvalue=0x7fff8b1d4290, avalue=avalue@entry=0x7fff8b1d4210) at ../src/x86/ffi64.c:522
#19 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd32e40, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#20 0x0000003371c10298 in g_closure_invoke (closure=0xd32e40, return_value=return_value@entry=0x0, n_param_values=5, param_values=param_values@entry=0x7fff8b1d4520, invocation_hint=invocation_hint@entry=0x7fff8b1d44c0) at gclosure.c:777
#21 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xcf5780, detail=detail@entry=0, instance=instance@entry=0xcf78a0, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d4520) at gsignal.c:3586
#22 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xcf78a0, signal_id=signal_id@entry=2, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d4778) at gsignal.c:3330
#23 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xcf78a0, detailed_signal=detailed_signal@entry=0x4b183d "link-changed") at gsignal.c:3426
#24 0x000000000044c6f3 in announce_object (platform=platform@entry=0xcf78a0, object=0xde1720, change_type=change_type@entry=NM_PLATFORM_SIGNAL_REMOVED, reason=reason@entry=NM_PLATFORM_REASON_EXTERNAL)
at platform/nm-linux-platform.c:1572
#25 0x000000000044ec07 in event_notification (msg=<optimized out>, user_data=<optimized out>) at platform/nm-linux-platform.c:1886
#26 0x0000003844c1117f in nl_cb_call (msg=<optimized out>, type=<optimized out>, cb=<optimized out>) at ../include/netlink-private/netlink.h:141
#27 recvmsgs (cb=0xcf7240, sk=0xcf7330) at nl.c:952
#28 nl_recvmsgs_report (sk=0xcf7330, cb=0xcf7240) at nl.c:1003
#29 0x0000003844c11549 in nl_recvmsgs (sk=<optimized out>, cb=<optimized out>) at nl.c:1027
#30 0x0000003844c11569 in nl_recvmsgs_default (sk=<optimized out>) at nl.c:1041
#31 0x000000000044e955 in event_handler (channel=<optimized out>, io_condition=<optimized out>, user_data=0xcf78a0) at platform/nm-linux-platform.c:3804
#32 0x0000003370c492a6 in g_main_dispatch (context=0xcf5190) at gmain.c:3066
#33 g_main_context_dispatch (context=context@entry=0xcf5190) at gmain.c:3642
#34 0x0000003370c49628 in g_main_context_iterate (context=0xcf5190, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3713
#35 0x0000003370c49a3a in g_main_loop_run (loop=0xcf4e30) at gmain.c:3907
#36 0x0000000000429f15 in main (argc=1, argv=0x7fff8b1d4f38) at main.c:678
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-23 11:18:45 +02:00
|
|
|
NMDeviceStateReason reason;
|
2012-11-14 14:05:30 -06:00
|
|
|
|
2014-02-25 16:44:01 -05:00
|
|
|
/* Don't release the slaves if this connection doesn't belong to NM. */
|
|
|
|
|
if (nm_device_uses_generated_connection (self))
|
|
|
|
|
return;
|
|
|
|
|
|
device: fix warning releasing of slave when slave device gets removed
When the slave device gets removed, the master is not in a state-change when
calling nm_device_release_one_slave(). This triggers a warning [1].
[1] backtrace:
#0 0x0000003370c504e9 in g_logv (log_domain=0x4c144c "NetworkManager", log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, args=args@entry=0x7fff8b1d35b0) at gmessages.c:989
#1 0x0000003370c5063f in g_log (log_domain=log_domain@entry=0x4c144c "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_WARNING, format=format@entry=0x3370cc1fdc "%s") at gmessages.c:1025
#2 0x0000003370c50956 in g_warn_message (domain=domain@entry=0x4c144c "NetworkManager", file=file@entry=0x4b14d5 "devices/nm-device.c", line=line@entry=841, func=func@entry=0x4b48f0 <__FUNCTION__.35456> "nm_device_release_one_slave",
warnexpr=warnexpr@entry=0x0) at gmessages.c:1058
#3 0x0000000000436c30 in nm_device_release_one_slave (dev=dev@entry=0xd92540, slave=slave@entry=0xdb0e50, configure=configure@entry=1) at devices/nm-device.c:841
#4 0x000000000043a779 in slave_state_changed (slave=0xdb0e50, slave_new_state=NM_DEVICE_STATE_UNMANAGED, slave_old_state=NM_DEVICE_STATE_ACTIVATED, reason=<optimized out>, self=0xd92540) at devices/nm-device.c:1214
#5 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#6 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d3a00, fn=0x43a677 <slave_state_changed>, rvalue=0x7fff8b1d3970, avalue=avalue@entry=0x7fff8b1d38f0) at ../src/x86/ffi64.c:522
#7 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd76120, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#8 0x0000003371c10298 in g_closure_invoke (closure=0xd76120, return_value=return_value@entry=0x0, n_param_values=4, param_values=param_values@entry=0x7fff8b1d3c00, invocation_hint=invocation_hint@entry=0x7fff8b1d3ba0) at gclosure.c:777
#9 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xd9d850, detail=detail@entry=0, instance=instance@entry=0xdb0e50, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d3c00) at gsignal.c:3586
#10 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xdb0e50, signal_id=signal_id@entry=68, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d3e38) at gsignal.c:3330
#11 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xdb0e50, detailed_signal=detailed_signal@entry=0x4c3ce2 "state-changed") at gsignal.c:3426
#12 0x000000000043754f in _set_state_full (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:6689
#13 0x000000000043797c in nm_device_state_changed (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:6823
#14 0x0000000000439fe7 in nm_device_set_unmanaged (device=device@entry=0xdb0e50, flag=flag@entry=NM_UNMANAGED_INTERNAL, unmanaged=unmanaged@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:5983
#15 0x00000000004799c2 in remove_device (manager=manager@entry=0xd86150, device=0xdb0e50, quitting=quitting@entry=0) at nm-manager.c:769
#16 0x000000000047e3bf in platform_link_cb (platform=<optimized out>, ifindex=35, plink=<optimized out>, change_type=<optimized out>, reason=<optimized out>, user_data=<optimized out>) at nm-manager.c:2123
#17 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#18 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d4320, fn=0x47e34b <platform_link_cb>, rvalue=0x7fff8b1d4290, avalue=avalue@entry=0x7fff8b1d4210) at ../src/x86/ffi64.c:522
#19 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd32e40, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#20 0x0000003371c10298 in g_closure_invoke (closure=0xd32e40, return_value=return_value@entry=0x0, n_param_values=5, param_values=param_values@entry=0x7fff8b1d4520, invocation_hint=invocation_hint@entry=0x7fff8b1d44c0) at gclosure.c:777
#21 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xcf5780, detail=detail@entry=0, instance=instance@entry=0xcf78a0, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d4520) at gsignal.c:3586
#22 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xcf78a0, signal_id=signal_id@entry=2, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d4778) at gsignal.c:3330
#23 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xcf78a0, detailed_signal=detailed_signal@entry=0x4b183d "link-changed") at gsignal.c:3426
#24 0x000000000044c6f3 in announce_object (platform=platform@entry=0xcf78a0, object=0xde1720, change_type=change_type@entry=NM_PLATFORM_SIGNAL_REMOVED, reason=reason@entry=NM_PLATFORM_REASON_EXTERNAL)
at platform/nm-linux-platform.c:1572
#25 0x000000000044ec07 in event_notification (msg=<optimized out>, user_data=<optimized out>) at platform/nm-linux-platform.c:1886
#26 0x0000003844c1117f in nl_cb_call (msg=<optimized out>, type=<optimized out>, cb=<optimized out>) at ../include/netlink-private/netlink.h:141
#27 recvmsgs (cb=0xcf7240, sk=0xcf7330) at nl.c:952
#28 nl_recvmsgs_report (sk=0xcf7330, cb=0xcf7240) at nl.c:1003
#29 0x0000003844c11549 in nl_recvmsgs (sk=<optimized out>, cb=<optimized out>) at nl.c:1027
#30 0x0000003844c11569 in nl_recvmsgs_default (sk=<optimized out>) at nl.c:1041
#31 0x000000000044e955 in event_handler (channel=<optimized out>, io_condition=<optimized out>, user_data=0xcf78a0) at platform/nm-linux-platform.c:3804
#32 0x0000003370c492a6 in g_main_dispatch (context=0xcf5190) at gmain.c:3066
#33 g_main_context_dispatch (context=context@entry=0xcf5190) at gmain.c:3642
#34 0x0000003370c49628 in g_main_context_iterate (context=0xcf5190, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3713
#35 0x0000003370c49a3a in g_main_loop_run (loop=0xcf4e30) at gmain.c:3907
#36 0x0000000000429f15 in main (argc=1, argv=0x7fff8b1d4f38) at main.c:678
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-23 11:18:45 +02:00
|
|
|
reason = priv->state_reason;
|
|
|
|
|
if (priv->state == NM_DEVICE_STATE_FAILED)
|
|
|
|
|
reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED;
|
|
|
|
|
|
2013-05-15 14:39:16 -05:00
|
|
|
while (priv->slaves) {
|
|
|
|
|
SlaveInfo *info = priv->slaves->data;
|
|
|
|
|
|
device: fix warning releasing of slave when slave device gets removed
When the slave device gets removed, the master is not in a state-change when
calling nm_device_release_one_slave(). This triggers a warning [1].
[1] backtrace:
#0 0x0000003370c504e9 in g_logv (log_domain=0x4c144c "NetworkManager", log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, args=args@entry=0x7fff8b1d35b0) at gmessages.c:989
#1 0x0000003370c5063f in g_log (log_domain=log_domain@entry=0x4c144c "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_WARNING, format=format@entry=0x3370cc1fdc "%s") at gmessages.c:1025
#2 0x0000003370c50956 in g_warn_message (domain=domain@entry=0x4c144c "NetworkManager", file=file@entry=0x4b14d5 "devices/nm-device.c", line=line@entry=841, func=func@entry=0x4b48f0 <__FUNCTION__.35456> "nm_device_release_one_slave",
warnexpr=warnexpr@entry=0x0) at gmessages.c:1058
#3 0x0000000000436c30 in nm_device_release_one_slave (dev=dev@entry=0xd92540, slave=slave@entry=0xdb0e50, configure=configure@entry=1) at devices/nm-device.c:841
#4 0x000000000043a779 in slave_state_changed (slave=0xdb0e50, slave_new_state=NM_DEVICE_STATE_UNMANAGED, slave_old_state=NM_DEVICE_STATE_ACTIVATED, reason=<optimized out>, self=0xd92540) at devices/nm-device.c:1214
#5 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#6 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d3a00, fn=0x43a677 <slave_state_changed>, rvalue=0x7fff8b1d3970, avalue=avalue@entry=0x7fff8b1d38f0) at ../src/x86/ffi64.c:522
#7 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd76120, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#8 0x0000003371c10298 in g_closure_invoke (closure=0xd76120, return_value=return_value@entry=0x0, n_param_values=4, param_values=param_values@entry=0x7fff8b1d3c00, invocation_hint=invocation_hint@entry=0x7fff8b1d3ba0) at gclosure.c:777
#9 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xd9d850, detail=detail@entry=0, instance=instance@entry=0xdb0e50, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d3c00) at gsignal.c:3586
#10 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xdb0e50, signal_id=signal_id@entry=68, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d3e38) at gsignal.c:3330
#11 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xdb0e50, detailed_signal=detailed_signal@entry=0x4c3ce2 "state-changed") at gsignal.c:3426
#12 0x000000000043754f in _set_state_full (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:6689
#13 0x000000000043797c in nm_device_state_changed (device=device@entry=0xdb0e50, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:6823
#14 0x0000000000439fe7 in nm_device_set_unmanaged (device=device@entry=0xdb0e50, flag=flag@entry=NM_UNMANAGED_INTERNAL, unmanaged=unmanaged@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:5983
#15 0x00000000004799c2 in remove_device (manager=manager@entry=0xd86150, device=0xdb0e50, quitting=quitting@entry=0) at nm-manager.c:769
#16 0x000000000047e3bf in platform_link_cb (platform=<optimized out>, ifindex=35, plink=<optimized out>, change_type=<optimized out>, reason=<optimized out>, user_data=<optimized out>) at nm-manager.c:2123
#17 0x0000003371805d8c in ffi_call_unix64 () at ../src/x86/unix64.S:76
#18 0x00000033718056bc in ffi_call (cif=cif@entry=0x7fff8b1d4320, fn=0x47e34b <platform_link_cb>, rvalue=0x7fff8b1d4290, avalue=avalue@entry=0x7fff8b1d4210) at ../src/x86/ffi64.c:522
#19 0x0000003371c10ad8 in g_cclosure_marshal_generic (closure=0xd32e40, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=0x0) at gclosure.c:1454
#20 0x0000003371c10298 in g_closure_invoke (closure=0xd32e40, return_value=return_value@entry=0x0, n_param_values=5, param_values=param_values@entry=0x7fff8b1d4520, invocation_hint=invocation_hint@entry=0x7fff8b1d44c0) at gclosure.c:777
#21 0x0000003371c2235d in signal_emit_unlocked_R (node=node@entry=0xcf5780, detail=detail@entry=0, instance=instance@entry=0xcf78a0, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff8b1d4520) at gsignal.c:3586
#22 0x0000003371c2a0f2 in g_signal_emit_valist (instance=instance@entry=0xcf78a0, signal_id=signal_id@entry=2, detail=detail@entry=0, var_args=var_args@entry=0x7fff8b1d4778) at gsignal.c:3330
#23 0x0000003371c2a8f8 in g_signal_emit_by_name (instance=instance@entry=0xcf78a0, detailed_signal=detailed_signal@entry=0x4b183d "link-changed") at gsignal.c:3426
#24 0x000000000044c6f3 in announce_object (platform=platform@entry=0xcf78a0, object=0xde1720, change_type=change_type@entry=NM_PLATFORM_SIGNAL_REMOVED, reason=reason@entry=NM_PLATFORM_REASON_EXTERNAL)
at platform/nm-linux-platform.c:1572
#25 0x000000000044ec07 in event_notification (msg=<optimized out>, user_data=<optimized out>) at platform/nm-linux-platform.c:1886
#26 0x0000003844c1117f in nl_cb_call (msg=<optimized out>, type=<optimized out>, cb=<optimized out>) at ../include/netlink-private/netlink.h:141
#27 recvmsgs (cb=0xcf7240, sk=0xcf7330) at nl.c:952
#28 nl_recvmsgs_report (sk=0xcf7330, cb=0xcf7240) at nl.c:1003
#29 0x0000003844c11549 in nl_recvmsgs (sk=<optimized out>, cb=<optimized out>) at nl.c:1027
#30 0x0000003844c11569 in nl_recvmsgs_default (sk=<optimized out>) at nl.c:1041
#31 0x000000000044e955 in event_handler (channel=<optimized out>, io_condition=<optimized out>, user_data=0xcf78a0) at platform/nm-linux-platform.c:3804
#32 0x0000003370c492a6 in g_main_dispatch (context=0xcf5190) at gmain.c:3066
#33 g_main_context_dispatch (context=context@entry=0xcf5190) at gmain.c:3642
#34 0x0000003370c49628 in g_main_context_iterate (context=0xcf5190, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3713
#35 0x0000003370c49a3a in g_main_loop_run (loop=0xcf4e30) at gmain.c:3907
#36 0x0000000000429f15 in main (argc=1, argv=0x7fff8b1d4f38) at main.c:678
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-23 11:18:45 +02:00
|
|
|
nm_device_release_one_slave (self, info->slave, TRUE, reason);
|
2013-05-15 14:39:16 -05:00
|
|
|
}
|
2012-11-14 14:05:30 -06:00
|
|
|
}
|
|
|
|
|
|
2014-01-02 14:46:02 -05:00
|
|
|
/**
|
|
|
|
|
* nm_device_get_master:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the device
|
2014-01-02 14:46:02 -05:00
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* If @self has been enslaved by another device, this returns that
|
2014-01-02 14:46:02 -05:00
|
|
|
* device. Otherwise it returns %NULL. (In particular, note that if
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self is in the process of activating as a slave, but has not yet
|
2014-01-02 14:46:02 -05:00
|
|
|
* been enslaved by its master, this will return %NULL.)
|
|
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* Returns: (transfer none): @self's master, or %NULL
|
2014-01-02 14:46:02 -05:00
|
|
|
*/
|
|
|
|
|
NMDevice *
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_get_master (NMDevice *self)
|
2014-01-02 14:46:02 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-01-02 14:46:02 -05:00
|
|
|
|
|
|
|
|
if (priv->enslaved)
|
|
|
|
|
return priv->master;
|
|
|
|
|
else
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2012-11-14 14:05:30 -06:00
|
|
|
|
|
|
|
|
/**
|
2013-10-21 12:50:58 -04:00
|
|
|
* nm_device_slave_notify_enslave:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the slave device
|
2013-10-21 12:50:58 -04:00
|
|
|
* @success: whether the enslaving operation succeeded
|
2012-11-14 14:05:30 -06:00
|
|
|
*
|
2013-10-21 12:50:58 -04:00
|
|
|
* Notifies a slave that either it has been enslaved, or else its master tried
|
|
|
|
|
* to enslave it and failed.
|
2012-11-14 14:05:30 -06:00
|
|
|
*/
|
2013-11-18 12:06:10 -06:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_slave_notify_enslave (NMDevice *self, gboolean success)
|
2012-11-14 14:05:30 -06:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMConnection *connection = nm_device_get_connection (self);
|
2014-02-25 16:44:01 -05:00
|
|
|
gboolean activating = (priv->state == NM_DEVICE_STATE_IP_CONFIG);
|
2012-11-14 14:05:30 -06:00
|
|
|
|
2013-10-21 12:50:58 -04:00
|
|
|
g_assert (priv->master);
|
2012-11-14 14:05:30 -06:00
|
|
|
|
2014-02-25 16:44:01 -05:00
|
|
|
if (!priv->enslaved) {
|
|
|
|
|
if (success) {
|
|
|
|
|
if (activating) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: connection '%s' enslaved, continuing activation",
|
|
|
|
|
nm_connection_get_id (connection));
|
|
|
|
|
} else
|
|
|
|
|
_LOGI (LOGD_DEVICE, "enslaved to %s", nm_device_get_iface (priv->master));
|
2014-02-25 16:44:01 -05:00
|
|
|
|
|
|
|
|
priv->enslaved = TRUE;
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_MASTER);
|
2014-02-25 16:44:01 -05:00
|
|
|
} else if (activating) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE, "Activation: connection '%s' could not be enslaved",
|
|
|
|
|
nm_connection_get_id (connection));
|
2014-02-25 16:44:01 -05:00
|
|
|
}
|
2013-10-21 12:50:58 -04:00
|
|
|
}
|
|
|
|
|
|
2014-02-25 16:44:01 -05:00
|
|
|
if (activating) {
|
|
|
|
|
priv->ip4_state = IP_DONE;
|
|
|
|
|
priv->ip6_state = IP_DONE;
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_queue_state (self,
|
2014-02-25 16:44:01 -05:00
|
|
|
success ? NM_DEVICE_STATE_SECONDARIES : NM_DEVICE_STATE_FAILED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_NONE);
|
|
|
|
|
} else
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_queue_recheck_assume (self);
|
2013-10-21 12:50:58 -04:00
|
|
|
}
|
2013-01-17 15:44:30 -06:00
|
|
|
|
2013-10-21 12:50:58 -04:00
|
|
|
/**
|
|
|
|
|
* nm_device_slave_notify_release:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the slave device
|
2013-12-05 09:13:26 -05:00
|
|
|
* @reason: the reason associated with the state change
|
2013-10-21 12:50:58 -04:00
|
|
|
*
|
2013-12-05 09:13:26 -05:00
|
|
|
* Notifies a slave that it has been released, and why.
|
2013-10-21 12:50:58 -04:00
|
|
|
*/
|
2013-11-18 12:06:10 -06:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason)
|
2013-10-21 12:50:58 -04:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMConnection *connection = nm_device_get_connection (self);
|
2013-10-21 12:50:58 -04:00
|
|
|
NMDeviceState new_state;
|
2013-12-05 09:13:26 -05:00
|
|
|
const char *master_status;
|
2013-10-21 12:50:58 -04:00
|
|
|
|
2014-02-25 16:44:01 -05:00
|
|
|
if ( reason != NM_DEVICE_STATE_REASON_NONE
|
|
|
|
|
&& priv->state > NM_DEVICE_STATE_DISCONNECTED
|
2013-10-21 12:50:58 -04:00
|
|
|
&& priv->state <= NM_DEVICE_STATE_ACTIVATED) {
|
2013-12-05 09:13:26 -05:00
|
|
|
if (reason == NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED) {
|
2013-10-21 12:50:58 -04:00
|
|
|
new_state = NM_DEVICE_STATE_FAILED;
|
2013-12-05 09:13:26 -05:00
|
|
|
master_status = "failed";
|
|
|
|
|
} else if (reason == NM_DEVICE_STATE_REASON_USER_REQUESTED) {
|
|
|
|
|
new_state = NM_DEVICE_STATE_DEACTIVATING;
|
|
|
|
|
master_status = "deactivated by user request";
|
2013-10-21 12:50:58 -04:00
|
|
|
} else {
|
|
|
|
|
new_state = NM_DEVICE_STATE_DISCONNECTED;
|
2013-12-05 09:13:26 -05:00
|
|
|
master_status = "deactivated";
|
2012-11-14 14:05:30 -06:00
|
|
|
}
|
2013-10-21 12:50:58 -04:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "Activation: connection '%s' master %s",
|
|
|
|
|
nm_connection_get_id (connection),
|
|
|
|
|
master_status);
|
2013-12-05 09:13:26 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_queue_state (self, new_state, reason);
|
2014-02-12 23:54:26 +01:00
|
|
|
} else
|
|
|
|
|
_LOGI (LOGD_DEVICE, "released from master %s", nm_device_get_iface (priv->master));
|
2014-01-02 14:46:02 -05:00
|
|
|
|
|
|
|
|
if (priv->enslaved) {
|
|
|
|
|
priv->enslaved = FALSE;
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_MASTER);
|
2014-01-02 14:46:02 -05:00
|
|
|
}
|
2012-02-28 18:35:30 -06:00
|
|
|
}
|
|
|
|
|
|
2013-01-18 11:03:29 -06:00
|
|
|
/**
|
|
|
|
|
* nm_device_get_enslaved:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the #NMDevice
|
2013-01-18 11:03:29 -06:00
|
|
|
*
|
|
|
|
|
* Returns: %TRUE if the device is enslaved to a master device (eg bridge or
|
2013-07-25 15:36:45 +02:00
|
|
|
* bond or team), %FALSE if not
|
2013-01-18 11:03:29 -06:00
|
|
|
*/
|
|
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_get_enslaved (NMDevice *self)
|
2013-01-18 11:03:29 -06:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->enslaved;
|
2013-01-18 11:03:29 -06:00
|
|
|
}
|
|
|
|
|
|
2012-11-12 13:29:06 -05:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
is_available (NMDevice *self)
|
2012-11-12 13:29:06 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2011-10-18 13:48:48 +02:00
|
|
|
|
2013-11-04 19:51:28 -06:00
|
|
|
return priv->carrier || priv->ignore_carrier;
|
2011-10-18 13:48:48 +02:00
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2013-07-12 10:43:45 -04:00
|
|
|
/**
|
|
|
|
|
* nm_device_is_available:
|
|
|
|
|
* @self: the #NMDevice
|
|
|
|
|
*
|
|
|
|
|
* Checks if @self would currently be capable of activating a
|
|
|
|
|
* connection. In particular, it checks that the device is ready (eg,
|
|
|
|
|
* is not missing firmware), that it has carrier (if necessary), and
|
|
|
|
|
* that any necessary external software (eg, ModemManager,
|
|
|
|
|
* wpa_supplicant) is available.
|
|
|
|
|
*
|
|
|
|
|
* @self can only be in a state higher than
|
|
|
|
|
* %NM_DEVICE_STATE_UNAVAILABLE when nm_device_is_available() returns
|
|
|
|
|
* %TRUE. (But note that it can still be %NM_DEVICE_STATE_UNMANAGED
|
|
|
|
|
* when it is available.)
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE or %FALSE
|
|
|
|
|
*/
|
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
|
2013-03-19 09:17:41 -04:00
|
|
|
nm_device_is_available (NMDevice *self)
|
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
|
|
|
{
|
2010-05-25 10:52:25 -07:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->firmware_missing)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2013-05-07 10:23:44 -04:00
|
|
|
return NM_DEVICE_GET_CLASS (self)->is_available (self);
|
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
|
|
|
}
|
|
|
|
|
|
2011-11-17 23:28:30 -06:00
|
|
|
gboolean
|
|
|
|
|
nm_device_get_enabled (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
|
|
|
|
|
|
|
|
|
if (NM_DEVICE_GET_CLASS (self)->get_enabled)
|
|
|
|
|
return NM_DEVICE_GET_CLASS (self)->get_enabled (self);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-17 23:38:08 -06:00
|
|
|
void
|
|
|
|
|
nm_device_set_enabled (NMDevice *self, gboolean enabled)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
|
|
|
|
|
|
|
|
|
if (NM_DEVICE_GET_CLASS (self)->set_enabled)
|
|
|
|
|
NM_DEVICE_GET_CLASS (self)->set_enabled (self, enabled);
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-20 16:09:22 -05:00
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_get_autoconnect (NMDevice *self)
|
2011-11-18 12:02:58 -06:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
2011-11-18 12:02:58 -06:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->autoconnect;
|
2011-11-18 12:02:58 -06:00
|
|
|
}
|
|
|
|
|
|
2009-07-15 17:22:10 -04:00
|
|
|
static gboolean
|
|
|
|
|
autoconnect_allowed_accumulator (GSignalInvocationHint *ihint,
|
|
|
|
|
GValue *return_accu,
|
|
|
|
|
const GValue *handler_return, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
if (!g_value_get_boolean (handler_return))
|
|
|
|
|
g_value_set_boolean (return_accu, FALSE);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_device_autoconnect_allowed (NMDevice *self)
|
|
|
|
|
{
|
2009-09-16 13:18:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-03-22 10:49:19 +01:00
|
|
|
GValue instance = G_VALUE_INIT;
|
|
|
|
|
GValue retval = G_VALUE_INIT;
|
2009-07-15 17:22:10 -04:00
|
|
|
|
|
|
|
|
g_value_init (&instance, G_TYPE_OBJECT);
|
2014-05-05 20:58:27 +02:00
|
|
|
g_value_set_object (&instance, self);
|
2009-07-15 17:22:10 -04:00
|
|
|
|
|
|
|
|
g_value_init (&retval, G_TYPE_BOOLEAN);
|
2012-05-14 15:32:54 +02:00
|
|
|
if (priv->autoconnect)
|
2009-09-16 13:18:24 +02:00
|
|
|
g_value_set_boolean (&retval, TRUE);
|
2012-05-14 15:32:54 +02:00
|
|
|
else
|
|
|
|
|
g_value_set_boolean (&retval, FALSE);
|
2009-07-15 17:22:10 -04:00
|
|
|
|
|
|
|
|
/* Use g_signal_emitv() rather than g_signal_emit() to avoid the return
|
|
|
|
|
* value being changed if no handlers are connected */
|
|
|
|
|
g_signal_emitv (&instance, signals[AUTOCONNECT_ALLOWED], 0, &retval);
|
2014-05-05 20:58:27 +02:00
|
|
|
g_value_unset (&instance);
|
2009-07-15 17:22:10 -04:00
|
|
|
return g_value_get_boolean (&retval);
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-06 16:16:54 -05:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
can_auto_connect (NMDevice *self,
|
2013-03-06 16:16:54 -05:00
|
|
|
NMConnection *connection,
|
|
|
|
|
char **specific_object)
|
|
|
|
|
{
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
|
|
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
|
|
|
|
if (!nm_setting_connection_get_autoconnect (s_con))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
return nm_device_connection_is_available (self, connection, FALSE);
|
2013-03-06 16:16:54 -05:00
|
|
|
}
|
|
|
|
|
|
2013-06-27 14:39:13 +02:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
device_has_config (NMDevice *self)
|
2013-06-27 14:39:13 +02:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-06-27 14:39:13 +02:00
|
|
|
|
|
|
|
|
/* Check for IP configuration. */
|
|
|
|
|
if (priv->ip4_config && nm_ip4_config_get_num_addresses (priv->ip4_config))
|
|
|
|
|
return TRUE;
|
|
|
|
|
if (priv->ip6_config && nm_ip6_config_get_num_addresses (priv->ip6_config))
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
/* The existence of a software device is good enough. */
|
2014-07-15 13:36:24 +02:00
|
|
|
if (nm_device_is_software (self))
|
2013-06-27 14:39:13 +02:00
|
|
|
return TRUE;
|
|
|
|
|
|
2013-11-07 01:11:51 -06:00
|
|
|
/* Slaves are also configured by definition */
|
|
|
|
|
if (nm_platform_link_get_master (priv->ifindex) > 0)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
2013-06-27 14:39:13 +02:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-18 20:17:57 +02:00
|
|
|
/**
|
|
|
|
|
* nm_device_master_update_slave_connection:
|
|
|
|
|
* @self: the master #NMDevice
|
|
|
|
|
* @slave: the slave #NMDevice
|
|
|
|
|
* @connection: the #NMConnection to update with the slave settings
|
|
|
|
|
* @GError: (out): error description
|
|
|
|
|
*
|
|
|
|
|
* Reads the slave configuration for @slave and updates @connection with those
|
|
|
|
|
* properties. This invokes a virtual function on the master device @self.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE if the configuration was read and @connection updated,
|
|
|
|
|
* %FALSE on failure.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
|
|
|
|
nm_device_master_update_slave_connection (NMDevice *self,
|
|
|
|
|
NMDevice *slave,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceClass *klass;
|
|
|
|
|
gboolean success;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (self, FALSE);
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
|
|
|
|
g_return_val_if_fail (slave, FALSE);
|
|
|
|
|
g_return_val_if_fail (connection, FALSE);
|
|
|
|
|
g_return_val_if_fail (!error || !*error, FALSE);
|
|
|
|
|
g_return_val_if_fail (nm_connection_get_setting_connection (connection), FALSE);
|
|
|
|
|
|
2014-08-02 00:48:35 +02:00
|
|
|
g_return_val_if_fail (nm_device_get_iface (self), FALSE);
|
2014-06-18 20:17:57 +02:00
|
|
|
|
|
|
|
|
klass = NM_DEVICE_GET_CLASS (self);
|
|
|
|
|
if (klass->master_update_slave_connection) {
|
|
|
|
|
success = klass->master_update_slave_connection (self, slave, connection, error);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (!error || (success && !*error) || *error, success);
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_set_error (error,
|
|
|
|
|
NM_DEVICE_ERROR,
|
|
|
|
|
NM_DEVICE_ERROR_UNSUPPORTED_DEVICE_TYPE,
|
|
|
|
|
"master device '%s' cannot update a slave connection for slave device '%s' (master type not supported?)",
|
2014-08-02 00:48:35 +02:00
|
|
|
nm_device_get_iface (self), nm_device_get_iface (slave));
|
2014-06-18 20:17:57 +02:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-27 14:39:13 +02:00
|
|
|
NMConnection *
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_generate_connection (NMDevice *self, NMDevice *master)
|
2013-06-27 14:39:13 +02:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
const char *ifname = nm_device_get_iface (self);
|
2013-06-27 14:39:13 +02:00
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSetting *s_con;
|
|
|
|
|
NMSetting *s_ip4;
|
|
|
|
|
NMSetting *s_ip6;
|
|
|
|
|
gs_free char *uuid = NULL;
|
2013-11-08 00:35:42 -06:00
|
|
|
const char *ip4_method, *ip6_method;
|
2014-03-26 12:39:13 -04:00
|
|
|
GError *error = NULL;
|
2013-06-27 14:39:13 +02:00
|
|
|
|
|
|
|
|
/* If update_connection() is not implemented, just fail. */
|
|
|
|
|
if (!klass->update_connection)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* Return NULL if device is unconfigured. */
|
2014-07-15 13:36:24 +02:00
|
|
|
if (!device_has_config (self)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "device has no existing configuration");
|
2013-06-27 14:39:13 +02:00
|
|
|
return NULL;
|
2013-11-14 10:01:24 -06:00
|
|
|
}
|
2013-06-27 14:39:13 +02:00
|
|
|
|
2014-08-13 14:34:29 -04:00
|
|
|
connection = nm_simple_connection_new ();
|
2013-06-27 14:39:13 +02:00
|
|
|
s_con = nm_setting_connection_new ();
|
|
|
|
|
uuid = nm_utils_uuid_generate ();
|
|
|
|
|
|
|
|
|
|
g_object_set (s_con,
|
|
|
|
|
NM_SETTING_CONNECTION_UUID, uuid,
|
2014-07-26 02:30:22 +02:00
|
|
|
NM_SETTING_CONNECTION_ID, ifname,
|
2013-06-27 14:39:13 +02:00
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
|
2014-03-18 14:21:59 +01:00
|
|
|
NM_SETTING_CONNECTION_INTERFACE_NAME, ifname,
|
2013-06-27 14:39:13 +02:00
|
|
|
NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL),
|
|
|
|
|
NULL);
|
|
|
|
|
if (klass->connection_type)
|
|
|
|
|
g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, klass->connection_type, NULL);
|
|
|
|
|
nm_connection_add_setting (connection, s_con);
|
2013-11-06 14:13:59 -06:00
|
|
|
|
2013-08-22 20:41:01 +02:00
|
|
|
/* If the device is a slave, update various slave settings */
|
2014-06-18 20:17:57 +02:00
|
|
|
if (master) {
|
|
|
|
|
if (!nm_device_master_update_slave_connection (master,
|
2014-07-15 13:36:24 +02:00
|
|
|
self,
|
2014-06-18 20:17:57 +02:00
|
|
|
connection,
|
|
|
|
|
&error))
|
|
|
|
|
{
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGE (LOGD_DEVICE, "master device '%s' failed to update slave connection: %s",
|
|
|
|
|
nm_device_get_iface (master), error ? error->message : "(unknown error)");
|
2014-06-18 20:17:57 +02:00
|
|
|
g_error_free (error);
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
2013-08-22 20:41:01 +02:00
|
|
|
}
|
2013-11-14 10:01:24 -06:00
|
|
|
} else {
|
|
|
|
|
/* Only regular and master devices get IP configuration; slaves do not */
|
2014-05-19 10:24:15 -04:00
|
|
|
s_ip4 = nm_ip4_config_create_setting (priv->ip4_config);
|
2013-11-14 10:01:24 -06:00
|
|
|
nm_connection_add_setting (connection, s_ip4);
|
|
|
|
|
|
2014-05-19 10:24:15 -04:00
|
|
|
s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
|
2013-11-14 10:01:24 -06:00
|
|
|
nm_connection_add_setting (connection, s_ip6);
|
2013-08-22 20:41:01 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
klass->update_connection (self, connection);
|
2013-06-27 14:39:13 +02:00
|
|
|
|
|
|
|
|
/* Check the connection in case of update_connection() bug. */
|
2014-03-26 12:39:13 -04:00
|
|
|
if (!nm_connection_verify (connection, &error)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGE (LOGD_DEVICE, "Generated connection does not verify: %s", error->message);
|
2014-03-26 12:39:13 -04:00
|
|
|
g_clear_error (&error);
|
|
|
|
|
g_object_unref (connection);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2013-06-27 14:39:13 +02:00
|
|
|
|
2013-11-08 00:35:42 -06:00
|
|
|
/* Ignore the connection if it has no IP configuration,
|
|
|
|
|
* no slave configuration, and is not a master interface.
|
|
|
|
|
*/
|
2013-11-14 10:01:24 -06:00
|
|
|
ip4_method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
|
|
|
|
ip6_method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
|
|
|
|
if ( g_strcmp0 (ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0
|
|
|
|
|
&& g_strcmp0 (ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0
|
2014-05-29 13:54:50 -04:00
|
|
|
&& !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con))) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "ignoring generated connection (no IP and not slave)");
|
2013-11-08 00:35:42 -06:00
|
|
|
g_object_unref (connection);
|
|
|
|
|
connection = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-27 14:39:13 +02:00
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 13:52:55 -04:00
|
|
|
/**
|
|
|
|
|
* nm_device_get_best_auto_connection:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: an #NMDevice
|
2013-03-13 13:52:55 -04:00
|
|
|
* @connections: (element-type #NMConnection): a list of connections
|
|
|
|
|
* @specific_object: (out) (transfer full): on output, the path of an
|
|
|
|
|
* object associated with the returned connection, to be passed to
|
|
|
|
|
* nm_manager_activate_connection(), or %NULL.
|
|
|
|
|
*
|
|
|
|
|
* Looks through @connections to see if there is a connection that can
|
2014-07-15 13:36:24 +02:00
|
|
|
* be auto-activated on @self right now. This requires, at a minimum,
|
|
|
|
|
* that the connection be compatible with @self, and that it have the
|
2013-03-13 13:52:55 -04:00
|
|
|
* #NMSettingConnection:autoconnect property set. Some devices impose
|
|
|
|
|
* additional requirements. (Eg, a Wi-Fi connection can only be
|
|
|
|
|
* activated if its SSID was seen in the last scan.)
|
|
|
|
|
*
|
|
|
|
|
* Returns: an auto-activatable #NMConnection, or %NULL if none are
|
|
|
|
|
* available.
|
|
|
|
|
*/
|
|
|
|
|
|
2007-09-09 17:58:44 +00:00
|
|
|
NMConnection *
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_get_best_auto_connection (NMDevice *self,
|
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
|
|
|
GSList *connections,
|
|
|
|
|
char **specific_object)
|
2007-09-09 17:58:44 +00:00
|
|
|
{
|
2013-03-06 16:16:54 -05:00
|
|
|
GSList *iter;
|
2007-09-09 17:58:44 +00:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
2007-09-10 19:11:40 +00:00
|
|
|
g_return_val_if_fail (specific_object != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (*specific_object == NULL, NULL);
|
2007-09-09 17:58:44 +00:00
|
|
|
|
2012-11-08 13:15:51 -05:00
|
|
|
for (iter = connections; iter; iter = iter->next) {
|
|
|
|
|
NMConnection *connection = NM_CONNECTION (iter->data);
|
2012-11-12 13:29:06 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object))
|
2013-03-06 16:16:54 -05:00
|
|
|
return connection;
|
2012-11-08 13:15:51 -05:00
|
|
|
}
|
|
|
|
|
|
2013-03-06 16:16:54 -05:00
|
|
|
return NULL;
|
2007-09-09 17:58:44 +00:00
|
|
|
}
|
|
|
|
|
|
2011-01-10 23:39:12 -06:00
|
|
|
gboolean
|
|
|
|
|
nm_device_complete_connection (NMDevice *self,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
const char *specific_object,
|
|
|
|
|
const GSList *existing_connections,
|
|
|
|
|
GError **error)
|
|
|
|
|
{
|
|
|
|
|
gboolean success = FALSE;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (self != NULL, FALSE);
|
|
|
|
|
g_return_val_if_fail (connection != NULL, FALSE);
|
|
|
|
|
|
|
|
|
|
if (!NM_DEVICE_GET_CLASS (self)->complete_connection) {
|
2011-11-18 00:05:37 -06:00
|
|
|
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CONNECTION_INVALID,
|
2011-01-10 23:39:12 -06:00
|
|
|
"Device class %s had no complete_connection method",
|
|
|
|
|
G_OBJECT_TYPE_NAME (self));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
success = NM_DEVICE_GET_CLASS (self)->complete_connection (self,
|
|
|
|
|
connection,
|
|
|
|
|
specific_object,
|
|
|
|
|
existing_connections,
|
|
|
|
|
error);
|
|
|
|
|
if (success)
|
|
|
|
|
success = nm_connection_verify (connection, error);
|
|
|
|
|
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-07 07:44:36 -05:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
check_connection_compatible (NMDevice *self, NMConnection *connection)
|
2013-03-07 07:44:36 -05:00
|
|
|
{
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
const char *config_iface, *device_iface;
|
|
|
|
|
|
|
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
|
|
|
|
|
config_iface = nm_setting_connection_get_interface_name (s_con);
|
2014-07-15 13:36:24 +02:00
|
|
|
device_iface = nm_device_get_iface (self);
|
2014-05-30 13:44:53 -05:00
|
|
|
if (config_iface && strcmp (config_iface, device_iface) != 0)
|
2013-03-07 07:44:36 -05:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 13:52:55 -04:00
|
|
|
/**
|
|
|
|
|
* nm_device_check_connection_compatible:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: an #NMDevice
|
2013-03-13 13:52:55 -04:00
|
|
|
* @connection: an #NMConnection
|
|
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* Checks if @connection could potentially be activated on @self.
|
|
|
|
|
* This means only that @self has the proper capabilities, and that
|
2013-03-13 13:52:55 -04:00
|
|
|
* @connection is not locked to some other device. It does not
|
2014-07-15 13:36:24 +02:00
|
|
|
* necessarily mean that @connection could be activated on @self
|
2013-03-13 13:52:55 -04:00
|
|
|
* right now. (Eg, it might refer to a Wi-Fi network that is not
|
|
|
|
|
* currently available.)
|
|
|
|
|
*
|
|
|
|
|
* Returns: #TRUE if @connection could potentially be activated on
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self.
|
2013-03-13 13:52:55 -04:00
|
|
|
*/
|
2011-11-17 23:04:47 -06:00
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_check_connection_compatible (NMDevice *self, NMConnection *connection)
|
2011-11-17 23:04:47 -06:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
2011-11-17 23:04:47 -06:00
|
|
|
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
return NM_DEVICE_GET_CLASS (self)->check_connection_compatible (self, connection);
|
2011-11-17 23:04:47 -06:00
|
|
|
}
|
|
|
|
|
|
core: don't do anything interesting in NMDevice dispose()
The NMDevice dispose() function contained some badly-duplicated logic
about when to deactivate a device on its last ref. This logic should
only run when the device is removed by the manager, since the manager
controls the device's life-cycle, and the manager knows best when to
clean up the device. But since it was tied to the device's refcount,
it could have run later than the manager wanted, or not at all.
It gets better. Dispose duplicated logic that was already done in
nm_device_cleanup(), and then *called* nm_device_cleanup() if the
device was still activated and managed. But the manager already
unmanages the device when removing it, which triggers a call to
nm_device_cleanup(), takes the device down, and resets the IPv6
sysctl properties, which dispose() duplicated too. So by the time
dispose() runs, the device should already be unmanaged if the
manager wants to deconfigure it, and most of the dispose() code
should be a no-op.
Clean all that up and remove duplicated functions. Now, the flow
should be like this:
1) manager decides to remove the device and calls remove_device()
2) if the device should be deconfigured, the manager unmanages
the device
3) the NMDevice state change handler tears down the active connection
via nm_device_cleanup() and resets IPv6 sysctl properties
4) when the device's last reference is finally released, only internal
data members are freed in dispose() because the device should
already have been cleaned up by the manager and be unmanaged
5) if the device should be left running because it has an assumable
connection, then the device is not unmanaged, and no cleanup
happens in the state change handler or in dispose()
2014-05-23 15:41:46 -05:00
|
|
|
static gboolean
|
|
|
|
|
string_in_list (const char *str, const char **array, gsize array_len)
|
|
|
|
|
{
|
|
|
|
|
gsize i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < array_len; i++) {
|
|
|
|
|
if (strcmp (str, array[i]) == 0)
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-27 14:39:13 +02:00
|
|
|
/**
|
|
|
|
|
* nm_device_can_assume_connections:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: #NMDevice instance
|
2013-06-27 14:39:13 +02:00
|
|
|
*
|
|
|
|
|
* This is a convenience function to determine whether connection assumption
|
|
|
|
|
* is available for this device.
|
|
|
|
|
*
|
core: don't do anything interesting in NMDevice dispose()
The NMDevice dispose() function contained some badly-duplicated logic
about when to deactivate a device on its last ref. This logic should
only run when the device is removed by the manager, since the manager
controls the device's life-cycle, and the manager knows best when to
clean up the device. But since it was tied to the device's refcount,
it could have run later than the manager wanted, or not at all.
It gets better. Dispose duplicated logic that was already done in
nm_device_cleanup(), and then *called* nm_device_cleanup() if the
device was still activated and managed. But the manager already
unmanages the device when removing it, which triggers a call to
nm_device_cleanup(), takes the device down, and resets the IPv6
sysctl properties, which dispose() duplicated too. So by the time
dispose() runs, the device should already be unmanaged if the
manager wants to deconfigure it, and most of the dispose() code
should be a no-op.
Clean all that up and remove duplicated functions. Now, the flow
should be like this:
1) manager decides to remove the device and calls remove_device()
2) if the device should be deconfigured, the manager unmanages
the device
3) the NMDevice state change handler tears down the active connection
via nm_device_cleanup() and resets IPv6 sysctl properties
4) when the device's last reference is finally released, only internal
data members are freed in dispose() because the device should
already have been cleaned up by the manager and be unmanaged
5) if the device should be left running because it has an assumable
connection, then the device is not unmanaged, and no cleanup
happens in the state change handler or in dispose()
2014-05-23 15:41:46 -05:00
|
|
|
* Returns: %TRUE if the device is capable of assuming connections, %FALSE if not
|
|
|
|
|
*/
|
|
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_can_assume_connections (NMDevice *self)
|
core: don't do anything interesting in NMDevice dispose()
The NMDevice dispose() function contained some badly-duplicated logic
about when to deactivate a device on its last ref. This logic should
only run when the device is removed by the manager, since the manager
controls the device's life-cycle, and the manager knows best when to
clean up the device. But since it was tied to the device's refcount,
it could have run later than the manager wanted, or not at all.
It gets better. Dispose duplicated logic that was already done in
nm_device_cleanup(), and then *called* nm_device_cleanup() if the
device was still activated and managed. But the manager already
unmanages the device when removing it, which triggers a call to
nm_device_cleanup(), takes the device down, and resets the IPv6
sysctl properties, which dispose() duplicated too. So by the time
dispose() runs, the device should already be unmanaged if the
manager wants to deconfigure it, and most of the dispose() code
should be a no-op.
Clean all that up and remove duplicated functions. Now, the flow
should be like this:
1) manager decides to remove the device and calls remove_device()
2) if the device should be deconfigured, the manager unmanages
the device
3) the NMDevice state change handler tears down the active connection
via nm_device_cleanup() and resets IPv6 sysctl properties
4) when the device's last reference is finally released, only internal
data members are freed in dispose() because the device should
already have been cleaned up by the manager and be unmanaged
5) if the device should be left running because it has an assumable
connection, then the device is not unmanaged, and no cleanup
happens in the state change handler or in dispose()
2014-05-23 15:41:46 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
return !!NM_DEVICE_GET_CLASS (self)->update_connection;
|
core: don't do anything interesting in NMDevice dispose()
The NMDevice dispose() function contained some badly-duplicated logic
about when to deactivate a device on its last ref. This logic should
only run when the device is removed by the manager, since the manager
controls the device's life-cycle, and the manager knows best when to
clean up the device. But since it was tied to the device's refcount,
it could have run later than the manager wanted, or not at all.
It gets better. Dispose duplicated logic that was already done in
nm_device_cleanup(), and then *called* nm_device_cleanup() if the
device was still activated and managed. But the manager already
unmanages the device when removing it, which triggers a call to
nm_device_cleanup(), takes the device down, and resets the IPv6
sysctl properties, which dispose() duplicated too. So by the time
dispose() runs, the device should already be unmanaged if the
manager wants to deconfigure it, and most of the dispose() code
should be a no-op.
Clean all that up and remove duplicated functions. Now, the flow
should be like this:
1) manager decides to remove the device and calls remove_device()
2) if the device should be deconfigured, the manager unmanages
the device
3) the NMDevice state change handler tears down the active connection
via nm_device_cleanup() and resets IPv6 sysctl properties
4) when the device's last reference is finally released, only internal
data members are freed in dispose() because the device should
already have been cleaned up by the manager and be unmanaged
5) if the device should be left running because it has an assumable
connection, then the device is not unmanaged, and no cleanup
happens in the state change handler or in dispose()
2014-05-23 15:41:46 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_can_assume_active_connection:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: #NMDevice instance
|
2013-06-27 14:39:13 +02:00
|
|
|
*
|
core: don't do anything interesting in NMDevice dispose()
The NMDevice dispose() function contained some badly-duplicated logic
about when to deactivate a device on its last ref. This logic should
only run when the device is removed by the manager, since the manager
controls the device's life-cycle, and the manager knows best when to
clean up the device. But since it was tied to the device's refcount,
it could have run later than the manager wanted, or not at all.
It gets better. Dispose duplicated logic that was already done in
nm_device_cleanup(), and then *called* nm_device_cleanup() if the
device was still activated and managed. But the manager already
unmanages the device when removing it, which triggers a call to
nm_device_cleanup(), takes the device down, and resets the IPv6
sysctl properties, which dispose() duplicated too. So by the time
dispose() runs, the device should already be unmanaged if the
manager wants to deconfigure it, and most of the dispose() code
should be a no-op.
Clean all that up and remove duplicated functions. Now, the flow
should be like this:
1) manager decides to remove the device and calls remove_device()
2) if the device should be deconfigured, the manager unmanages
the device
3) the NMDevice state change handler tears down the active connection
via nm_device_cleanup() and resets IPv6 sysctl properties
4) when the device's last reference is finally released, only internal
data members are freed in dispose() because the device should
already have been cleaned up by the manager and be unmanaged
5) if the device should be left running because it has an assumable
connection, then the device is not unmanaged, and no cleanup
happens in the state change handler or in dispose()
2014-05-23 15:41:46 -05:00
|
|
|
* This is a convenience function to determine whether the device's active
|
|
|
|
|
* connection can be assumed if NetworkManager restarts. This method returns
|
|
|
|
|
* %TRUE if and only if the device can assume connections, and the device has
|
|
|
|
|
* an active connection, and that active connection can be assumed.
|
2013-06-27 14:39:13 +02:00
|
|
|
*
|
core: don't do anything interesting in NMDevice dispose()
The NMDevice dispose() function contained some badly-duplicated logic
about when to deactivate a device on its last ref. This logic should
only run when the device is removed by the manager, since the manager
controls the device's life-cycle, and the manager knows best when to
clean up the device. But since it was tied to the device's refcount,
it could have run later than the manager wanted, or not at all.
It gets better. Dispose duplicated logic that was already done in
nm_device_cleanup(), and then *called* nm_device_cleanup() if the
device was still activated and managed. But the manager already
unmanages the device when removing it, which triggers a call to
nm_device_cleanup(), takes the device down, and resets the IPv6
sysctl properties, which dispose() duplicated too. So by the time
dispose() runs, the device should already be unmanaged if the
manager wants to deconfigure it, and most of the dispose() code
should be a no-op.
Clean all that up and remove duplicated functions. Now, the flow
should be like this:
1) manager decides to remove the device and calls remove_device()
2) if the device should be deconfigured, the manager unmanages
the device
3) the NMDevice state change handler tears down the active connection
via nm_device_cleanup() and resets IPv6 sysctl properties
4) when the device's last reference is finally released, only internal
data members are freed in dispose() because the device should
already have been cleaned up by the manager and be unmanaged
5) if the device should be left running because it has an assumable
connection, then the device is not unmanaged, and no cleanup
happens in the state change handler or in dispose()
2014-05-23 15:41:46 -05:00
|
|
|
* Returns: %TRUE if the device's active connection can be assumed, or %FALSE
|
|
|
|
|
* if there is no active connection or the active connection cannot be
|
|
|
|
|
* assumed.
|
2013-06-27 14:39:13 +02:00
|
|
|
*/
|
2011-11-17 23:10:11 -06:00
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_can_assume_active_connection (NMDevice *self)
|
2011-11-17 23:10:11 -06:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
core: don't do anything interesting in NMDevice dispose()
The NMDevice dispose() function contained some badly-duplicated logic
about when to deactivate a device on its last ref. This logic should
only run when the device is removed by the manager, since the manager
controls the device's life-cycle, and the manager knows best when to
clean up the device. But since it was tied to the device's refcount,
it could have run later than the manager wanted, or not at all.
It gets better. Dispose duplicated logic that was already done in
nm_device_cleanup(), and then *called* nm_device_cleanup() if the
device was still activated and managed. But the manager already
unmanages the device when removing it, which triggers a call to
nm_device_cleanup(), takes the device down, and resets the IPv6
sysctl properties, which dispose() duplicated too. So by the time
dispose() runs, the device should already be unmanaged if the
manager wants to deconfigure it, and most of the dispose() code
should be a no-op.
Clean all that up and remove duplicated functions. Now, the flow
should be like this:
1) manager decides to remove the device and calls remove_device()
2) if the device should be deconfigured, the manager unmanages
the device
3) the NMDevice state change handler tears down the active connection
via nm_device_cleanup() and resets IPv6 sysctl properties
4) when the device's last reference is finally released, only internal
data members are freed in dispose() because the device should
already have been cleaned up by the manager and be unmanaged
5) if the device should be left running because it has an assumable
connection, then the device is not unmanaged, and no cleanup
happens in the state change handler or in dispose()
2014-05-23 15:41:46 -05:00
|
|
|
NMConnection *connection;
|
|
|
|
|
const char *method;
|
|
|
|
|
const char *assumable_ip6_methods[] = {
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_AUTO,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_DHCP,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
|
|
|
|
|
};
|
|
|
|
|
const char *assumable_ip4_methods[] = {
|
|
|
|
|
NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_AUTO,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
|
|
|
|
|
};
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (!nm_device_can_assume_connections (self))
|
core: don't do anything interesting in NMDevice dispose()
The NMDevice dispose() function contained some badly-duplicated logic
about when to deactivate a device on its last ref. This logic should
only run when the device is removed by the manager, since the manager
controls the device's life-cycle, and the manager knows best when to
clean up the device. But since it was tied to the device's refcount,
it could have run later than the manager wanted, or not at all.
It gets better. Dispose duplicated logic that was already done in
nm_device_cleanup(), and then *called* nm_device_cleanup() if the
device was still activated and managed. But the manager already
unmanages the device when removing it, which triggers a call to
nm_device_cleanup(), takes the device down, and resets the IPv6
sysctl properties, which dispose() duplicated too. So by the time
dispose() runs, the device should already be unmanaged if the
manager wants to deconfigure it, and most of the dispose() code
should be a no-op.
Clean all that up and remove duplicated functions. Now, the flow
should be like this:
1) manager decides to remove the device and calls remove_device()
2) if the device should be deconfigured, the manager unmanages
the device
3) the NMDevice state change handler tears down the active connection
via nm_device_cleanup() and resets IPv6 sysctl properties
4) when the device's last reference is finally released, only internal
data members are freed in dispose() because the device should
already have been cleaned up by the manager and be unmanaged
5) if the device should be left running because it has an assumable
connection, then the device is not unmanaged, and no cleanup
happens in the state change handler or in dispose()
2014-05-23 15:41:46 -05:00
|
|
|
return FALSE;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
connection = nm_device_get_connection (self);
|
core: don't do anything interesting in NMDevice dispose()
The NMDevice dispose() function contained some badly-duplicated logic
about when to deactivate a device on its last ref. This logic should
only run when the device is removed by the manager, since the manager
controls the device's life-cycle, and the manager knows best when to
clean up the device. But since it was tied to the device's refcount,
it could have run later than the manager wanted, or not at all.
It gets better. Dispose duplicated logic that was already done in
nm_device_cleanup(), and then *called* nm_device_cleanup() if the
device was still activated and managed. But the manager already
unmanages the device when removing it, which triggers a call to
nm_device_cleanup(), takes the device down, and resets the IPv6
sysctl properties, which dispose() duplicated too. So by the time
dispose() runs, the device should already be unmanaged if the
manager wants to deconfigure it, and most of the dispose() code
should be a no-op.
Clean all that up and remove duplicated functions. Now, the flow
should be like this:
1) manager decides to remove the device and calls remove_device()
2) if the device should be deconfigured, the manager unmanages
the device
3) the NMDevice state change handler tears down the active connection
via nm_device_cleanup() and resets IPv6 sysctl properties
4) when the device's last reference is finally released, only internal
data members are freed in dispose() because the device should
already have been cleaned up by the manager and be unmanaged
5) if the device should be left running because it has an assumable
connection, then the device is not unmanaged, and no cleanup
happens in the state change handler or in dispose()
2014-05-23 15:41:46 -05:00
|
|
|
if (!connection)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
/* Can't assume connections that aren't yet configured
|
|
|
|
|
* FIXME: what about bridges/bonds waiting for slaves?
|
|
|
|
|
*/
|
|
|
|
|
if (priv->state < NM_DEVICE_STATE_IP_CONFIG)
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (priv->ip4_state != IP_DONE && priv->ip6_state != IP_DONE)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
|
|
|
|
if (!string_in_list (method, assumable_ip6_methods, G_N_ELEMENTS (assumable_ip6_methods)))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
|
|
|
|
if (!string_in_list (method, assumable_ip4_methods, G_N_ELEMENTS (assumable_ip4_methods)))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
2011-11-17 23:10:11 -06:00
|
|
|
}
|
|
|
|
|
|
2014-05-28 10:18:34 -04:00
|
|
|
static gboolean
|
|
|
|
|
nm_device_emit_recheck_assume (gpointer self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
priv->recheck_assume_id = 0;
|
|
|
|
|
if (!nm_device_get_act_request (self) && (priv->ip4_config || priv->ip6_config))
|
|
|
|
|
g_signal_emit (self, signals[RECHECK_ASSUME], 0);
|
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_device_queue_recheck_assume (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (nm_device_can_assume_connections (self) && !priv->recheck_assume_id)
|
|
|
|
|
priv->recheck_assume_id = g_idle_add (nm_device_emit_recheck_assume, self);
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-24 18:10:18 -06:00
|
|
|
void
|
|
|
|
|
nm_device_emit_recheck_auto_activate (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_signal_emit (self, signals[RECHECK_AUTO_ACTIVATE], 0);
|
|
|
|
|
}
|
|
|
|
|
|
2008-05-29 20:58:52 +00:00
|
|
|
static void
|
|
|
|
|
dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
|
|
|
|
|
switch (status) {
|
|
|
|
|
case NM_DNSMASQ_STATUS_DEAD:
|
2008-07-11 10:28:53 +00:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
|
2008-05-29 20:58:52 +00:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-23 17:36:52 -04:00
|
|
|
static void
|
2009-07-29 12:12:41 -04:00
|
|
|
activation_source_clear (NMDevice *self, gboolean remove_source, int family)
|
2009-03-23 17:36:52 -04:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2009-07-29 12:12:41 -04:00
|
|
|
guint *act_source_id;
|
|
|
|
|
gpointer *act_source_func;
|
|
|
|
|
|
|
|
|
|
if (family == AF_INET6) {
|
|
|
|
|
act_source_id = &priv->act_source6_id;
|
|
|
|
|
act_source_func = &priv->act_source6_func;
|
|
|
|
|
} else {
|
|
|
|
|
act_source_id = &priv->act_source_id;
|
|
|
|
|
act_source_func = &priv->act_source_func;
|
|
|
|
|
}
|
2009-03-23 17:36:52 -04:00
|
|
|
|
2009-07-29 12:12:41 -04:00
|
|
|
if (*act_source_id) {
|
2009-03-23 17:36:52 -04:00
|
|
|
if (remove_source)
|
2009-07-29 12:12:41 -04:00
|
|
|
g_source_remove (*act_source_id);
|
|
|
|
|
*act_source_id = 0;
|
|
|
|
|
*act_source_func = NULL;
|
2009-03-23 17:36:52 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2009-07-29 12:12:41 -04:00
|
|
|
activation_source_schedule (NMDevice *self, GSourceFunc func, int family)
|
2009-03-23 17:36:52 -04:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2009-07-29 12:12:41 -04:00
|
|
|
guint *act_source_id;
|
|
|
|
|
gpointer *act_source_func;
|
2009-03-23 17:36:52 -04:00
|
|
|
|
2009-07-29 12:12:41 -04:00
|
|
|
if (family == AF_INET6) {
|
|
|
|
|
act_source_id = &priv->act_source6_id;
|
|
|
|
|
act_source_func = &priv->act_source6_func;
|
|
|
|
|
} else {
|
|
|
|
|
act_source_id = &priv->act_source_id;
|
|
|
|
|
act_source_func = &priv->act_source_func;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
if (*act_source_id)
|
|
|
|
|
_LOGE (LOGD_DEVICE, "activation stage already scheduled");
|
2009-03-23 17:36:52 -04:00
|
|
|
|
|
|
|
|
/* Don't bother rescheduling the same function that's about to
|
|
|
|
|
* run anyway. Fixes issues with crappy wireless drivers sending
|
|
|
|
|
* streams of associate events before NM has had a chance to process
|
|
|
|
|
* the first one.
|
|
|
|
|
*/
|
2009-07-29 12:12:41 -04:00
|
|
|
if (!*act_source_id || (*act_source_func != func)) {
|
|
|
|
|
activation_source_clear (self, TRUE, family);
|
|
|
|
|
*act_source_id = g_idle_add (func, self);
|
|
|
|
|
*act_source_func = func;
|
2009-03-23 17:36:52 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-03 01:19:54 -07:00
|
|
|
gboolean
|
|
|
|
|
nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingIP4Config *s_ip4;
|
|
|
|
|
NMSettingIP6Config *s_ip6;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (self != NULL, TRUE);
|
|
|
|
|
|
2011-12-05 12:27:49 +01:00
|
|
|
connection = nm_device_get_connection (self);
|
2010-05-03 01:19:54 -07:00
|
|
|
g_assert (connection);
|
|
|
|
|
|
|
|
|
|
/* Fail the connection if the failed IP method is required to complete */
|
|
|
|
|
if (ip6) {
|
2011-10-09 22:50:04 -05:00
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
2013-09-26 17:34:23 -04:00
|
|
|
if (!nm_setting_ip6_config_get_may_fail (s_ip6))
|
2010-05-03 01:19:54 -07:00
|
|
|
return TRUE;
|
|
|
|
|
} else {
|
2011-10-09 22:50:04 -05:00
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
2013-09-26 17:34:23 -04:00
|
|
|
if (!nm_setting_ip4_config_get_may_fail (s_ip4))
|
2010-05-03 01:19:54 -07:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-11 09:21:17 -05:00
|
|
|
static void
|
|
|
|
|
master_ready_cb (NMActiveConnection *active,
|
|
|
|
|
GParamSpec *pspec,
|
|
|
|
|
NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMActiveConnection *master;
|
|
|
|
|
|
|
|
|
|
g_assert (priv->state == NM_DEVICE_STATE_PREPARE);
|
|
|
|
|
|
|
|
|
|
/* Notify a master device that it has a new slave */
|
|
|
|
|
g_assert (nm_active_connection_get_master_ready (active));
|
|
|
|
|
master = nm_active_connection_get_master (active);
|
|
|
|
|
|
|
|
|
|
priv->master = g_object_ref (nm_active_connection_get_device (master));
|
2013-11-07 01:08:02 -06:00
|
|
|
nm_device_master_add_slave (priv->master,
|
|
|
|
|
self,
|
|
|
|
|
nm_active_connection_get_assumed (active) ? FALSE : TRUE);
|
2013-09-11 09:21:17 -05:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "master connection ready; master device %s",
|
|
|
|
|
nm_device_get_iface (priv->master));
|
2013-09-11 09:21:17 -05:00
|
|
|
|
|
|
|
|
if (priv->master_ready_id) {
|
|
|
|
|
g_signal_handler_disconnect (active, priv->master_ready_id);
|
|
|
|
|
priv->master_ready_id = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_device_activate_schedule_stage2_device_config (self);
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-14 00:45:10 -08:00
|
|
|
static NMActStageReturn
|
2012-09-27 12:12:15 -04:00
|
|
|
act_stage1_prepare (NMDevice *self, NMDeviceStateReason *reason)
|
2010-01-14 00:45:10 -08:00
|
|
|
{
|
2013-11-07 01:08:02 -06:00
|
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
2011-10-18 13:48:48 +02:00
|
|
|
}
|
|
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
/*
|
|
|
|
|
* nm_device_activate_stage1_device_prepare
|
|
|
|
|
*
|
|
|
|
|
* Prepare for device activation
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
static gboolean
|
2007-01-04 12:06:26 +00:00
|
|
|
nm_device_activate_stage1_device_prepare (gpointer user_data)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2007-06-11 13:36:34 +00:00
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
2010-01-27 16:20:09 -08:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-11-07 01:08:02 -06:00
|
|
|
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
2008-07-11 10:28:53 +00:00
|
|
|
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
2013-11-07 01:08:02 -06:00
|
|
|
NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-01-04 12:06:26 +00:00
|
|
|
/* Clear the activation source ID now that this stage has run */
|
2009-07-29 12:12:41 -04:00
|
|
|
activation_source_clear (self, FALSE, 0);
|
2006-12-28 22:13:59 +00:00
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
priv->ip4_state = priv->ip6_state = IP_NONE;
|
2010-01-27 16:20:09 -08:00
|
|
|
|
2014-03-20 11:22:19 -05:00
|
|
|
/* Notify the new ActiveConnection along with the state change */
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_ACTIVE_CONNECTION);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: Stage 1 of 5 (Device Prepare) started...");
|
2008-07-11 10:28:53 +00:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2013-11-07 01:08:02 -06:00
|
|
|
/* Assumed connections were already set up outside NetworkManager */
|
|
|
|
|
if (!nm_active_connection_get_assumed (active)) {
|
|
|
|
|
ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, &reason);
|
|
|
|
|
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
|
|
|
|
|
goto out;
|
|
|
|
|
} else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
|
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
|
2006-01-03 17:07:07 +00:00
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2013-11-07 01:08:02 -06:00
|
|
|
if (nm_active_connection_get_master (active)) {
|
|
|
|
|
/* If the master connection is ready for slaves, attach ourselves */
|
|
|
|
|
if (nm_active_connection_get_master_ready (active))
|
|
|
|
|
master_ready_cb (active, NULL, self);
|
|
|
|
|
else {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "waiting for master connection to become ready");
|
2013-11-07 01:08:02 -06:00
|
|
|
|
|
|
|
|
/* Attach a signal handler and wait for the master connection to begin activating */
|
|
|
|
|
g_assert (priv->master_ready_id == 0);
|
|
|
|
|
priv->master_ready_id = g_signal_connect (active,
|
|
|
|
|
"notify::" NM_ACTIVE_CONNECTION_INT_MASTER_READY,
|
|
|
|
|
(GCallback) master_ready_cb,
|
|
|
|
|
self);
|
|
|
|
|
/* Postpone */
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
nm_device_activate_schedule_stage2_device_config (self);
|
2006-01-03 17:07:07 +00:00
|
|
|
|
|
|
|
|
out:
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: Stage 1 of 5 (Device Prepare) complete.");
|
2005-12-31 08:21:24 +00:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* nm_device_activate_schedule_stage1_device_prepare
|
|
|
|
|
*
|
|
|
|
|
* Prepare a device for activation
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void
|
2007-06-11 13:36:34 +00:00
|
|
|
nm_device_activate_schedule_stage1_device_prepare (NMDevice *self)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2007-06-11 13:36:34 +00:00
|
|
|
NMDevicePrivate *priv;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-06-11 13:36:34 +00:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-06-11 13:36:34 +00:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
g_return_if_fail (priv->act_request);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2009-07-29 12:12:41 -04:00
|
|
|
activation_source_schedule (self, nm_device_activate_stage1_device_prepare, 0);
|
2006-12-28 22:13:59 +00:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: Stage 1 of 5 (Device Prepare) scheduled...");
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2006-01-03 17:07:07 +00:00
|
|
|
static NMActStageReturn
|
2014-07-15 13:36:24 +02:00
|
|
|
act_stage2_config (NMDevice *self, NMDeviceStateReason *reason)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
|
|
|
|
/* Nothing to do */
|
2006-01-03 17:07:07 +00:00
|
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
/*
|
|
|
|
|
* nm_device_activate_stage2_device_config
|
|
|
|
|
*
|
|
|
|
|
* Determine device parameters and set those on the device, ie
|
2007-06-27 16:18:52 +00:00
|
|
|
* for wireless devices, set SSID, keys, etc.
|
2005-12-31 08:21:24 +00:00
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
static gboolean
|
2007-01-04 12:06:26 +00:00
|
|
|
nm_device_activate_stage2_device_config (gpointer user_data)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2007-06-11 13:36:34 +00:00
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
2013-11-07 01:08:02 -06:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2007-01-04 12:06:26 +00:00
|
|
|
NMActStageReturn ret;
|
2008-07-11 10:28:53 +00:00
|
|
|
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
2008-08-18 18:29:47 +00:00
|
|
|
gboolean no_firmware = FALSE;
|
2013-11-07 01:08:02 -06:00
|
|
|
NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
|
|
|
|
|
GSList *iter;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-01-04 12:06:26 +00:00
|
|
|
/* Clear the activation source ID now that this stage has run */
|
2009-07-29 12:12:41 -04:00
|
|
|
activation_source_clear (self, FALSE, 0);
|
2006-12-28 22:13:59 +00:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) starting...");
|
2008-07-11 10:28:53 +00:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2013-11-07 01:08:02 -06:00
|
|
|
/* Assumed connections were already set up outside NetworkManager */
|
|
|
|
|
if (!nm_active_connection_get_assumed (active)) {
|
|
|
|
|
if (!nm_device_bring_up (self, FALSE, &no_firmware)) {
|
|
|
|
|
if (no_firmware)
|
|
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_FIRMWARE_MISSING);
|
|
|
|
|
else
|
|
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = NM_DEVICE_GET_CLASS (self)->act_stage2_config (self, &reason);
|
|
|
|
|
if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
|
|
|
|
|
goto out;
|
|
|
|
|
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
|
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
|
2007-03-12 04:49:29 +00:00
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2013-11-07 01:08:02 -06:00
|
|
|
/* If we have slaves that aren't yet enslaved, do that now */
|
|
|
|
|
for (iter = priv->slaves; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
SlaveInfo *info = iter->data;
|
2014-06-05 13:31:46 -04:00
|
|
|
NMDeviceState slave_state = nm_device_get_state (info->slave);
|
2013-11-07 01:08:02 -06:00
|
|
|
|
2014-06-05 13:31:46 -04:00
|
|
|
if (slave_state == NM_DEVICE_STATE_IP_CONFIG)
|
2013-11-07 01:08:02 -06:00
|
|
|
nm_device_enslave_slave (self, info->slave, nm_device_get_connection (info->slave));
|
2014-06-05 13:31:46 -04:00
|
|
|
else if ( nm_device_uses_generated_connection (self)
|
|
|
|
|
&& slave_state <= NM_DEVICE_STATE_DISCONNECTED)
|
|
|
|
|
nm_device_queue_recheck_assume (info->slave);
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) successful.");
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-06-11 13:36:34 +00:00
|
|
|
nm_device_activate_schedule_stage3_ip_config_start (self);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
|
|
|
|
out:
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) complete.");
|
2005-12-31 08:21:24 +00:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* nm_device_activate_schedule_stage2_device_config
|
|
|
|
|
*
|
|
|
|
|
* Schedule setup of the hardware device
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void
|
2007-06-11 13:36:34 +00:00
|
|
|
nm_device_activate_schedule_stage2_device_config (NMDevice *self)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2007-06-11 13:36:34 +00:00
|
|
|
NMDevicePrivate *priv;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-06-11 13:36:34 +00:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-06-11 13:36:34 +00:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
g_return_if_fail (priv->act_request);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2009-07-29 12:12:41 -04:00
|
|
|
activation_source_schedule (self, nm_device_activate_stage2_device_config, 0);
|
2006-12-28 22:13:59 +00:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) scheduled...");
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2011-10-07 11:50:37 -05:00
|
|
|
/*********************************************/
|
|
|
|
|
/* avahi-autoipd stuff */
|
|
|
|
|
|
2008-07-09 14:05:49 +00:00
|
|
|
static void
|
|
|
|
|
aipd_timeout_remove (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->aipd_timeout) {
|
|
|
|
|
g_source_remove (priv->aipd_timeout);
|
|
|
|
|
priv->aipd_timeout = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
aipd_cleanup (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->aipd_watch) {
|
|
|
|
|
g_source_remove (priv->aipd_watch);
|
|
|
|
|
priv->aipd_watch = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-27 19:42:54 +00:00
|
|
|
if (priv->aipd_pid > 0) {
|
2014-02-14 11:58:06 +01:00
|
|
|
nm_utils_kill_child_sync (priv->aipd_pid, SIGKILL, LOGD_AUTOIP4, "avahi-autoipd", NULL, 0, 0);
|
2008-07-27 19:42:54 +00:00
|
|
|
priv->aipd_pid = -1;
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-09 14:05:49 +00:00
|
|
|
aipd_timeout_remove (self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMIP4Config *
|
2013-07-31 23:59:50 +02:00
|
|
|
aipd_get_ip4_config (NMDevice *self, guint32 lla)
|
2008-07-09 14:05:49 +00:00
|
|
|
{
|
|
|
|
|
NMIP4Config *config = NULL;
|
2013-06-29 13:33:36 +02:00
|
|
|
NMPlatformIP4Address address;
|
2013-07-31 23:07:32 +02:00
|
|
|
NMPlatformIP4Route route;
|
2008-07-09 14:05:49 +00:00
|
|
|
|
|
|
|
|
config = nm_ip4_config_new ();
|
2011-10-09 22:50:04 -05:00
|
|
|
g_assert (config);
|
2008-07-11 10:28:53 +00:00
|
|
|
|
2013-06-29 13:33:36 +02:00
|
|
|
memset (&address, 0, sizeof (address));
|
2013-07-31 23:59:50 +02:00
|
|
|
address.address = lla;
|
2013-06-29 13:33:36 +02:00
|
|
|
address.plen = 16;
|
2014-01-06 14:14:14 -06:00
|
|
|
address.source = NM_PLATFORM_SOURCE_IP4LL;
|
2013-06-29 13:33:36 +02:00
|
|
|
nm_ip4_config_add_address (config, &address);
|
2008-07-09 14:05:49 +00:00
|
|
|
|
2010-06-09 15:01:23 +02:00
|
|
|
/* Add a multicast route for link-local connections: destination= 224.0.0.0, netmask=240.0.0.0 */
|
2013-07-31 23:07:32 +02:00
|
|
|
memset (&route, 0, sizeof (route));
|
|
|
|
|
route.network = htonl (0xE0000000L);
|
|
|
|
|
route.plen = 4;
|
2014-01-06 14:14:14 -06:00
|
|
|
route.source = NM_PLATFORM_SOURCE_IP4LL;
|
2014-06-04 11:14:55 -04:00
|
|
|
route.metric = nm_device_get_priority (self);
|
2013-07-31 23:07:32 +02:00
|
|
|
nm_ip4_config_add_route (config, &route);
|
2010-06-09 15:01:23 +02:00
|
|
|
|
2013-07-31 23:07:32 +02:00
|
|
|
return config;
|
2008-07-09 14:05:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define IPV4LL_NETWORK (htonl (0xA9FE0000L))
|
|
|
|
|
#define IPV4LL_NETMASK (htonl (0xFFFF0000L))
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_device_handle_autoip4_event (NMDevice *self,
|
|
|
|
|
const char *event,
|
|
|
|
|
const char *address)
|
|
|
|
|
{
|
2011-10-09 23:48:13 -05:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2008-07-09 14:05:49 +00:00
|
|
|
NMConnection *connection = NULL;
|
2014-02-12 23:54:26 +01:00
|
|
|
const char *method;
|
2013-08-01 10:34:46 -05:00
|
|
|
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
2008-07-09 14:05:49 +00:00
|
|
|
|
|
|
|
|
g_return_if_fail (event != NULL);
|
|
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
if (priv->act_request == NULL)
|
2008-07-09 14:05:49 +00:00
|
|
|
return;
|
|
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
connection = nm_act_request_get_connection (priv->act_request);
|
|
|
|
|
g_assert (connection);
|
2008-07-09 14:05:49 +00:00
|
|
|
|
|
|
|
|
/* Ignore if the connection isn't an AutoIP connection */
|
core: don't have IP4 and IP6 configs on slaves
Although it's convenient in some places to have IP configs on all
connections, it makes more sense in other places to not have IP
configs on slaves. (eg, it's confusing for nmcli, etc, to report a
full NMSettingIP4Config on a slave device). So revert parts of the
earlier patch. However, it's still safe to assume that s_ip4 != NULL
if method != DISABLED, so some of the earlier simplifications can
stay.
Also, add nm_utils_get_ip_config_method(), which returns the correct
IP config method for a connection, whether the connection has IP4 and
IP6 settings objects or not, and use that to keep some more of the
simplifications from the earlier patch.
2013-10-14 10:38:56 -04:00
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
|
|
|
|
if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) != 0)
|
2008-07-09 14:05:49 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (strcmp (event, "BIND") == 0) {
|
2013-07-31 23:59:50 +02:00
|
|
|
guint32 lla;
|
2011-10-09 22:50:04 -05:00
|
|
|
NMIP4Config *config;
|
2008-07-09 14:05:49 +00:00
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
if (inet_pton (AF_INET, address, &lla) <= 0) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGE (LOGD_AUTOIP4, "invalid address %s received from avahi-autoipd.", address);
|
2008-07-11 10:28:53 +00:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_AUTOIP_ERROR);
|
2008-07-09 14:05:49 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-31 23:59:50 +02:00
|
|
|
if ((lla & IPV4LL_NETMASK) != IPV4LL_NETWORK) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGE (LOGD_AUTOIP4, "invalid address %s received from avahi-autoipd (not link-local).", address);
|
2008-07-11 10:28:53 +00:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_AUTOIP_ERROR);
|
2008-07-09 14:05:49 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
config = aipd_get_ip4_config (self, lla);
|
|
|
|
|
if (config == NULL) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGE (LOGD_AUTOIP4, "failed to get autoip config");
|
2011-10-09 22:50:04 -05:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
if (priv->ip4_state == IP_CONF) {
|
2008-07-09 14:05:49 +00:00
|
|
|
aipd_timeout_remove (self);
|
2011-10-09 22:50:04 -05:00
|
|
|
nm_device_activate_schedule_ip4_config_result (self, config);
|
2011-10-09 23:48:13 -05:00
|
|
|
} else if (priv->ip4_state == IP_DONE) {
|
2013-08-01 15:44:53 -05:00
|
|
|
if (!ip4_config_merge_and_apply (self, config, TRUE, &reason)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGE (LOGD_AUTOIP4, "failed to update IP4 config for autoip change.");
|
2013-08-01 10:34:46 -05:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
|
|
|
|
}
|
2011-10-09 23:48:13 -05:00
|
|
|
} else
|
|
|
|
|
g_assert_not_reached ();
|
2011-10-09 22:50:04 -05:00
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
g_object_unref (config);
|
2008-07-09 14:05:49 +00:00
|
|
|
} else {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_AUTOIP4, "autoip address %s no longer valid because '%s'.", address, event);
|
2008-07-09 14:05:49 +00:00
|
|
|
|
|
|
|
|
/* The address is gone; terminate the connection or fail activation */
|
2008-07-11 10:28:53 +00:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
|
2008-07-09 14:05:49 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
aipd_watch_cb (GPid pid, gint status, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMDeviceState state;
|
|
|
|
|
|
|
|
|
|
if (!priv->aipd_watch)
|
|
|
|
|
return;
|
|
|
|
|
priv->aipd_watch = 0;
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
if (WIFEXITED (status))
|
|
|
|
|
_LOGD (LOGD_AUTOIP4, "avahi-autoipd exited with error code %d", WEXITSTATUS (status));
|
|
|
|
|
else if (WIFSTOPPED (status))
|
|
|
|
|
_LOGW (LOGD_AUTOIP4, "avahi-autoipd stopped unexpectedly with signal %d", WSTOPSIG (status));
|
|
|
|
|
else if (WIFSIGNALED (status))
|
|
|
|
|
_LOGW (LOGD_AUTOIP4, "avahi-autoipd died with signal %d", WTERMSIG (status));
|
|
|
|
|
else
|
|
|
|
|
_LOGW (LOGD_AUTOIP4, "avahi-autoipd died from an unknown cause");
|
2008-07-09 14:05:49 +00:00
|
|
|
|
|
|
|
|
aipd_cleanup (self);
|
|
|
|
|
|
|
|
|
|
state = nm_device_get_state (self);
|
|
|
|
|
if (nm_device_is_activating (self) || (state == NM_DEVICE_STATE_ACTIVATED))
|
2008-07-11 10:28:53 +00:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_AUTOIP_FAILED);
|
2008-07-09 14:05:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
aipd_timeout_cb (gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
if (priv->aipd_timeout) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_AUTOIP4, "avahi-autoipd timed out.");
|
2011-10-09 23:48:13 -05:00
|
|
|
priv->aipd_timeout = 0;
|
|
|
|
|
aipd_cleanup (self);
|
2008-07-09 14:05:49 +00:00
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
if (priv->ip4_state == IP_CONF)
|
|
|
|
|
nm_device_activate_schedule_ip4_config_timeout (self);
|
|
|
|
|
}
|
2008-07-09 14:05:49 +00:00
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
aipd_child_setup (gpointer user_data G_GNUC_UNUSED)
|
|
|
|
|
{
|
|
|
|
|
/* We are in the child process at this point.
|
|
|
|
|
* Give child it's own program group for signal
|
|
|
|
|
* separation.
|
|
|
|
|
*/
|
|
|
|
|
pid_t pid = getpid ();
|
|
|
|
|
setpgid (pid, pid);
|
2012-05-21 14:10:05 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* We blocked signals in main(). We need to restore original signal
|
|
|
|
|
* mask for avahi-autoipd here so that it can receive signals.
|
|
|
|
|
*/
|
|
|
|
|
nm_unblock_posix_signals (NULL);
|
2008-07-09 14:05:49 +00:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* default to installed helper, but can be modified for testing */
|
|
|
|
|
const char *nm_device_autoipd_helper_path = LIBEXECDIR "/nm-avahi-autoipd.action";
|
|
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
static NMActStageReturn
|
|
|
|
|
aipd_start (NMDevice *self, NMDeviceStateReason *reason)
|
2008-07-09 14:05:49 +00:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-07-31 14:02:22 -05:00
|
|
|
const char *argv[6];
|
|
|
|
|
char *cmdline;
|
|
|
|
|
const char *aipd_binary;
|
2010-08-08 01:36:35 -05:00
|
|
|
int i = 0;
|
2011-10-09 22:50:04 -05:00
|
|
|
GError *error = NULL;
|
2008-07-09 14:05:49 +00:00
|
|
|
|
|
|
|
|
aipd_cleanup (self);
|
|
|
|
|
|
|
|
|
|
/* Find avahi-autoipd */
|
2014-07-31 14:02:22 -05:00
|
|
|
aipd_binary = nm_utils_find_helper ("avahi-autoipd", NULL, NULL);
|
|
|
|
|
if (!aipd_binary) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE | LOGD_AUTOIP4,
|
|
|
|
|
"Activation: Stage 3 of 5 (IP Configure Start) failed"
|
|
|
|
|
" to start avahi-autoipd: not found");
|
2011-10-09 22:50:04 -05:00
|
|
|
*reason = NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED;
|
|
|
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
2008-07-09 14:05:49 +00:00
|
|
|
}
|
|
|
|
|
|
2014-07-31 14:02:22 -05:00
|
|
|
argv[i++] = aipd_binary;
|
2010-08-08 01:36:35 -05:00
|
|
|
argv[i++] = "--script";
|
2014-07-31 14:02:22 -05:00
|
|
|
argv[i++] = nm_device_autoipd_helper_path;
|
2013-05-22 16:12:23 +02:00
|
|
|
|
2013-10-01 11:08:31 -04:00
|
|
|
if (nm_logging_enabled (LOGL_DEBUG, LOGD_AUTOIP4))
|
2010-08-08 01:36:35 -05:00
|
|
|
argv[i++] = "--debug";
|
2014-07-31 14:02:22 -05:00
|
|
|
argv[i++] = nm_device_get_ip_iface (self);
|
2010-08-08 01:36:35 -05:00
|
|
|
argv[i++] = NULL;
|
|
|
|
|
|
2014-07-31 14:02:22 -05:00
|
|
|
cmdline = g_strjoinv (" ", (char **) argv);
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_AUTOIP4, "running: %s", cmdline);
|
2010-08-08 01:36:35 -05:00
|
|
|
g_free (cmdline);
|
2008-07-09 14:05:49 +00:00
|
|
|
|
2014-07-31 14:02:22 -05:00
|
|
|
if (!g_spawn_async ("/", (char **) argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
|
2011-10-09 22:50:04 -05:00
|
|
|
&aipd_child_setup, NULL, &(priv->aipd_pid), &error)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE | LOGD_AUTOIP4,
|
|
|
|
|
"Activation: Stage 3 of 5 (IP Configure Start) failed"
|
|
|
|
|
" to start avahi-autoipd: %s",
|
|
|
|
|
error && error->message ? error->message : "(unknown)");
|
2011-10-09 22:50:04 -05:00
|
|
|
g_clear_error (&error);
|
|
|
|
|
aipd_cleanup (self);
|
|
|
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | LOGD_AUTOIP4,
|
|
|
|
|
"Activation: Stage 3 of 5 (IP Configure Start) started"
|
|
|
|
|
" avahi-autoipd...");
|
2008-07-09 14:05:49 +00:00
|
|
|
|
|
|
|
|
/* Monitor the child process so we know when it dies */
|
|
|
|
|
priv->aipd_watch = g_child_watch_add (priv->aipd_pid, aipd_watch_cb, self);
|
|
|
|
|
|
|
|
|
|
/* Start a timeout to bound the address attempt */
|
2008-12-31 18:57:36 -05:00
|
|
|
priv->aipd_timeout = g_timeout_add_seconds (20, aipd_timeout_cb, self);
|
2008-07-09 14:05:49 +00:00
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
2008-07-09 14:05:49 +00:00
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2011-10-07 11:50:37 -05:00
|
|
|
/*********************************************/
|
|
|
|
|
/* DHCPv4 stuff */
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static void
|
|
|
|
|
dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->dhcp4_client) {
|
|
|
|
|
/* Stop any ongoing DHCP transaction on this device */
|
|
|
|
|
if (priv->dhcp4_state_sigid) {
|
|
|
|
|
g_signal_handler_disconnect (priv->dhcp4_client, priv->dhcp4_state_sigid);
|
|
|
|
|
priv->dhcp4_state_sigid = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
|
|
|
|
|
|
|
|
|
|
if (stop)
|
|
|
|
|
nm_dhcp_client_stop (priv->dhcp4_client, release);
|
|
|
|
|
|
2014-05-22 13:59:06 -05:00
|
|
|
g_clear_object (&priv->dhcp4_client);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
core: fix dhcp4_cleanup() to clear dhcp4_client first (avoids assert accessing NM_DEVICE_DHCP4_CONFIG)
dhcp4_cleanup() should first clear @dhcp4_client variables before
clearing @dhcp4_config. Otherwise the following assert fails [1] and
the DBUS property NM_DEVICE_DHCP4_CONFIG is set to %NULL.
Analog to dhcp6_cleanup(), dhcp6_client, and NM_DEVICE_DHCP6_CONFIG.
[1] backtrace:
#0 0x0000003370c504e9 in g_logv (log_domain=0x4c148c "unrecognized-specs-changed", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fff4710ed60) at gmessages.c:989
#1 0x0000003370c5063f in g_log (log_domain=log_domain@entry=0x4c144c "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x3370cbc89a "%s: assertion '%s' failed") at gmessages.c:1025
#2 0x0000003370c50679 in g_return_if_fail_warning (log_domain=log_domain@entry=0x4c144c "NetworkManager", pretty_function=pretty_function@entry=0x4c6140 <__PRETTY_FUNCTION__.15969> "nm_dhcp4_config_get_dbus_path",
expression=expression@entry=0x4c60d9 "NM_IS_DHCP4_CONFIG (self)") at gmessages.c:1034
#3 0x000000000046b1d4 in nm_dhcp4_config_get_dbus_path (self=0x0) at nm-dhcp4-config.c:115
#4 0x0000000000434791 in get_property (object=0x9d2320, prop_id=13, value=0x9618a0, pspec=0x9bbc20) at devices/nm-device.c:7539
#5 0x0000003371c18e73 in object_get_property (value=0x9618a0, pspec=<optimized out>, object=0x9d2320) at gobject.c:1303
#6 g_object_get_property (object=0x9d2320, property_name=<optimized out>, value=0x9618a0) at gobject.c:2402
#7 0x000000000048482c in idle_id_reset (data=<optimized out>) at nm-properties-changed-signal.c:123
#8 0x0000003371c13055 in g_cclosure_marshal_VOID__PARAM (closure=0x9618a0, return_value=0xffffffff, n_param_values=0, param_values=0x7fff4710f130, invocation_hint=0x0, marshal_data=0x4b5201) at gmarshal.c:1037
#9 0x0000003371c10298 in g_closure_invoke (closure=0x2, closure@entry=0x919d00, return_value=return_value@entry=0x0, n_param_values=1192292656, param_values=0x9d2320, param_values@entry=0x7fff4710f130,
invocation_hint=invocation_hint@entry=0x7fff4710f0d0) at gclosure.c:777
#10 0x0000003371c21b87 in signal_emit_unlocked_R (node=node@entry=0x919d90, detail=detail@entry=667, instance=instance@entry=0x9d2320, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff4710f130) at gsignal.c:3516
#11 0x0000003371c2a0f2 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fff4710f2c0) at gsignal.c:3330
#12 0x0000003371c2a3af in g_signal_emit (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3386
#13 0x0000003371c14945 in g_object_dispatch_properties_changed (object=0x9d2320, n_pspecs=4294967295, pspecs=0x0) at gobject.c:1047
#14 0x0000003371c17019 in g_object_notify_by_spec_internal (pspec=<optimized out>, object=0x9d2320) at gobject.c:1141
#15 g_object_notify (object=0x9d2320, property_name=property_name@entry=0x4c400f "dhcp4-config") at gobject.c:1183
#16 0x0000000000434332 in dhcp4_cleanup (self=self@entry=0x9d2320, stop=stop@entry=1, release=release@entry=0) at devices/nm-device.c:2581
#17 0x0000000000434cab in _cleanup_generic_pre (self=self@entry=0x9d2320, deconfigure=deconfigure@entry=1) at devices/nm-device.c:6448
#18 0x0000000000436db1 in nm_device_cleanup (self=self@entry=0x9d2320, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:6524
#19 0x0000000000437358 in _set_state_full (device=device@entry=0x9d2320, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:6641
#20 0x000000000043797c in nm_device_state_changed (device=device@entry=0x9d2320, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:6823
#21 0x0000000000439fe7 in nm_device_set_unmanaged (device=device@entry=0x9d2320, flag=flag@entry=NM_UNMANAGED_INTERNAL, unmanaged=unmanaged@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:5983
#22 0x000000000043a193 in nm_device_set_unmanaged_quitting (device=0x9d2320) at devices/nm-device.c:5998
#23 0x00000000004799f9 in remove_device (manager=0x9b2150, device=0x9d2320, quitting=1) at nm-manager.c:775
#24 0x000000000047bf47 in dispose (object=0x9b2150) at nm-manager.c:4935
#25 0x0000003371c14ee8 in g_object_unref (_object=0x9b2150) at gobject.c:3160
#26 0x0000000000429f43 in main (argc=1, argv=0x7fff4710f9a8) at main.c:681
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-23 10:32:32 +02:00
|
|
|
|
|
|
|
|
if (priv->dhcp4_config) {
|
|
|
|
|
g_clear_object (&priv->dhcp4_config);
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP4_CONFIG);
|
|
|
|
|
}
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
static gboolean
|
|
|
|
|
ip4_config_merge_and_apply (NMDevice *self,
|
|
|
|
|
NMIP4Config *config,
|
2013-08-01 15:44:53 -05:00
|
|
|
gboolean commit,
|
2013-08-01 10:34:46 -05:00
|
|
|
NMDeviceStateReason *out_reason)
|
2010-01-12 22:09:28 -08:00
|
|
|
{
|
2013-08-01 10:34:46 -05:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2010-01-12 22:09:28 -08:00
|
|
|
NMConnection *connection;
|
2013-08-01 10:34:46 -05:00
|
|
|
gboolean success;
|
|
|
|
|
NMIP4Config *composite;
|
2010-01-12 22:09:28 -08:00
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
/* Merge all the configs into the composite config */
|
|
|
|
|
if (config) {
|
|
|
|
|
g_clear_object (&priv->dev_ip4_config);
|
|
|
|
|
priv->dev_ip4_config = g_object_ref (config);
|
2011-10-07 12:05:51 -05:00
|
|
|
}
|
2010-01-14 00:45:10 -08:00
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
composite = nm_ip4_config_new ();
|
2013-08-01 15:44:53 -05:00
|
|
|
if (priv->dev_ip4_config)
|
|
|
|
|
nm_ip4_config_merge (composite, priv->dev_ip4_config);
|
2013-08-01 10:59:42 -05:00
|
|
|
if (priv->vpn4_config)
|
|
|
|
|
nm_ip4_config_merge (composite, priv->vpn4_config);
|
2013-08-01 15:44:53 -05:00
|
|
|
if (priv->ext_ip4_config)
|
|
|
|
|
nm_ip4_config_merge (composite, priv->ext_ip4_config);
|
2010-01-14 00:45:10 -08:00
|
|
|
|
2014-07-15 17:16:56 -05:00
|
|
|
/* Merge WWAN config *last* to ensure modem-given settings overwrite
|
|
|
|
|
* any external stuff set by pppd or other scripts.
|
|
|
|
|
*/
|
|
|
|
|
if (priv->wwan_ip4_config)
|
|
|
|
|
nm_ip4_config_merge (composite, priv->wwan_ip4_config);
|
|
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
/* Merge user overrides into the composite config */
|
2013-08-01 15:44:53 -05:00
|
|
|
connection = nm_device_get_connection (self);
|
2014-06-09 09:36:01 -04:00
|
|
|
if (connection) {
|
|
|
|
|
nm_ip4_config_merge_setting (composite,
|
|
|
|
|
nm_connection_get_setting_ip4_config (connection),
|
|
|
|
|
nm_device_get_priority (self));
|
|
|
|
|
}
|
2013-08-01 10:34:46 -05:00
|
|
|
|
|
|
|
|
/* Allow setting MTU etc */
|
2013-08-01 15:44:53 -05:00
|
|
|
if (commit) {
|
|
|
|
|
if (NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit)
|
|
|
|
|
NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, composite);
|
|
|
|
|
}
|
2011-10-09 22:50:04 -05:00
|
|
|
|
2013-08-01 15:44:53 -05:00
|
|
|
success = nm_device_set_ip4_config (self, composite, commit, out_reason);
|
2013-08-01 10:34:46 -05:00
|
|
|
g_object_unref (composite);
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dhcp4_lease_change (NMDevice *self, NMIP4Config *config)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (config != NULL);
|
|
|
|
|
|
2013-08-01 15:44:53 -05:00
|
|
|
if (!ip4_config_merge_and_apply (self, config, TRUE, &reason)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DHCP4, "failed to update IPv4 config for DHCP change.");
|
2013-08-01 10:34:46 -05:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
|
|
|
|
} else {
|
|
|
|
|
/* Notify dispatcher scripts of new DHCP4 config */
|
|
|
|
|
nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE,
|
|
|
|
|
nm_device_get_connection (self),
|
|
|
|
|
self,
|
|
|
|
|
NULL,
|
2014-05-14 21:21:10 -05:00
|
|
|
NULL,
|
2013-08-01 10:34:46 -05:00
|
|
|
NULL);
|
|
|
|
|
}
|
2010-01-12 22:09:28 -08:00
|
|
|
}
|
|
|
|
|
|
2011-10-07 12:23:35 -05:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp4_fail (NMDevice *self, gboolean timeout)
|
2011-10-07 12:23:35 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2011-10-07 12:23:35 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp4_cleanup (self, TRUE, FALSE);
|
2011-10-09 23:48:13 -05:00
|
|
|
if (timeout || (priv->ip4_state == IP_CONF))
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_activate_schedule_ip4_config_timeout (self);
|
2013-07-02 16:42:49 +02:00
|
|
|
else if (priv->ip4_state == IP_FAIL)
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
|
2011-10-07 12:23:35 -05:00
|
|
|
}
|
|
|
|
|
|
2014-07-01 12:30:29 -05:00
|
|
|
static void
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
dhcp4_update_config (NMDevice *self, NMDhcp4Config *config, GHashTable *options)
|
2014-07-01 12:30:29 -05:00
|
|
|
{
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
const char *key, *value;
|
|
|
|
|
|
|
|
|
|
/* Update the DHCP4 config object with new DHCP options */
|
|
|
|
|
nm_dhcp4_config_reset (config);
|
|
|
|
|
|
|
|
|
|
g_hash_table_iter_init (&iter, options);
|
|
|
|
|
while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value))
|
|
|
|
|
nm_dhcp4_config_add_option (config, key, value);
|
|
|
|
|
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP4_CONFIG);
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-12 22:09:28 -08:00
|
|
|
static void
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
dhcp4_state_changed (NMDhcpClient *client,
|
2014-05-15 12:49:11 -05:00
|
|
|
NMDhcpState state,
|
2014-07-01 09:48:58 -05:00
|
|
|
NMIP4Config *ip4_config,
|
2014-07-01 12:30:29 -05:00
|
|
|
GHashTable *options,
|
2011-10-07 12:05:51 -05:00
|
|
|
gpointer user_data)
|
2010-01-12 22:09:28 -08:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2010-01-12 22:09:28 -08:00
|
|
|
|
2011-10-07 12:05:51 -05:00
|
|
|
g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == FALSE);
|
2014-07-01 09:48:58 -05:00
|
|
|
g_return_if_fail (!ip4_config || NM_IS_IP4_CONFIG (ip4_config));
|
2010-01-12 22:09:28 -08:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DHCP4, "new DHCPv4 client state %d", state);
|
2011-10-07 12:05:51 -05:00
|
|
|
|
2010-01-12 22:09:28 -08:00
|
|
|
switch (state) {
|
2014-05-15 12:49:11 -05:00
|
|
|
case NM_DHCP_STATE_BOUND:
|
2014-07-01 09:48:58 -05:00
|
|
|
if (!ip4_config) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DHCP4, "failed to get IPv4 config in response to DHCP event.");
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_state_changed (self,
|
2013-08-01 10:34:46 -05:00
|
|
|
NM_DEVICE_STATE_FAILED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp4_update_config (self, priv->dhcp4_config, options);
|
2014-01-06 16:01:22 -06:00
|
|
|
|
|
|
|
|
if (priv->ip4_state == IP_CONF)
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_activate_schedule_ip4_config_result (self, ip4_config);
|
2014-01-06 16:01:22 -06:00
|
|
|
else if (priv->ip4_state == IP_DONE)
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp4_lease_change (self, ip4_config);
|
2010-01-12 22:09:28 -08:00
|
|
|
break;
|
2014-05-15 12:49:11 -05:00
|
|
|
case NM_DHCP_STATE_TIMEOUT:
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp4_fail (self, TRUE);
|
2010-01-12 22:09:28 -08:00
|
|
|
break;
|
2014-05-15 12:49:11 -05:00
|
|
|
case NM_DHCP_STATE_DONE:
|
|
|
|
|
case NM_DHCP_STATE_FAIL:
|
2010-01-13 17:59:54 -08:00
|
|
|
/* dhclient quit and can't get/renew a lease; so kill the connection */
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp4_fail (self, FALSE);
|
2010-01-12 22:09:28 -08:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-05 14:07:32 -06:00
|
|
|
static NMActStageReturn
|
|
|
|
|
dhcp4_start (NMDevice *self,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
NMDeviceStateReason *reason)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2011-01-05 16:23:00 -06:00
|
|
|
NMSettingIP4Config *s_ip4;
|
2014-04-10 18:02:52 -05:00
|
|
|
const guint8 *hw_addr;
|
|
|
|
|
size_t hw_addr_len = 0;
|
2012-06-13 13:28:55 -05:00
|
|
|
GByteArray *tmp = NULL;
|
2011-01-05 14:07:32 -06:00
|
|
|
|
2011-12-05 12:27:47 +01:00
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
2011-01-05 14:07:32 -06:00
|
|
|
|
|
|
|
|
/* Clear old exported DHCP options */
|
|
|
|
|
if (priv->dhcp4_config)
|
|
|
|
|
g_object_unref (priv->dhcp4_config);
|
|
|
|
|
priv->dhcp4_config = nm_dhcp4_config_new ();
|
|
|
|
|
|
2014-04-10 18:02:52 -05:00
|
|
|
hw_addr = nm_platform_link_get_address (nm_device_get_ip_ifindex (self), &hw_addr_len);
|
|
|
|
|
if (hw_addr_len) {
|
|
|
|
|
tmp = g_byte_array_sized_new (hw_addr_len);
|
|
|
|
|
g_byte_array_append (tmp, hw_addr, hw_addr_len);
|
2012-06-13 13:28:55 -05:00
|
|
|
}
|
|
|
|
|
|
2011-01-05 16:23:00 -06:00
|
|
|
/* Begin DHCP on the interface */
|
2011-01-05 14:07:32 -06:00
|
|
|
g_warn_if_fail (priv->dhcp4_client == NULL);
|
2014-04-02 16:00:35 -05:00
|
|
|
priv->dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (),
|
2011-01-05 14:07:32 -06:00
|
|
|
nm_device_get_ip_iface (self),
|
2014-04-03 13:13:17 -05:00
|
|
|
nm_device_get_ip_ifindex (self),
|
2012-06-13 13:28:55 -05:00
|
|
|
tmp,
|
2011-03-08 13:41:28 +01:00
|
|
|
nm_connection_get_uuid (connection),
|
2014-06-04 11:14:55 -04:00
|
|
|
nm_device_get_priority (self),
|
2014-07-11 12:50:17 -05:00
|
|
|
nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4),
|
|
|
|
|
nm_setting_ip4_config_get_dhcp_hostname (s_ip4),
|
|
|
|
|
nm_setting_ip4_config_get_dhcp_client_id (s_ip4),
|
2011-01-05 14:07:32 -06:00
|
|
|
priv->dhcp_timeout,
|
2014-03-10 16:11:21 +01:00
|
|
|
priv->dhcp_anycast_address);
|
2012-06-13 13:28:55 -05:00
|
|
|
|
|
|
|
|
if (tmp)
|
|
|
|
|
g_byte_array_free (tmp, TRUE);
|
|
|
|
|
|
2011-01-05 14:07:32 -06:00
|
|
|
if (!priv->dhcp4_client) {
|
|
|
|
|
*reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED;
|
|
|
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
priv->dhcp4_state_sigid = g_signal_connect (priv->dhcp4_client,
|
2014-03-11 14:02:24 +01:00
|
|
|
NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
|
2011-10-07 12:05:51 -05:00
|
|
|
G_CALLBACK (dhcp4_state_changed),
|
2011-01-05 14:07:32 -06:00
|
|
|
self);
|
|
|
|
|
|
2014-04-14 17:57:56 +02:00
|
|
|
nm_device_add_pending_action (self, PENDING_ACTION_DHCP4, TRUE);
|
|
|
|
|
|
2011-01-05 14:07:32 -06:00
|
|
|
/* DHCP devices will be notified by the DHCP manager when stuff happens */
|
|
|
|
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-05 16:23:00 -06:00
|
|
|
gboolean
|
|
|
|
|
nm_device_dhcp4_renew (NMDevice *self, gboolean release)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMActStageReturn ret;
|
|
|
|
|
NMDeviceStateReason reason;
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (priv->dhcp4_client != NULL, FALSE);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DHCP4, "DHCPv4 lease renewal requested");
|
2011-09-21 00:30:38 -05:00
|
|
|
|
2011-01-05 16:23:00 -06:00
|
|
|
/* Terminate old DHCP instance and release the old lease */
|
2011-09-21 00:30:38 -05:00
|
|
|
dhcp4_cleanup (self, TRUE, release);
|
2011-01-05 16:23:00 -06:00
|
|
|
|
2011-12-05 12:27:49 +01:00
|
|
|
connection = nm_device_get_connection (self);
|
2011-01-05 16:23:00 -06:00
|
|
|
g_assert (connection);
|
|
|
|
|
|
|
|
|
|
/* Start DHCP again on the interface */
|
|
|
|
|
ret = dhcp4_start (self, connection, &reason);
|
|
|
|
|
|
|
|
|
|
return (ret != NM_ACT_STAGE_RETURN_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-07 11:50:37 -05:00
|
|
|
/*********************************************/
|
|
|
|
|
|
|
|
|
|
static GHashTable *shared_ips = NULL;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
release_shared_ip (gpointer data)
|
|
|
|
|
{
|
|
|
|
|
g_hash_table_remove (shared_ips, data);
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-12 15:25:23 -05:00
|
|
|
static gboolean
|
2014-02-12 23:54:26 +01:00
|
|
|
reserve_shared_ip (NMDevice *self, NMSettingIP4Config *s_ip4, NMPlatformIP4Address *address)
|
2011-10-07 11:50:37 -05:00
|
|
|
{
|
2012-10-12 15:25:23 -05:00
|
|
|
if (G_UNLIKELY (shared_ips == NULL))
|
|
|
|
|
shared_ips = g_hash_table_new (g_direct_hash, g_direct_equal);
|
|
|
|
|
|
|
|
|
|
memset (address, 0, sizeof (*address));
|
2011-10-07 11:50:37 -05:00
|
|
|
|
2012-10-12 15:25:23 -05:00
|
|
|
if (s_ip4 && nm_setting_ip4_config_get_num_addresses (s_ip4)) {
|
|
|
|
|
/* Use the first user-supplied address */
|
|
|
|
|
NMIP4Address *user = nm_setting_ip4_config_get_address (s_ip4, 0);
|
|
|
|
|
|
|
|
|
|
g_assert (user);
|
|
|
|
|
address->address = nm_ip4_address_get_address (user);
|
|
|
|
|
address->plen = nm_ip4_address_get_prefix (user);
|
|
|
|
|
} else {
|
|
|
|
|
/* Find an unused address in the 10.42.x.x range */
|
|
|
|
|
guint32 start = (guint32) ntohl (0x0a2a0001); /* 10.42.0.1 */
|
|
|
|
|
guint32 count = 0;
|
|
|
|
|
|
|
|
|
|
while (g_hash_table_lookup (shared_ips, GUINT_TO_POINTER (start + count))) {
|
|
|
|
|
count += ntohl (0x100);
|
|
|
|
|
if (count > ntohl (0xFE00)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGE (LOGD_SHARING, "ran out of shared IP addresses!");
|
2012-10-12 15:25:23 -05:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
2011-10-07 11:50:37 -05:00
|
|
|
}
|
2012-10-12 15:25:23 -05:00
|
|
|
address->address = start + count;
|
|
|
|
|
address->plen = 24;
|
|
|
|
|
|
|
|
|
|
g_hash_table_insert (shared_ips,
|
|
|
|
|
GUINT_TO_POINTER (address->address),
|
|
|
|
|
GUINT_TO_POINTER (TRUE));
|
2011-10-07 11:50:37 -05:00
|
|
|
}
|
|
|
|
|
|
2012-10-12 15:25:23 -05:00
|
|
|
return TRUE;
|
2011-10-07 11:50:37 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMIP4Config *
|
2012-10-12 15:25:23 -05:00
|
|
|
shared4_new_config (NMDevice *self, NMConnection *connection, NMDeviceStateReason *reason)
|
2011-10-07 11:50:37 -05:00
|
|
|
{
|
|
|
|
|
NMIP4Config *config = NULL;
|
2013-06-29 13:33:36 +02:00
|
|
|
NMPlatformIP4Address address;
|
2011-10-07 11:50:37 -05:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
if (!reserve_shared_ip (self, nm_connection_get_setting_ip4_config (connection), &address)) {
|
2011-10-07 11:50:37 -05:00
|
|
|
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
config = nm_ip4_config_new ();
|
2014-01-06 14:14:14 -06:00
|
|
|
address.source = NM_PLATFORM_SOURCE_SHARED;
|
2013-06-29 13:33:36 +02:00
|
|
|
nm_ip4_config_add_address (config, &address);
|
2011-10-07 11:50:37 -05:00
|
|
|
|
|
|
|
|
/* Remove the address lock when the object gets disposed */
|
|
|
|
|
g_object_set_data_full (G_OBJECT (config), "shared-ip",
|
2012-10-12 15:25:23 -05:00
|
|
|
GUINT_TO_POINTER (address.address),
|
|
|
|
|
release_shared_ip);
|
2011-10-07 11:50:37 -05:00
|
|
|
|
|
|
|
|
return config;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*********************************************/
|
|
|
|
|
|
2013-01-25 11:59:05 -06:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
have_any_ready_slaves (NMDevice *self, const GSList *slaves)
|
2013-01-25 11:59:05 -06:00
|
|
|
{
|
|
|
|
|
const GSList *iter;
|
|
|
|
|
|
|
|
|
|
/* Any enslaved slave is "ready" in the generic case as it's
|
|
|
|
|
* at least >= NM_DEVCIE_STATE_IP_CONFIG and has had Layer 2
|
|
|
|
|
* properties set up.
|
|
|
|
|
*/
|
|
|
|
|
for (iter = slaves; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
if (nm_device_get_enslaved (iter->data))
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
ip4_requires_slaves (NMConnection *connection)
|
|
|
|
|
{
|
core: don't have IP4 and IP6 configs on slaves
Although it's convenient in some places to have IP configs on all
connections, it makes more sense in other places to not have IP
configs on slaves. (eg, it's confusing for nmcli, etc, to report a
full NMSettingIP4Config on a slave device). So revert parts of the
earlier patch. However, it's still safe to assume that s_ip4 != NULL
if method != DISABLED, so some of the earlier simplifications can
stay.
Also, add nm_utils_get_ip_config_method(), which returns the correct
IP config method for a connection, whether the connection has IP4 and
IP6 settings objects or not, and use that to keep some more of the
simplifications from the earlier patch.
2013-10-14 10:38:56 -04:00
|
|
|
const char *method;
|
2013-01-25 11:59:05 -06:00
|
|
|
|
core: don't have IP4 and IP6 configs on slaves
Although it's convenient in some places to have IP configs on all
connections, it makes more sense in other places to not have IP
configs on slaves. (eg, it's confusing for nmcli, etc, to report a
full NMSettingIP4Config on a slave device). So revert parts of the
earlier patch. However, it's still safe to assume that s_ip4 != NULL
if method != DISABLED, so some of the earlier simplifications can
stay.
Also, add nm_utils_get_ip_config_method(), which returns the correct
IP config method for a connection, whether the connection has IP4 and
IP6 settings objects or not, and use that to keep some more of the
simplifications from the earlier patch.
2013-10-14 10:38:56 -04:00
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
2013-09-26 17:34:23 -04:00
|
|
|
return strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0;
|
2013-01-25 11:59:05 -06:00
|
|
|
}
|
|
|
|
|
|
2006-01-03 17:47:38 +00:00
|
|
|
static NMActStageReturn
|
2012-09-27 12:12:15 -04:00
|
|
|
act_stage3_ip4_config_start (NMDevice *self,
|
|
|
|
|
NMIP4Config **out_config,
|
|
|
|
|
NMDeviceStateReason *reason)
|
2007-06-06 13:33:51 +00:00
|
|
|
{
|
2010-04-23 12:56:33 -07:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2009-05-03 00:51:09 -04:00
|
|
|
NMConnection *connection;
|
2011-12-06 17:00:40 -06:00
|
|
|
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
core: don't have IP4 and IP6 configs on slaves
Although it's convenient in some places to have IP configs on all
connections, it makes more sense in other places to not have IP
configs on slaves. (eg, it's confusing for nmcli, etc, to report a
full NMSettingIP4Config on a slave device). So revert parts of the
earlier patch. However, it's still safe to assume that s_ip4 != NULL
if method != DISABLED, so some of the earlier simplifications can
stay.
Also, add nm_utils_get_ip_config_method(), which returns the correct
IP config method for a connection, whether the connection has IP4 and
IP6 settings objects or not, and use that to keep some more of the
simplifications from the earlier patch.
2013-10-14 10:38:56 -04:00
|
|
|
const char *method;
|
2013-01-25 11:59:05 -06:00
|
|
|
GSList *slaves;
|
|
|
|
|
gboolean ready_slaves;
|
2008-07-09 14:05:49 +00:00
|
|
|
|
2008-07-11 10:28:53 +00:00
|
|
|
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
|
|
|
|
|
2013-06-07 15:11:23 -05:00
|
|
|
connection = nm_device_get_connection (self);
|
|
|
|
|
g_assert (connection);
|
|
|
|
|
|
core: don't have IP4 and IP6 configs on slaves
Although it's convenient in some places to have IP configs on all
connections, it makes more sense in other places to not have IP
configs on slaves. (eg, it's confusing for nmcli, etc, to report a
full NMSettingIP4Config on a slave device). So revert parts of the
earlier patch. However, it's still safe to assume that s_ip4 != NULL
if method != DISABLED, so some of the earlier simplifications can
stay.
Also, add nm_utils_get_ip_config_method(), which returns the correct
IP config method for a connection, whether the connection has IP4 and
IP6 settings objects or not, and use that to keep some more of the
simplifications from the earlier patch.
2013-10-14 10:38:56 -04:00
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
|
|
|
|
if (priv->master)
|
|
|
|
|
g_assert_cmpstr (method, ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED);
|
2013-06-07 15:11:23 -05:00
|
|
|
|
2013-09-26 17:34:23 -04:00
|
|
|
if ( strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) != 0
|
2014-05-20 16:39:57 -05:00
|
|
|
&& priv->is_master
|
2014-02-25 18:00:34 -06:00
|
|
|
&& !priv->carrier) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_IP4 | LOGD_DEVICE,
|
|
|
|
|
"IPv4 config waiting until carrier is on");
|
2013-05-07 10:23:44 -04:00
|
|
|
return NM_ACT_STAGE_RETURN_WAIT;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-25 11:59:05 -06:00
|
|
|
if (priv->is_master && ip4_requires_slaves (connection)) {
|
|
|
|
|
/* If the master has no ready slaves, and depends on slaves for
|
|
|
|
|
* a successful IPv4 attempt, then postpone IPv4 addressing.
|
|
|
|
|
*/
|
|
|
|
|
slaves = nm_device_master_get_slaves (self);
|
|
|
|
|
ready_slaves = NM_DEVICE_GET_CLASS (self)->have_any_ready_slaves (self, slaves);
|
|
|
|
|
g_slist_free (slaves);
|
|
|
|
|
|
|
|
|
|
if (ready_slaves == FALSE) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | LOGD_IP4,
|
|
|
|
|
"IPv4 config waiting until slaves are ready");
|
2013-01-25 11:59:05 -06:00
|
|
|
return NM_ACT_STAGE_RETURN_WAIT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
/* Start IPv4 addressing based on the method requested */
|
|
|
|
|
if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0)
|
2011-01-05 16:23:00 -06:00
|
|
|
ret = dhcp4_start (self, connection, reason);
|
2011-10-09 22:50:04 -05:00
|
|
|
else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) == 0)
|
|
|
|
|
ret = aipd_start (self, reason);
|
|
|
|
|
else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0) {
|
|
|
|
|
/* Use only IPv4 config from the connection data */
|
|
|
|
|
*out_config = nm_ip4_config_new ();
|
|
|
|
|
g_assert (*out_config);
|
2011-12-06 17:00:40 -06:00
|
|
|
ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
2011-10-09 22:50:04 -05:00
|
|
|
} else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) {
|
2012-10-12 15:25:23 -05:00
|
|
|
*out_config = shared4_new_config (self, connection, reason);
|
2011-12-06 17:00:40 -06:00
|
|
|
if (*out_config) {
|
2011-10-09 22:50:04 -05:00
|
|
|
priv->dnsmasq_manager = nm_dnsmasq_manager_new (nm_device_get_ip_iface (self));
|
2011-12-06 17:00:40 -06:00
|
|
|
ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
|
|
|
|
} else
|
2008-07-09 14:05:49 +00:00
|
|
|
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
2013-05-07 13:08:33 -05:00
|
|
|
} else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) {
|
2010-04-23 12:56:33 -07:00
|
|
|
/* Nothing to do... */
|
|
|
|
|
ret = NM_ACT_STAGE_RETURN_STOP;
|
2014-02-12 23:54:26 +01:00
|
|
|
} else
|
|
|
|
|
_LOGW (LOGD_IP4, "unhandled IPv4 config method '%s'; will fail", method);
|
2007-02-05 09:50:11 +00:00
|
|
|
|
2006-01-03 17:47:38 +00:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-07 11:53:09 -05:00
|
|
|
/*********************************************/
|
|
|
|
|
/* DHCPv6 stuff */
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static void
|
|
|
|
|
dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE;
|
2014-05-22 13:59:06 -05:00
|
|
|
g_clear_object (&priv->dhcp6_ip6_config);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
if (priv->dhcp6_client) {
|
|
|
|
|
if (priv->dhcp6_state_sigid) {
|
|
|
|
|
g_signal_handler_disconnect (priv->dhcp6_client, priv->dhcp6_state_sigid);
|
|
|
|
|
priv->dhcp6_state_sigid = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
|
|
|
|
|
|
|
|
|
|
if (stop)
|
|
|
|
|
nm_dhcp_client_stop (priv->dhcp6_client, release);
|
|
|
|
|
|
2014-05-22 13:59:06 -05:00
|
|
|
g_clear_object (&priv->dhcp6_client);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
core: fix dhcp4_cleanup() to clear dhcp4_client first (avoids assert accessing NM_DEVICE_DHCP4_CONFIG)
dhcp4_cleanup() should first clear @dhcp4_client variables before
clearing @dhcp4_config. Otherwise the following assert fails [1] and
the DBUS property NM_DEVICE_DHCP4_CONFIG is set to %NULL.
Analog to dhcp6_cleanup(), dhcp6_client, and NM_DEVICE_DHCP6_CONFIG.
[1] backtrace:
#0 0x0000003370c504e9 in g_logv (log_domain=0x4c148c "unrecognized-specs-changed", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fff4710ed60) at gmessages.c:989
#1 0x0000003370c5063f in g_log (log_domain=log_domain@entry=0x4c144c "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x3370cbc89a "%s: assertion '%s' failed") at gmessages.c:1025
#2 0x0000003370c50679 in g_return_if_fail_warning (log_domain=log_domain@entry=0x4c144c "NetworkManager", pretty_function=pretty_function@entry=0x4c6140 <__PRETTY_FUNCTION__.15969> "nm_dhcp4_config_get_dbus_path",
expression=expression@entry=0x4c60d9 "NM_IS_DHCP4_CONFIG (self)") at gmessages.c:1034
#3 0x000000000046b1d4 in nm_dhcp4_config_get_dbus_path (self=0x0) at nm-dhcp4-config.c:115
#4 0x0000000000434791 in get_property (object=0x9d2320, prop_id=13, value=0x9618a0, pspec=0x9bbc20) at devices/nm-device.c:7539
#5 0x0000003371c18e73 in object_get_property (value=0x9618a0, pspec=<optimized out>, object=0x9d2320) at gobject.c:1303
#6 g_object_get_property (object=0x9d2320, property_name=<optimized out>, value=0x9618a0) at gobject.c:2402
#7 0x000000000048482c in idle_id_reset (data=<optimized out>) at nm-properties-changed-signal.c:123
#8 0x0000003371c13055 in g_cclosure_marshal_VOID__PARAM (closure=0x9618a0, return_value=0xffffffff, n_param_values=0, param_values=0x7fff4710f130, invocation_hint=0x0, marshal_data=0x4b5201) at gmarshal.c:1037
#9 0x0000003371c10298 in g_closure_invoke (closure=0x2, closure@entry=0x919d00, return_value=return_value@entry=0x0, n_param_values=1192292656, param_values=0x9d2320, param_values@entry=0x7fff4710f130,
invocation_hint=invocation_hint@entry=0x7fff4710f0d0) at gclosure.c:777
#10 0x0000003371c21b87 in signal_emit_unlocked_R (node=node@entry=0x919d90, detail=detail@entry=667, instance=instance@entry=0x9d2320, emission_return=emission_return@entry=0x0,
instance_and_params=instance_and_params@entry=0x7fff4710f130) at gsignal.c:3516
#11 0x0000003371c2a0f2 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fff4710f2c0) at gsignal.c:3330
#12 0x0000003371c2a3af in g_signal_emit (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3386
#13 0x0000003371c14945 in g_object_dispatch_properties_changed (object=0x9d2320, n_pspecs=4294967295, pspecs=0x0) at gobject.c:1047
#14 0x0000003371c17019 in g_object_notify_by_spec_internal (pspec=<optimized out>, object=0x9d2320) at gobject.c:1141
#15 g_object_notify (object=0x9d2320, property_name=property_name@entry=0x4c400f "dhcp4-config") at gobject.c:1183
#16 0x0000000000434332 in dhcp4_cleanup (self=self@entry=0x9d2320, stop=stop@entry=1, release=release@entry=0) at devices/nm-device.c:2581
#17 0x0000000000434cab in _cleanup_generic_pre (self=self@entry=0x9d2320, deconfigure=deconfigure@entry=1) at devices/nm-device.c:6448
#18 0x0000000000436db1 in nm_device_cleanup (self=self@entry=0x9d2320, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:6524
#19 0x0000000000437358 in _set_state_full (device=device@entry=0x9d2320, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:6641
#20 0x000000000043797c in nm_device_state_changed (device=device@entry=0x9d2320, state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:6823
#21 0x0000000000439fe7 in nm_device_set_unmanaged (device=device@entry=0x9d2320, flag=flag@entry=NM_UNMANAGED_INTERNAL, unmanaged=unmanaged@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_REMOVED) at devices/nm-device.c:5983
#22 0x000000000043a193 in nm_device_set_unmanaged_quitting (device=0x9d2320) at devices/nm-device.c:5998
#23 0x00000000004799f9 in remove_device (manager=0x9b2150, device=0x9d2320, quitting=1) at nm-manager.c:775
#24 0x000000000047bf47 in dispose (object=0x9b2150) at nm-manager.c:4935
#25 0x0000003371c14ee8 in g_object_unref (_object=0x9b2150) at gobject.c:3160
#26 0x0000000000429f43 in main (argc=1, argv=0x7fff4710f9a8) at main.c:681
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-23 10:32:32 +02:00
|
|
|
|
|
|
|
|
if (priv->dhcp6_config) {
|
|
|
|
|
g_clear_object (&priv->dhcp6_config);
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG);
|
|
|
|
|
}
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
|
2011-10-21 14:25:35 -05:00
|
|
|
static gboolean
|
|
|
|
|
ip6_config_merge_and_apply (NMDevice *self,
|
2013-08-15 12:55:56 -05:00
|
|
|
gboolean commit,
|
2011-10-21 14:25:35 -05:00
|
|
|
NMDeviceStateReason *out_reason)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMConnection *connection;
|
2012-05-24 15:37:40 +02:00
|
|
|
gboolean success;
|
2011-10-21 14:25:35 -05:00
|
|
|
NMIP6Config *composite;
|
|
|
|
|
|
|
|
|
|
/* If no config was passed in, create a new one */
|
|
|
|
|
composite = nm_ip6_config_new ();
|
|
|
|
|
g_assert (composite);
|
|
|
|
|
|
2013-08-01 10:59:42 -05:00
|
|
|
/* Merge all the IP configs into the composite config */
|
2013-06-14 21:42:22 +02:00
|
|
|
if (priv->ac_ip6_config)
|
2013-07-04 13:34:44 +02:00
|
|
|
nm_ip6_config_merge (composite, priv->ac_ip6_config);
|
2013-06-14 21:42:22 +02:00
|
|
|
if (priv->dhcp6_ip6_config)
|
2013-07-04 13:34:44 +02:00
|
|
|
nm_ip6_config_merge (composite, priv->dhcp6_ip6_config);
|
2013-08-01 10:59:42 -05:00
|
|
|
if (priv->vpn6_config)
|
|
|
|
|
nm_ip6_config_merge (composite, priv->vpn6_config);
|
2013-08-15 12:55:56 -05:00
|
|
|
if (priv->ext_ip6_config)
|
|
|
|
|
nm_ip6_config_merge (composite, priv->ext_ip6_config);
|
2011-10-21 14:25:35 -05:00
|
|
|
|
2013-10-15 21:03:42 -05:00
|
|
|
/* Merge WWAN config *last* to ensure modem-given settings overwrite
|
|
|
|
|
* any external stuff set by pppd or other scripts.
|
|
|
|
|
*/
|
|
|
|
|
if (priv->wwan_ip6_config)
|
|
|
|
|
nm_ip6_config_merge (composite, priv->wwan_ip6_config);
|
|
|
|
|
|
2011-10-21 14:25:35 -05:00
|
|
|
/* Merge user overrides into the composite config */
|
2013-08-15 12:55:56 -05:00
|
|
|
connection = nm_device_get_connection (self);
|
2014-06-09 09:36:01 -04:00
|
|
|
if (connection) {
|
|
|
|
|
nm_ip6_config_merge_setting (composite,
|
|
|
|
|
nm_connection_get_setting_ip6_config (connection),
|
|
|
|
|
nm_device_get_priority (self));
|
|
|
|
|
}
|
2011-10-21 14:25:35 -05:00
|
|
|
|
2014-03-14 14:08:51 +01:00
|
|
|
nm_ip6_config_addresses_sort (composite,
|
|
|
|
|
priv->rdisc ? priv->rdisc_use_tempaddr : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
|
|
|
|
|
|
2014-08-13 14:24:45 -05:00
|
|
|
/* Allow setting MTU etc */
|
|
|
|
|
if (commit) {
|
|
|
|
|
if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit)
|
|
|
|
|
NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self, composite);
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-15 12:55:56 -05:00
|
|
|
success = nm_device_set_ip6_config (self, composite, commit, out_reason);
|
2011-10-21 14:25:35 -05:00
|
|
|
g_object_unref (composite);
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp6_lease_change (NMDevice *self)
|
2011-10-07 12:06:26 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2011-10-07 12:06:26 -05:00
|
|
|
NMConnection *connection;
|
2011-10-09 22:50:04 -05:00
|
|
|
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
2011-10-07 12:06:26 -05:00
|
|
|
|
2011-10-21 14:25:35 -05:00
|
|
|
if (priv->dhcp6_ip6_config == NULL) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DHCP6, "failed to get DHCPv6 config for rebind");
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
|
2011-10-09 22:50:04 -05:00
|
|
|
return;
|
2011-10-07 12:06:26 -05:00
|
|
|
}
|
|
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
g_assert (priv->dhcp6_client); /* sanity check */
|
2011-10-07 12:05:51 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
connection = nm_device_get_connection (self);
|
2011-10-07 12:05:51 -05:00
|
|
|
g_assert (connection);
|
|
|
|
|
|
2011-10-21 14:25:35 -05:00
|
|
|
/* Apply the updated config */
|
2014-07-15 13:36:24 +02:00
|
|
|
if (ip6_config_merge_and_apply (self, TRUE, &reason) == FALSE) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event.");
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
2011-10-21 14:25:35 -05:00
|
|
|
} else {
|
|
|
|
|
/* Notify dispatcher scripts of new DHCPv6 config */
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE, connection, self, NULL, NULL, NULL);
|
2011-10-07 12:05:51 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-07 12:23:35 -05:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp6_fail (NMDevice *self, gboolean timeout)
|
2011-10-07 12:23:35 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2011-10-07 12:23:35 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp6_cleanup (self, TRUE, FALSE);
|
2014-07-23 14:03:42 -05:00
|
|
|
|
|
|
|
|
if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) {
|
|
|
|
|
if (timeout || (priv->ip6_state == IP_CONF))
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_activate_schedule_ip6_config_timeout (self);
|
2014-07-23 14:03:42 -05:00
|
|
|
else if (priv->ip6_state == IP_FAIL)
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
|
2014-07-23 14:03:42 -05:00
|
|
|
} else {
|
|
|
|
|
/* not a hard failure; just live with the RA info */
|
|
|
|
|
if (priv->ip6_state == IP_CONF)
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_activate_schedule_ip6_config_result (self);
|
2014-07-23 14:03:42 -05:00
|
|
|
}
|
2011-10-07 12:23:35 -05:00
|
|
|
}
|
|
|
|
|
|
2014-05-15 14:11:48 -05:00
|
|
|
static void
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
dhcp6_timeout (NMDevice *self, NMDhcpClient *client)
|
2014-05-15 14:11:48 -05:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED)
|
|
|
|
|
dhcp6_fail (self, TRUE);
|
|
|
|
|
else {
|
|
|
|
|
/* not a hard failure; just live with the RA info */
|
2014-05-30 17:09:10 -05:00
|
|
|
dhcp6_cleanup (self, TRUE, FALSE);
|
2014-05-15 14:11:48 -05:00
|
|
|
if (priv->ip6_state == IP_CONF)
|
|
|
|
|
nm_device_activate_schedule_ip6_config_result (self);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-01 12:30:29 -05:00
|
|
|
static void
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
dhcp6_update_config (NMDevice *self, NMDhcp6Config *config, GHashTable *options)
|
2014-07-01 12:30:29 -05:00
|
|
|
{
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
const char *key, *value;
|
|
|
|
|
|
|
|
|
|
/* Update the DHCP6 config object with new DHCP options */
|
|
|
|
|
nm_dhcp6_config_reset (config);
|
|
|
|
|
|
|
|
|
|
g_hash_table_iter_init (&iter, options);
|
|
|
|
|
while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value))
|
|
|
|
|
nm_dhcp6_config_add_option (config, key, value);
|
|
|
|
|
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG);
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-07 12:05:51 -05:00
|
|
|
static void
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
dhcp6_state_changed (NMDhcpClient *client,
|
2014-05-15 12:49:11 -05:00
|
|
|
NMDhcpState state,
|
2014-07-01 09:48:58 -05:00
|
|
|
NMIP6Config *ip6_config,
|
2014-07-01 12:30:29 -05:00
|
|
|
GHashTable *options,
|
2011-10-07 12:05:51 -05:00
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2011-10-07 12:05:51 -05:00
|
|
|
|
|
|
|
|
g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == TRUE);
|
2014-07-01 09:48:58 -05:00
|
|
|
g_return_if_fail (!ip6_config || NM_IS_IP6_CONFIG (ip6_config));
|
2011-10-07 12:05:51 -05:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DHCP6, "new DHCPv6 client state %d", state);
|
2011-10-07 12:05:51 -05:00
|
|
|
|
|
|
|
|
switch (state) {
|
2014-05-15 12:49:11 -05:00
|
|
|
case NM_DHCP_STATE_BOUND:
|
2014-01-06 16:06:49 -06:00
|
|
|
g_clear_object (&priv->dhcp6_ip6_config);
|
2014-07-01 09:48:58 -05:00
|
|
|
if (ip6_config) {
|
|
|
|
|
priv->dhcp6_ip6_config = g_object_ref (ip6_config);
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp6_update_config (self, priv->dhcp6_config, options);
|
2014-01-06 16:06:49 -06:00
|
|
|
}
|
|
|
|
|
|
2013-06-14 21:42:22 +02:00
|
|
|
if (priv->ip6_state == IP_CONF) {
|
|
|
|
|
if (priv->dhcp6_ip6_config == NULL) {
|
|
|
|
|
/* FIXME: Initial DHCP failed; should we fail IPv6 entirely then? */
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED);
|
2013-06-14 21:42:22 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_activate_schedule_ip6_config_result (self);
|
2013-06-14 21:42:22 +02:00
|
|
|
} else if (priv->ip6_state == IP_DONE)
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp6_lease_change (self);
|
2011-10-07 12:05:51 -05:00
|
|
|
break;
|
2014-05-15 12:49:11 -05:00
|
|
|
case NM_DHCP_STATE_TIMEOUT:
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp6_timeout (self, client);
|
2011-10-07 12:05:51 -05:00
|
|
|
break;
|
2014-05-15 12:49:11 -05:00
|
|
|
case NM_DHCP_STATE_DONE:
|
2011-10-07 12:05:51 -05:00
|
|
|
/* In IPv6 info-only mode, the client doesn't handle leases so it
|
|
|
|
|
* may exit right after getting a response from the server. That's
|
|
|
|
|
* normal. In that case we just ignore the exit.
|
|
|
|
|
*/
|
2013-05-30 16:53:23 +02:00
|
|
|
if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF)
|
2011-10-07 12:05:51 -05:00
|
|
|
break;
|
|
|
|
|
/* Otherwise, fall through */
|
2014-05-15 12:49:11 -05:00
|
|
|
case NM_DHCP_STATE_FAIL:
|
2011-10-07 12:05:51 -05:00
|
|
|
/* dhclient quit and can't get/renew a lease; so kill the connection */
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp6_fail (self, FALSE);
|
2011-10-07 12:05:51 -05:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-27 16:20:09 -08:00
|
|
|
static NMActStageReturn
|
|
|
|
|
dhcp6_start (NMDevice *self,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
guint32 dhcp_opt,
|
|
|
|
|
NMDeviceStateReason *reason)
|
|
|
|
|
{
|
2014-04-14 17:57:56 +02:00
|
|
|
NMSettingIP6Config *s_ip6;
|
2010-01-27 16:20:09 -08:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
2012-06-13 13:28:55 -05:00
|
|
|
GByteArray *tmp = NULL;
|
2014-04-10 18:02:52 -05:00
|
|
|
const guint8 *hw_addr;
|
|
|
|
|
size_t hw_addr_len = 0;
|
2010-01-27 16:20:09 -08:00
|
|
|
|
|
|
|
|
if (!connection) {
|
2011-12-05 12:27:49 +01:00
|
|
|
connection = nm_device_get_connection (self);
|
2010-01-27 16:20:09 -08:00
|
|
|
g_assert (connection);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-11 12:50:17 -05:00
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
|
|
|
|
g_assert (s_ip6);
|
2010-01-27 16:20:09 -08:00
|
|
|
|
|
|
|
|
/* Clear old exported DHCP options */
|
|
|
|
|
if (priv->dhcp6_config)
|
|
|
|
|
g_object_unref (priv->dhcp6_config);
|
|
|
|
|
priv->dhcp6_config = nm_dhcp6_config_new ();
|
|
|
|
|
|
2011-10-21 14:25:35 -05:00
|
|
|
g_warn_if_fail (priv->dhcp6_ip6_config == NULL);
|
|
|
|
|
if (priv->dhcp6_ip6_config) {
|
|
|
|
|
g_object_unref (priv->dhcp6_ip6_config);
|
|
|
|
|
priv->dhcp6_ip6_config = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-10 18:02:52 -05:00
|
|
|
hw_addr = nm_platform_link_get_address (nm_device_get_ip_ifindex (self), &hw_addr_len);
|
|
|
|
|
if (hw_addr_len) {
|
|
|
|
|
tmp = g_byte_array_sized_new (hw_addr_len);
|
|
|
|
|
g_byte_array_append (tmp, hw_addr, hw_addr_len);
|
2012-06-13 13:28:55 -05:00
|
|
|
}
|
|
|
|
|
|
2014-04-02 16:00:35 -05:00
|
|
|
priv->dhcp6_client = nm_dhcp_manager_start_ip6 (nm_dhcp_manager_get (),
|
2012-06-13 13:28:55 -05:00
|
|
|
nm_device_get_ip_iface (self),
|
2014-04-03 13:13:17 -05:00
|
|
|
nm_device_get_ip_ifindex (self),
|
2012-06-13 13:28:55 -05:00
|
|
|
tmp,
|
2011-03-08 13:41:28 +01:00
|
|
|
nm_connection_get_uuid (connection),
|
2014-06-04 11:14:55 -04:00
|
|
|
nm_device_get_priority (self),
|
2014-07-11 12:50:17 -05:00
|
|
|
nm_setting_ip6_config_get_dhcp_hostname (s_ip6),
|
2010-01-27 16:20:09 -08:00
|
|
|
priv->dhcp_timeout,
|
2014-03-10 16:11:21 +01:00
|
|
|
priv->dhcp_anycast_address,
|
2014-07-08 11:37:38 -05:00
|
|
|
(dhcp_opt == NM_RDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE,
|
|
|
|
|
nm_setting_ip6_config_get_ip6_privacy (s_ip6));
|
2012-06-13 13:28:55 -05:00
|
|
|
if (tmp)
|
|
|
|
|
g_byte_array_free (tmp, TRUE);
|
|
|
|
|
|
2010-01-27 16:20:09 -08:00
|
|
|
if (priv->dhcp6_client) {
|
|
|
|
|
priv->dhcp6_state_sigid = g_signal_connect (priv->dhcp6_client,
|
2014-03-11 14:02:24 +01:00
|
|
|
NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
|
2011-10-07 12:05:51 -05:00
|
|
|
G_CALLBACK (dhcp6_state_changed),
|
2010-01-27 16:20:09 -08:00
|
|
|
self);
|
|
|
|
|
|
2014-04-14 17:57:56 +02:00
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
|
|
|
|
if (!nm_setting_ip6_config_get_may_fail (s_ip6) ||
|
|
|
|
|
!strcmp (nm_setting_ip6_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_DHCP))
|
|
|
|
|
nm_device_add_pending_action (self, PENDING_ACTION_DHCP6, TRUE);
|
|
|
|
|
|
2010-01-27 16:20:09 -08:00
|
|
|
/* DHCP devices will be notified by the DHCP manager when stuff happens */
|
|
|
|
|
ret = NM_ACT_STAGE_RETURN_POSTPONE;
|
|
|
|
|
} else {
|
|
|
|
|
*reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED;
|
|
|
|
|
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-28 21:25:34 +01:00
|
|
|
gboolean
|
|
|
|
|
nm_device_dhcp6_renew (NMDevice *self, gboolean release)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMActStageReturn ret;
|
|
|
|
|
NMDeviceStateReason reason;
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (priv->dhcp6_client != NULL, FALSE);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DHCP6, "DHCPv6 lease renewal requested");
|
2014-01-28 21:25:34 +01:00
|
|
|
|
|
|
|
|
/* Terminate old DHCP instance and release the old lease */
|
|
|
|
|
dhcp6_cleanup (self, TRUE, release);
|
|
|
|
|
|
|
|
|
|
connection = nm_device_get_connection (self);
|
|
|
|
|
g_assert (connection);
|
|
|
|
|
|
|
|
|
|
/* Start DHCP again on the interface */
|
|
|
|
|
ret = dhcp6_start (self, connection, priv->dhcp6_mode, &reason);
|
|
|
|
|
|
|
|
|
|
return (ret != NM_ACT_STAGE_RETURN_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-07 11:53:09 -05:00
|
|
|
/******************************************/
|
|
|
|
|
|
2013-11-07 22:59:43 +01:00
|
|
|
static gboolean
|
2014-08-13 14:44:22 -05:00
|
|
|
have_ip6_address (const NMIP6Config *ip6_config, gboolean linklocal)
|
2013-11-07 22:59:43 +01:00
|
|
|
{
|
2014-08-13 14:44:22 -05:00
|
|
|
guint i;
|
2013-11-07 22:59:43 +01:00
|
|
|
|
|
|
|
|
if (!ip6_config)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < nm_ip6_config_get_num_addresses (ip6_config); i++) {
|
|
|
|
|
const NMPlatformIP6Address *addr = nm_ip6_config_get_address (ip6_config, i);
|
|
|
|
|
|
2014-08-13 14:44:22 -05:00
|
|
|
if ((IN6_IS_ADDR_LINKLOCAL (&addr->address) == linklocal) &&
|
2013-11-07 22:59:43 +01:00
|
|
|
!(addr->flags & IFA_F_TENTATIVE))
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
linklocal6_cleanup (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->linklocal6_timeout_id) {
|
|
|
|
|
g_source_remove (priv->linklocal6_timeout_id);
|
|
|
|
|
priv->linklocal6_timeout_id = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
linklocal6_timeout_cb (gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *self = user_data;
|
|
|
|
|
|
|
|
|
|
linklocal6_cleanup (self);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses failed due to timeout");
|
2013-11-07 22:59:43 +01:00
|
|
|
|
|
|
|
|
nm_device_activate_schedule_ip6_config_timeout (self);
|
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
linklocal6_complete (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
const char *method;
|
|
|
|
|
|
|
|
|
|
g_assert (priv->linklocal6_timeout_id);
|
2014-08-13 14:44:22 -05:00
|
|
|
g_assert (have_ip6_address (priv->ip6_config, TRUE));
|
2013-11-07 22:59:43 +01:00
|
|
|
|
|
|
|
|
linklocal6_cleanup (self);
|
|
|
|
|
|
|
|
|
|
connection = nm_device_get_connection (self);
|
|
|
|
|
g_assert (connection);
|
|
|
|
|
|
|
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses successful, continue with method %s", method);
|
2013-11-07 22:59:43 +01:00
|
|
|
|
2014-07-22 16:24:07 -05:00
|
|
|
if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
|
|
|
|
|
if (!addrconf6_start_with_link_ready (self)) {
|
|
|
|
|
/* Time out IPv6 instead of failing the entire activation */
|
|
|
|
|
nm_device_activate_schedule_ip6_config_timeout (self);
|
|
|
|
|
}
|
|
|
|
|
} else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0)
|
2013-11-07 22:59:43 +01:00
|
|
|
nm_device_activate_schedule_ip6_config_result (self);
|
|
|
|
|
else
|
|
|
|
|
g_return_if_fail (FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-24 17:14:30 -05:00
|
|
|
static void
|
|
|
|
|
check_and_add_ipv6ll_addr (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
int ip_ifindex = nm_device_get_ip_ifindex (self);
|
|
|
|
|
NMUtilsIPv6IfaceId iid;
|
|
|
|
|
struct in6_addr lladdr;
|
|
|
|
|
guint i, n;
|
|
|
|
|
|
|
|
|
|
if (priv->nm_ipv6ll == FALSE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (priv->ip6_config) {
|
|
|
|
|
n = nm_ip6_config_get_num_addresses (priv->ip6_config);
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
|
const NMPlatformIP6Address *addr;
|
|
|
|
|
|
|
|
|
|
addr = nm_ip6_config_get_address (priv->ip6_config, i);
|
|
|
|
|
if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) {
|
|
|
|
|
/* Already have an LL address, nothing to do */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!nm_device_get_ip_iface_identifier (self, &iid)) {
|
|
|
|
|
_LOGW (LOGD_IP6, "failed to get interface identifier; IPv6 may be broken");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset (&lladdr, 0, sizeof (lladdr));
|
|
|
|
|
lladdr.s6_addr16[0] = htons (0xfe80);
|
|
|
|
|
nm_utils_ipv6_addr_set_interface_identfier (&lladdr, iid);
|
|
|
|
|
_LOGD (LOGD_IP6, "adding IPv6LL address %s", nm_utils_inet6_ntop (&lladdr, NULL));
|
|
|
|
|
if (!nm_platform_ip6_address_add (ip_ifindex,
|
|
|
|
|
lladdr,
|
|
|
|
|
in6addr_any,
|
|
|
|
|
64,
|
|
|
|
|
NM_PLATFORM_LIFETIME_PERMANENT,
|
|
|
|
|
NM_PLATFORM_LIFETIME_PERMANENT,
|
|
|
|
|
0)) {
|
|
|
|
|
_LOGW (LOGD_IP6, "failed to add IPv6 link-local address %s",
|
|
|
|
|
nm_utils_inet6_ntop (&lladdr, NULL));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-07 22:59:43 +01:00
|
|
|
static NMActStageReturn
|
|
|
|
|
linklocal6_start (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
const char *method;
|
|
|
|
|
|
|
|
|
|
linklocal6_cleanup (self);
|
|
|
|
|
|
2014-08-13 14:44:22 -05:00
|
|
|
if (have_ip6_address (priv->ip6_config, TRUE))
|
2013-11-07 22:59:43 +01:00
|
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
|
|
|
|
|
|
|
|
|
connection = nm_device_get_connection (self);
|
|
|
|
|
g_assert (connection);
|
|
|
|
|
|
|
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "linklocal6: starting IPv6 with method '%s', but the device has no link-local addresses configured. Wait.", method);
|
2013-11-07 22:59:43 +01:00
|
|
|
|
2014-07-24 17:14:30 -05:00
|
|
|
check_and_add_ipv6ll_addr (self);
|
|
|
|
|
|
2013-11-07 22:59:43 +01:00
|
|
|
priv->linklocal6_timeout_id = g_timeout_add_seconds (5, linklocal6_timeout_cb, self);
|
|
|
|
|
|
|
|
|
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************/
|
|
|
|
|
|
2014-01-03 17:03:35 +01:00
|
|
|
static void
|
|
|
|
|
print_support_extended_ifa_flags (NMSettingIP6ConfigPrivacy use_tempaddr)
|
|
|
|
|
{
|
|
|
|
|
static gint8 warn = 0;
|
|
|
|
|
static gint8 s_libnl = -1, s_kernel;
|
|
|
|
|
|
|
|
|
|
if (warn >= 2)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (s_libnl == -1) {
|
|
|
|
|
s_libnl = !!nm_platform_check_support_libnl_extended_ifa_flags ();
|
|
|
|
|
s_kernel = !!nm_platform_check_support_kernel_extended_ifa_flags ();
|
|
|
|
|
|
|
|
|
|
if (s_libnl && s_kernel) {
|
|
|
|
|
nm_log_dbg (LOGD_IP6, "kernel and libnl support extended IFA_FLAGS (needed by NM for IPv6 private addresses)");
|
|
|
|
|
warn = 2;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( use_tempaddr != NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR
|
|
|
|
|
&& use_tempaddr != NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) {
|
|
|
|
|
if (warn == 0) {
|
|
|
|
|
nm_log_dbg (LOGD_IP6, "%s%s%s %s not support extended IFA_FLAGS (needed by NM for IPv6 private addresses)",
|
|
|
|
|
!s_kernel ? "kernel" : "",
|
|
|
|
|
!s_kernel && !s_libnl ? " and " : "",
|
|
|
|
|
!s_libnl ? "libnl" : "",
|
|
|
|
|
!s_kernel && !s_libnl ? "do" : "does");
|
|
|
|
|
warn = 1;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!s_libnl && !s_kernel) {
|
|
|
|
|
nm_log_warn (LOGD_IP6, "libnl and the kernel do not support extended IFA_FLAGS needed by NM for "
|
|
|
|
|
"IPv6 private addresses. This feature is not available");
|
|
|
|
|
} else if (!s_libnl) {
|
|
|
|
|
nm_log_warn (LOGD_IP6, "libnl does not support extended IFA_FLAGS needed by NM for "
|
|
|
|
|
"IPv6 private addresses. This feature is not available");
|
|
|
|
|
} else if (!s_kernel) {
|
|
|
|
|
nm_log_warn (LOGD_IP6, "The kernel does not support extended IFA_FLAGS needed by NM for "
|
|
|
|
|
"IPv6 private addresses. This feature is not available");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
warn = 2;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-07 11:53:09 -05:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
|
2011-10-07 11:53:09 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2011-10-07 11:53:09 -05:00
|
|
|
NMConnection *connection;
|
2013-05-30 16:53:23 +02:00
|
|
|
int i;
|
|
|
|
|
NMDeviceStateReason reason;
|
2014-01-03 17:03:35 +01:00
|
|
|
static int system_support = -1;
|
2014-03-07 23:51:13 +01:00
|
|
|
guint ifa_flags = 0x00;
|
2014-01-03 17:03:35 +01:00
|
|
|
|
|
|
|
|
if (system_support == -1) {
|
|
|
|
|
/*
|
|
|
|
|
* Check, if both libnl and the kernel are recent enough,
|
|
|
|
|
* to help user space handling RA. If it's not supported,
|
2014-01-03 17:03:35 +01:00
|
|
|
* we have no ipv6-privacy and must add autoconf addresses
|
|
|
|
|
* as /128. The reason for the /128 is to prevent the kernel
|
|
|
|
|
* from adding a prefix route for this address.
|
2014-01-03 17:03:35 +01:00
|
|
|
**/
|
|
|
|
|
system_support = nm_platform_check_support_libnl_extended_ifa_flags () &&
|
|
|
|
|
nm_platform_check_support_kernel_extended_ifa_flags ();
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-04 14:34:12 +01:00
|
|
|
if (system_support)
|
|
|
|
|
ifa_flags = IFA_F_NOPREFIXROUTE;
|
2014-01-03 17:03:35 +01:00
|
|
|
if (priv->rdisc_use_tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR
|
|
|
|
|
|| priv->rdisc_use_tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)
|
2014-03-04 14:34:12 +01:00
|
|
|
{
|
|
|
|
|
/* without system_support, this flag will be ignored. Still set it, doesn't seem to do any harm. */
|
2014-01-03 17:03:35 +01:00
|
|
|
ifa_flags |= IFA_F_MANAGETEMPADDR;
|
2014-03-04 14:34:12 +01:00
|
|
|
}
|
2011-10-07 11:53:09 -05:00
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
g_return_if_fail (priv->act_request);
|
2014-07-15 13:36:24 +02:00
|
|
|
connection = nm_device_get_connection (self);
|
2011-10-07 11:53:09 -05:00
|
|
|
g_assert (connection);
|
|
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
if (!priv->ac_ip6_config)
|
|
|
|
|
priv->ac_ip6_config = nm_ip6_config_new ();
|
2011-10-07 11:53:09 -05:00
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
if (changed & NM_RDISC_CONFIG_GATEWAYS) {
|
|
|
|
|
/* Use the first gateway as ordered in router discovery cache. */
|
|
|
|
|
if (rdisc->gateways->len) {
|
|
|
|
|
NMRDiscGateway *gateway = &g_array_index (rdisc->gateways, NMRDiscGateway, 0);
|
2011-10-07 11:53:09 -05:00
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
nm_ip6_config_set_gateway (priv->ac_ip6_config, &gateway->address);
|
|
|
|
|
} else
|
|
|
|
|
nm_ip6_config_set_gateway (priv->ac_ip6_config, NULL);
|
2011-10-07 11:53:09 -05:00
|
|
|
}
|
|
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
if (changed & NM_RDISC_CONFIG_ADDRESSES) {
|
|
|
|
|
/* Rebuild address list from router discovery cache. */
|
|
|
|
|
nm_ip6_config_reset_addresses (priv->ac_ip6_config);
|
2011-10-07 11:53:09 -05:00
|
|
|
|
2014-01-06 21:05:00 +01:00
|
|
|
/* rdisc->addresses contains at most max_addresses entries.
|
|
|
|
|
* This is different from what the kernel does, which
|
|
|
|
|
* also counts static and temporary addresses when checking
|
|
|
|
|
* max_addresses.
|
|
|
|
|
**/
|
2013-05-30 16:53:23 +02:00
|
|
|
for (i = 0; i < rdisc->addresses->len; i++) {
|
|
|
|
|
NMRDiscAddress *discovered_address = &g_array_index (rdisc->addresses, NMRDiscAddress, i);
|
|
|
|
|
NMPlatformIP6Address address;
|
|
|
|
|
|
|
|
|
|
memset (&address, 0, sizeof (address));
|
|
|
|
|
address.address = discovered_address->address;
|
2014-01-03 17:03:35 +01:00
|
|
|
address.plen = system_support ? 64 : 128;
|
2013-07-29 14:53:06 +02:00
|
|
|
address.timestamp = discovered_address->timestamp;
|
|
|
|
|
address.lifetime = discovered_address->lifetime;
|
|
|
|
|
address.preferred = discovered_address->preferred;
|
2014-04-01 22:46:46 +02:00
|
|
|
if (address.preferred > address.lifetime)
|
|
|
|
|
address.preferred = address.lifetime;
|
2014-01-06 14:14:14 -06:00
|
|
|
address.source = NM_PLATFORM_SOURCE_RDISC;
|
2014-01-03 17:03:35 +01:00
|
|
|
address.flags = ifa_flags;
|
2013-05-30 16:53:23 +02:00
|
|
|
|
|
|
|
|
nm_ip6_config_add_address (priv->ac_ip6_config, &address);
|
2013-06-14 21:42:22 +02:00
|
|
|
}
|
2011-10-07 11:53:09 -05:00
|
|
|
}
|
|
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
if (changed & NM_RDISC_CONFIG_ROUTES) {
|
|
|
|
|
/* Rebuild route list from router discovery cache. */
|
|
|
|
|
nm_ip6_config_reset_routes (priv->ac_ip6_config);
|
2011-10-07 11:53:09 -05:00
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
for (i = 0; i < rdisc->routes->len; i++) {
|
|
|
|
|
NMRDiscRoute *discovered_route = &g_array_index (rdisc->routes, NMRDiscRoute, i);
|
2013-07-31 23:07:32 +02:00
|
|
|
NMPlatformIP6Route route;
|
2011-10-07 11:53:09 -05:00
|
|
|
|
2013-11-20 13:40:07 -06:00
|
|
|
/* Only accept non-default routes. The router has no idea what the
|
|
|
|
|
* local configuration or user preferences are, so sending routes
|
|
|
|
|
* with a prefix length of 0 is quite rude and thus ignored.
|
|
|
|
|
*/
|
|
|
|
|
if (discovered_route->plen > 0) {
|
|
|
|
|
memset (&route, 0, sizeof (route));
|
|
|
|
|
route.network = discovered_route->network;
|
|
|
|
|
route.plen = discovered_route->plen;
|
|
|
|
|
route.gateway = discovered_route->gateway;
|
2014-01-06 14:14:14 -06:00
|
|
|
route.source = NM_PLATFORM_SOURCE_RDISC;
|
2014-07-15 13:36:24 +02:00
|
|
|
route.metric = nm_device_get_priority (self);
|
2013-05-30 16:53:23 +02:00
|
|
|
|
2013-11-20 13:40:07 -06:00
|
|
|
nm_ip6_config_add_route (priv->ac_ip6_config, &route);
|
|
|
|
|
}
|
2013-06-14 21:42:22 +02:00
|
|
|
}
|
2011-10-07 11:53:09 -05:00
|
|
|
}
|
|
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
if (changed & NM_RDISC_CONFIG_DNS_SERVERS) {
|
|
|
|
|
/* Rebuild DNS server list from router discovery cache. */
|
|
|
|
|
nm_ip6_config_reset_nameservers (priv->ac_ip6_config);
|
2011-10-07 11:53:09 -05:00
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
for (i = 0; i < rdisc->dns_servers->len; i++) {
|
|
|
|
|
NMRDiscDNSServer *discovered_server = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i);
|
2011-10-07 11:53:09 -05:00
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
nm_ip6_config_add_nameserver (priv->ac_ip6_config, &discovered_server->address);
|
|
|
|
|
}
|
2011-10-07 11:53:09 -05:00
|
|
|
}
|
|
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
if (changed & NM_RDISC_CONFIG_DNS_DOMAINS) {
|
2013-12-19 10:58:46 -06:00
|
|
|
/* Rebuild domain list from router discovery cache. */
|
|
|
|
|
nm_ip6_config_reset_domains (priv->ac_ip6_config);
|
|
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
for (i = 0; i < rdisc->dns_domains->len; i++) {
|
|
|
|
|
NMRDiscDNSDomain *discovered_domain = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i);
|
2011-10-09 22:50:04 -05:00
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
nm_ip6_config_add_domain (priv->ac_ip6_config, discovered_domain->domain);
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-10-09 22:50:04 -05:00
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
if (changed & NM_RDISC_CONFIG_DHCP_LEVEL) {
|
2014-07-15 13:36:24 +02:00
|
|
|
dhcp6_cleanup (self, TRUE, TRUE);
|
2013-05-30 16:53:23 +02:00
|
|
|
|
|
|
|
|
priv->dhcp6_mode = rdisc->dhcp_level;
|
|
|
|
|
|
|
|
|
|
switch (priv->dhcp6_mode) {
|
|
|
|
|
case NM_RDISC_DHCP_LEVEL_NONE:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | LOGD_DHCP6,
|
|
|
|
|
"Activation: Stage 3 of 5 (IP Configure Start) starting DHCPv6"
|
|
|
|
|
" as requested by IPv6 router...");
|
2014-07-15 13:36:24 +02:00
|
|
|
switch (dhcp6_start (self, connection, priv->dhcp6_mode, &reason)) {
|
2013-05-30 16:53:23 +02:00
|
|
|
case NM_ACT_STAGE_RETURN_SUCCESS:
|
|
|
|
|
g_warn_if_reached ();
|
|
|
|
|
break;
|
|
|
|
|
case NM_ACT_STAGE_RETURN_POSTPONE:
|
|
|
|
|
return;
|
|
|
|
|
default:
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
2013-05-30 16:53:23 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-10-09 22:50:04 -05:00
|
|
|
}
|
2013-05-30 16:53:23 +02:00
|
|
|
|
2014-09-15 11:35:53 +02:00
|
|
|
/* hop_limit == 0 is a special value "unspecified", so do not touch
|
|
|
|
|
* in this case */
|
|
|
|
|
if (changed & NM_RDISC_CONFIG_HOP_LIMIT && rdisc->hop_limit > 0) {
|
2014-02-21 17:21:59 -05:00
|
|
|
char val[16];
|
|
|
|
|
|
|
|
|
|
g_snprintf (val, sizeof (val), "%d", rdisc->hop_limit);
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_ipv6_sysctl_set (self, "hop_limit", val);
|
2014-02-21 17:21:59 -05:00
|
|
|
}
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_activate_schedule_ip6_config_result (self);
|
2011-10-07 11:53:09 -05:00
|
|
|
}
|
|
|
|
|
|
2014-08-13 09:40:08 -05:00
|
|
|
static void
|
|
|
|
|
rdisc_ra_timeout (NMRDisc *rdisc, NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
/* We don't want to stop listening for router advertisements completely,
|
|
|
|
|
* but instead let device activation continue activating. If an RA
|
|
|
|
|
* shows up later, we'll use it as long as the device is not disconnected.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
_LOGD (LOGD_IP6, "timed out waiting for IPv6 router advertisement");
|
2014-08-13 14:44:22 -05:00
|
|
|
if (priv->ip6_state == IP_CONF) {
|
|
|
|
|
/* If RA is our only source of addressing information and we don't
|
|
|
|
|
* ever receive one, then time out IPv6. But if there is other
|
|
|
|
|
* IPv6 configuration, like manual IPv6 addresses or external IPv6
|
|
|
|
|
* config, consider that sufficient for IPv6 success.
|
|
|
|
|
*/
|
|
|
|
|
if (have_ip6_address (priv->ip6_config, FALSE))
|
|
|
|
|
nm_device_activate_schedule_ip6_config_result (self);
|
|
|
|
|
else
|
|
|
|
|
nm_device_activate_schedule_ip6_config_timeout (self);
|
|
|
|
|
}
|
2014-08-13 09:40:08 -05:00
|
|
|
}
|
|
|
|
|
|
2014-07-22 16:24:07 -05:00
|
|
|
static gboolean
|
2014-07-22 16:20:36 -05:00
|
|
|
addrconf6_start_with_link_ready (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMUtilsIPv6IfaceId iid;
|
|
|
|
|
|
|
|
|
|
g_assert (priv->rdisc);
|
|
|
|
|
|
2014-07-24 17:14:30 -05:00
|
|
|
if (!nm_device_get_ip_iface_identifier (self, &iid)) {
|
|
|
|
|
_LOGW (LOGD_IP6, "failed to get interface identifier; IPv6 cannot continue");
|
2014-07-22 16:24:07 -05:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
nm_rdisc_set_iid (priv->rdisc, iid);
|
2014-07-22 16:20:36 -05:00
|
|
|
|
2014-08-13 14:29:25 -05:00
|
|
|
/* Apply any manual configuration before starting RA */
|
|
|
|
|
if (!ip6_config_merge_and_apply (self, TRUE, NULL))
|
|
|
|
|
_LOGW (LOGD_IP6, "failed to apply manual IPv6 configuration");
|
|
|
|
|
|
2014-07-22 16:20:36 -05:00
|
|
|
nm_device_ipv6_sysctl_set (self, "accept_ra", "1");
|
|
|
|
|
nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0");
|
|
|
|
|
nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0");
|
|
|
|
|
nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0");
|
|
|
|
|
|
2014-08-13 09:40:08 -05:00
|
|
|
priv->rdisc_changed_id = g_signal_connect (priv->rdisc,
|
|
|
|
|
NM_RDISC_CONFIG_CHANGED,
|
|
|
|
|
G_CALLBACK (rdisc_config_changed),
|
|
|
|
|
self);
|
|
|
|
|
priv->rdisc_timeout_id = g_signal_connect (priv->rdisc,
|
|
|
|
|
NM_RDISC_RA_TIMEOUT,
|
|
|
|
|
G_CALLBACK (rdisc_ra_timeout),
|
|
|
|
|
self);
|
2014-07-22 16:20:36 -05:00
|
|
|
nm_rdisc_start (priv->rdisc);
|
2014-07-22 16:24:07 -05:00
|
|
|
return TRUE;
|
2014-07-22 16:20:36 -05:00
|
|
|
}
|
|
|
|
|
|
2014-07-22 16:24:07 -05:00
|
|
|
static NMActStageReturn
|
2014-01-03 17:03:35 +01:00
|
|
|
addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
|
2011-10-07 11:53:09 -05:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMConnection *connection;
|
2013-11-07 22:59:43 +01:00
|
|
|
NMActStageReturn ret;
|
2013-12-19 11:00:54 -06:00
|
|
|
const char *ip_iface = nm_device_get_ip_iface (self);
|
2011-10-07 11:53:09 -05:00
|
|
|
|
2011-12-05 12:27:49 +01:00
|
|
|
connection = nm_device_get_connection (self);
|
2011-10-07 11:53:09 -05:00
|
|
|
g_assert (connection);
|
|
|
|
|
|
2011-10-21 14:25:35 -05:00
|
|
|
g_warn_if_fail (priv->ac_ip6_config == NULL);
|
|
|
|
|
if (priv->ac_ip6_config) {
|
|
|
|
|
g_object_unref (priv->ac_ip6_config);
|
|
|
|
|
priv->ac_ip6_config = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-03 13:10:45 -05:00
|
|
|
priv->rdisc = nm_lndp_rdisc_new (nm_device_get_ip_ifindex (self), ip_iface);
|
2013-05-30 16:53:23 +02:00
|
|
|
if (!priv->rdisc) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGE (LOGD_IP6, "failed to start router discovery (%s)", ip_iface);
|
2013-05-30 16:53:23 +02:00
|
|
|
return FALSE;
|
2011-10-09 22:50:04 -05:00
|
|
|
}
|
2011-10-07 11:53:09 -05:00
|
|
|
|
2014-01-03 17:03:35 +01:00
|
|
|
priv->rdisc_use_tempaddr = use_tempaddr;
|
|
|
|
|
print_support_extended_ifa_flags (use_tempaddr);
|
|
|
|
|
|
2014-04-14 17:57:56 +02:00
|
|
|
if (!nm_setting_ip6_config_get_may_fail (nm_connection_get_setting_ip6_config (connection)))
|
|
|
|
|
nm_device_add_pending_action (self, PENDING_ACTION_AUTOCONF6, TRUE);
|
|
|
|
|
|
2013-11-07 22:59:43 +01:00
|
|
|
/* ensure link local is ready... */
|
|
|
|
|
ret = linklocal6_start (self);
|
2014-07-22 16:24:07 -05:00
|
|
|
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
|
|
|
|
|
/* success; wait for the LL address to show up */
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
2013-11-07 22:59:43 +01:00
|
|
|
|
2014-07-22 16:24:07 -05:00
|
|
|
/* success; already have the LL address; kick off router discovery */
|
|
|
|
|
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
|
|
|
|
|
return addrconf6_start_with_link_ready (self);
|
2013-11-07 22:59:43 +01:00
|
|
|
}
|
|
|
|
|
|
2011-10-07 11:53:09 -05:00
|
|
|
static void
|
|
|
|
|
addrconf6_cleanup (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
2014-08-13 09:40:08 -05:00
|
|
|
if (priv->rdisc_changed_id) {
|
|
|
|
|
g_signal_handler_disconnect (priv->rdisc, priv->rdisc_changed_id);
|
|
|
|
|
priv->rdisc_changed_id = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (priv->rdisc_timeout_id) {
|
|
|
|
|
g_signal_handler_disconnect (priv->rdisc, priv->rdisc_timeout_id);
|
|
|
|
|
priv->rdisc_timeout_id = 0;
|
2011-10-07 11:53:09 -05:00
|
|
|
}
|
|
|
|
|
|
2014-04-14 17:57:56 +02:00
|
|
|
nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE);
|
|
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
g_clear_object (&priv->ac_ip6_config);
|
|
|
|
|
g_clear_object (&priv->rdisc);
|
2011-10-07 11:53:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************/
|
|
|
|
|
|
2014-05-20 15:17:13 -05:00
|
|
|
static const char *ip6_properties_to_save[] = {
|
|
|
|
|
"accept_ra",
|
|
|
|
|
"accept_ra_defrtr",
|
|
|
|
|
"accept_ra_pinfo",
|
|
|
|
|
"accept_ra_rtr_pref",
|
|
|
|
|
"disable_ipv6",
|
|
|
|
|
"hop_limit",
|
|
|
|
|
"use_tempaddr",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
save_ip6_properties (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
const char *ifname = nm_device_get_ip_iface (self);
|
|
|
|
|
char *value;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
g_hash_table_remove_all (priv->ip6_saved_properties);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (ip6_properties_to_save); i++) {
|
|
|
|
|
value = nm_platform_sysctl_get (nm_utils_ip6_property_path (ifname, ip6_properties_to_save[i]));
|
|
|
|
|
if (value) {
|
|
|
|
|
g_hash_table_insert (priv->ip6_saved_properties,
|
|
|
|
|
(char *) ip6_properties_to_save[i],
|
|
|
|
|
value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
restore_ip6_properties (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
gpointer key, value;
|
|
|
|
|
|
|
|
|
|
g_hash_table_iter_init (&iter, priv->ip6_saved_properties);
|
2014-07-24 17:14:30 -05:00
|
|
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
|
|
|
/* Don't touch "disable_ipv6" if we're doing userland IPv6LL */
|
|
|
|
|
if (priv->nm_ipv6ll && strcmp (key, "disable_ipv6") == 0)
|
|
|
|
|
continue;
|
2014-05-20 15:17:13 -05:00
|
|
|
nm_device_ipv6_sysctl_set (self, key, value);
|
2014-07-24 17:14:30 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
set_disable_ipv6 (NMDevice *self, const char *value)
|
|
|
|
|
{
|
|
|
|
|
/* We only touch disable_ipv6 when NM is not managing the IPv6LL address */
|
|
|
|
|
if (NM_DEVICE_GET_PRIVATE (self)->nm_ipv6ll == FALSE)
|
|
|
|
|
nm_device_ipv6_sysctl_set (self, "disable_ipv6", value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
set_nm_ipv6ll (NMDevice *self, gboolean enable)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
int ifindex = nm_device_get_ip_ifindex (self);
|
|
|
|
|
|
|
|
|
|
if (!nm_platform_check_support_user_ipv6ll ())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
priv->nm_ipv6ll = enable;
|
|
|
|
|
if (ifindex > 0) {
|
|
|
|
|
const char *detail = enable ? "enable" : "disable";
|
|
|
|
|
|
|
|
|
|
_LOGD (LOGD_IP6, "will %s userland IPv6LL", detail);
|
|
|
|
|
if (!nm_platform_link_set_user_ipv6ll_enabled (ifindex, enable))
|
|
|
|
|
_LOGW (LOGD_IP6, "failed to %s userspace IPv6LL address handling", detail);
|
|
|
|
|
}
|
2014-05-20 15:17:13 -05:00
|
|
|
}
|
|
|
|
|
|
2014-01-03 17:03:35 +01:00
|
|
|
static NMSettingIP6ConfigPrivacy
|
|
|
|
|
use_tempaddr_clamp (NMSettingIP6ConfigPrivacy use_tempaddr)
|
|
|
|
|
{
|
|
|
|
|
switch (use_tempaddr) {
|
|
|
|
|
case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
|
|
|
|
|
case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR:
|
|
|
|
|
case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR:
|
|
|
|
|
return use_tempaddr;
|
|
|
|
|
default:
|
|
|
|
|
return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-01 21:10:15 +02:00
|
|
|
/* Get net.ipv6.conf.default.use_tempaddr value from /etc/sysctl.conf or
|
|
|
|
|
* /lib/sysctl.d/sysctl.conf
|
|
|
|
|
*/
|
2014-01-03 17:03:35 +01:00
|
|
|
static NMSettingIP6ConfigPrivacy
|
2012-08-01 21:10:15 +02:00
|
|
|
ip6_use_tempaddr (void)
|
|
|
|
|
{
|
|
|
|
|
char *contents = NULL;
|
|
|
|
|
const char *group_name = "[forged_group]\n";
|
|
|
|
|
char *sysctl_data = NULL;
|
|
|
|
|
GKeyFile *keyfile;
|
|
|
|
|
GError *error = NULL;
|
2014-01-03 17:03:35 +01:00
|
|
|
gint tmp;
|
|
|
|
|
NMSettingIP6ConfigPrivacy ret = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
|
2012-08-01 21:10:15 +02:00
|
|
|
|
|
|
|
|
/* Read file contents to a string. */
|
2013-12-13 20:12:57 +01:00
|
|
|
if (!g_file_get_contents ("/etc/sysctl.conf", &contents, NULL, NULL))
|
|
|
|
|
if (!g_file_get_contents ("/lib/sysctl.d/sysctl.conf", &contents, NULL, NULL))
|
2014-01-03 17:03:35 +01:00
|
|
|
return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
|
2012-08-01 21:10:15 +02:00
|
|
|
|
|
|
|
|
/* Prepend a group so that we can use GKeyFile parser. */
|
|
|
|
|
sysctl_data = g_strdup_printf ("%s%s", group_name, contents);
|
|
|
|
|
|
|
|
|
|
keyfile = g_key_file_new ();
|
2013-12-13 20:12:57 +01:00
|
|
|
if (!g_key_file_load_from_data (keyfile, sysctl_data, -1, G_KEY_FILE_NONE, NULL))
|
2012-08-01 21:10:15 +02:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
|
|
tmp = g_key_file_get_integer (keyfile, "forged_group", "net.ipv6.conf.default.use_tempaddr", &error);
|
|
|
|
|
if (error == NULL)
|
2014-01-03 17:03:35 +01:00
|
|
|
ret = use_tempaddr_clamp (tmp);
|
2012-08-01 21:10:15 +02:00
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
g_free (contents);
|
|
|
|
|
g_free (sysctl_data);
|
|
|
|
|
g_clear_error (&error);
|
|
|
|
|
g_key_file_free (keyfile);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-25 11:59:05 -06:00
|
|
|
static gboolean
|
|
|
|
|
ip6_requires_slaves (NMConnection *connection)
|
|
|
|
|
{
|
core: don't have IP4 and IP6 configs on slaves
Although it's convenient in some places to have IP configs on all
connections, it makes more sense in other places to not have IP
configs on slaves. (eg, it's confusing for nmcli, etc, to report a
full NMSettingIP4Config on a slave device). So revert parts of the
earlier patch. However, it's still safe to assume that s_ip4 != NULL
if method != DISABLED, so some of the earlier simplifications can
stay.
Also, add nm_utils_get_ip_config_method(), which returns the correct
IP config method for a connection, whether the connection has IP4 and
IP6 settings objects or not, and use that to keep some more of the
simplifications from the earlier patch.
2013-10-14 10:38:56 -04:00
|
|
|
const char *method;
|
2013-01-25 11:59:05 -06:00
|
|
|
|
core: don't have IP4 and IP6 configs on slaves
Although it's convenient in some places to have IP configs on all
connections, it makes more sense in other places to not have IP
configs on slaves. (eg, it's confusing for nmcli, etc, to report a
full NMSettingIP4Config on a slave device). So revert parts of the
earlier patch. However, it's still safe to assume that s_ip4 != NULL
if method != DISABLED, so some of the earlier simplifications can
stay.
Also, add nm_utils_get_ip_config_method(), which returns the correct
IP config method for a connection, whether the connection has IP4 and
IP6 settings objects or not, and use that to keep some more of the
simplifications from the earlier patch.
2013-10-14 10:38:56 -04:00
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
2013-01-25 11:59:05 -06:00
|
|
|
|
|
|
|
|
/* SLAAC, DHCP, and Link-Local depend on connectivity (and thus slaves)
|
|
|
|
|
* to complete addressing. SLAAC and DHCP obviously need a peer to
|
|
|
|
|
* provide a prefix, while Link-Local must perform DAD on the local link.
|
|
|
|
|
*/
|
2013-09-26 17:34:23 -04:00
|
|
|
return strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0
|
|
|
|
|
|| strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0
|
|
|
|
|
|| strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0;
|
2013-01-25 11:59:05 -06:00
|
|
|
}
|
|
|
|
|
|
2009-07-29 12:12:41 -04:00
|
|
|
static NMActStageReturn
|
2012-09-27 12:12:15 -04:00
|
|
|
act_stage3_ip6_config_start (NMDevice *self,
|
|
|
|
|
NMIP6Config **out_config,
|
|
|
|
|
NMDeviceStateReason *reason)
|
2009-07-29 12:12:41 -04:00
|
|
|
{
|
2009-07-30 13:50:42 -04:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2010-01-27 16:20:09 -08:00
|
|
|
const char *ip_iface;
|
2010-04-30 15:49:41 -07:00
|
|
|
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
2010-01-14 00:45:10 -08:00
|
|
|
NMConnection *connection;
|
core: don't have IP4 and IP6 configs on slaves
Although it's convenient in some places to have IP configs on all
connections, it makes more sense in other places to not have IP
configs on slaves. (eg, it's confusing for nmcli, etc, to report a
full NMSettingIP4Config on a slave device). So revert parts of the
earlier patch. However, it's still safe to assume that s_ip4 != NULL
if method != DISABLED, so some of the earlier simplifications can
stay.
Also, add nm_utils_get_ip_config_method(), which returns the correct
IP config method for a connection, whether the connection has IP4 and
IP6 settings objects or not, and use that to keep some more of the
simplifications from the earlier patch.
2013-10-14 10:38:56 -04:00
|
|
|
const char *method;
|
2012-02-21 15:44:19 +01:00
|
|
|
NMSettingIP6ConfigPrivacy ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
|
|
|
|
|
const char *ip6_privacy_str = "0\n";
|
2013-01-25 11:59:05 -06:00
|
|
|
GSList *slaves;
|
|
|
|
|
gboolean ready_slaves;
|
2009-07-30 13:50:42 -04:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
|
|
|
|
|
2013-06-07 15:11:23 -05:00
|
|
|
ip_iface = nm_device_get_ip_iface (self);
|
2013-05-07 10:23:44 -04:00
|
|
|
|
2011-12-05 12:27:49 +01:00
|
|
|
connection = nm_device_get_connection (self);
|
2010-01-14 00:45:10 -08:00
|
|
|
g_assert (connection);
|
|
|
|
|
|
core: don't have IP4 and IP6 configs on slaves
Although it's convenient in some places to have IP configs on all
connections, it makes more sense in other places to not have IP
configs on slaves. (eg, it's confusing for nmcli, etc, to report a
full NMSettingIP4Config on a slave device). So revert parts of the
earlier patch. However, it's still safe to assume that s_ip4 != NULL
if method != DISABLED, so some of the earlier simplifications can
stay.
Also, add nm_utils_get_ip_config_method(), which returns the correct
IP config method for a connection, whether the connection has IP4 and
IP6 settings objects or not, and use that to keep some more of the
simplifications from the earlier patch.
2013-10-14 10:38:56 -04:00
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
|
|
|
|
if (priv->master)
|
|
|
|
|
g_assert_cmpstr (method, ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE);
|
2013-06-07 15:11:23 -05:00
|
|
|
|
2013-09-26 17:34:23 -04:00
|
|
|
if ( strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) != 0
|
2014-05-20 16:39:57 -05:00
|
|
|
&& priv->is_master
|
2014-02-25 18:00:34 -06:00
|
|
|
&& !priv->carrier) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_IP6 | LOGD_DEVICE,
|
|
|
|
|
"IPv6 config waiting until carrier is on");
|
2013-06-07 15:11:23 -05:00
|
|
|
return NM_ACT_STAGE_RETURN_WAIT;
|
|
|
|
|
}
|
2010-01-14 00:45:10 -08:00
|
|
|
|
2013-01-25 11:59:05 -06:00
|
|
|
if (priv->is_master && ip6_requires_slaves (connection)) {
|
|
|
|
|
/* If the master has no ready slaves, and depends on slaves for
|
|
|
|
|
* a successful IPv6 attempt, then postpone IPv6 addressing.
|
|
|
|
|
*/
|
|
|
|
|
slaves = nm_device_master_get_slaves (self);
|
|
|
|
|
ready_slaves = NM_DEVICE_GET_CLASS (self)->have_any_ready_slaves (self, slaves);
|
|
|
|
|
g_slist_free (slaves);
|
|
|
|
|
|
|
|
|
|
if (ready_slaves == FALSE) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | LOGD_IP6,
|
|
|
|
|
"IPv6 config waiting until slaves are ready");
|
2013-01-25 11:59:05 -06:00
|
|
|
return NM_ACT_STAGE_RETURN_WAIT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-30 16:53:23 +02:00
|
|
|
priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE;
|
2010-05-01 10:16:38 -07:00
|
|
|
|
2013-10-08 13:51:00 -04:00
|
|
|
if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) {
|
|
|
|
|
if (!priv->master)
|
|
|
|
|
restore_ip6_properties (self);
|
|
|
|
|
return NM_ACT_STAGE_RETURN_STOP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Re-enable IPv6 on the interface */
|
2014-07-24 17:14:30 -05:00
|
|
|
set_disable_ipv6 (self, "0");
|
2013-10-08 13:51:00 -04:00
|
|
|
|
2014-01-03 17:03:35 +01:00
|
|
|
/* Enable/disable IPv6 Privacy Extensions.
|
|
|
|
|
* If a global value is configured by sysadmin (e.g. /etc/sysctl.conf),
|
|
|
|
|
* use that value instead of per-connection value.
|
|
|
|
|
*/
|
|
|
|
|
ip6_privacy = ip6_use_tempaddr ();
|
|
|
|
|
if (ip6_privacy == NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) {
|
|
|
|
|
NMSettingIP6Config *s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
|
|
|
|
|
|
|
|
|
if (s_ip6)
|
|
|
|
|
ip6_privacy = nm_setting_ip6_config_get_ip6_privacy (s_ip6);
|
|
|
|
|
}
|
|
|
|
|
ip6_privacy = use_tempaddr_clamp (ip6_privacy);
|
|
|
|
|
|
2013-10-24 13:55:06 -04:00
|
|
|
if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
|
2014-01-03 17:03:35 +01:00
|
|
|
if (!addrconf6_start (self, ip6_privacy)) {
|
2013-10-07 11:40:16 -05:00
|
|
|
/* IPv6 might be disabled; allow IPv4 to proceed */
|
|
|
|
|
ret = NM_ACT_STAGE_RETURN_STOP;
|
2011-10-09 22:50:04 -05:00
|
|
|
} else
|
|
|
|
|
ret = NM_ACT_STAGE_RETURN_POSTPONE;
|
2013-11-07 20:38:08 +01:00
|
|
|
} else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) {
|
|
|
|
|
ret = linklocal6_start (self);
|
2013-11-07 21:30:25 -06:00
|
|
|
if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
|
|
|
|
|
/* New blank config; LL address is already in priv->ext_ip6_config */
|
|
|
|
|
*out_config = nm_ip6_config_new ();
|
|
|
|
|
g_assert (*out_config);
|
|
|
|
|
}
|
2013-05-07 13:08:33 -05:00
|
|
|
} else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) {
|
2013-05-30 16:53:23 +02:00
|
|
|
priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_MANAGED;
|
2010-07-27 21:43:42 -07:00
|
|
|
ret = dhcp6_start (self, connection, priv->dhcp6_mode, reason);
|
2013-05-07 13:08:33 -05:00
|
|
|
} else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0) {
|
2011-10-09 22:50:04 -05:00
|
|
|
/* New blank config */
|
|
|
|
|
*out_config = nm_ip6_config_new ();
|
|
|
|
|
g_assert (*out_config);
|
|
|
|
|
|
2010-04-30 15:49:41 -07:00
|
|
|
ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
2014-02-12 23:54:26 +01:00
|
|
|
} else
|
|
|
|
|
_LOGW (LOGD_IP6, "unhandled IPv6 config method '%s'; will fail", method);
|
2010-04-30 15:49:41 -07:00
|
|
|
|
|
|
|
|
/* Other methods (shared) aren't implemented yet */
|
2010-01-14 00:45:10 -08:00
|
|
|
|
2012-02-21 15:44:19 +01:00
|
|
|
switch (ip6_privacy) {
|
|
|
|
|
case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN:
|
|
|
|
|
case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
|
2012-11-16 13:57:47 -06:00
|
|
|
ip6_privacy_str = "0";
|
2012-02-21 15:44:19 +01:00
|
|
|
break;
|
|
|
|
|
case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR:
|
2012-11-16 13:57:47 -06:00
|
|
|
ip6_privacy_str = "1";
|
2012-02-21 15:44:19 +01:00
|
|
|
break;
|
|
|
|
|
case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR:
|
2012-11-16 13:57:47 -06:00
|
|
|
ip6_privacy_str = "2";
|
2012-02-21 15:44:19 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2014-02-21 17:04:59 -05:00
|
|
|
nm_device_ipv6_sysctl_set (self, "use_tempaddr", ip6_privacy_str);
|
2012-02-21 15:44:19 +01:00
|
|
|
|
2010-01-14 00:45:10 -08:00
|
|
|
return ret;
|
2009-07-29 12:12:41 -04:00
|
|
|
}
|
|
|
|
|
|
2012-11-15 17:52:24 -06:00
|
|
|
/**
|
|
|
|
|
* nm_device_activate_stage3_ip4_start:
|
|
|
|
|
* @self: the device
|
|
|
|
|
*
|
|
|
|
|
* Try starting IPv4 configuration.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
|
|
|
|
nm_device_activate_stage3_ip4_start (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMActStageReturn ret;
|
|
|
|
|
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
|
|
|
|
NMIP4Config *ip4_config = NULL;
|
|
|
|
|
|
|
|
|
|
g_assert (priv->ip4_state == IP_WAIT);
|
|
|
|
|
|
|
|
|
|
priv->ip4_state = IP_CONF;
|
|
|
|
|
ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip4_config_start (self, &ip4_config, &reason);
|
|
|
|
|
if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
|
|
|
|
|
g_assert (ip4_config);
|
|
|
|
|
nm_device_activate_schedule_ip4_config_result (self, ip4_config);
|
|
|
|
|
g_object_unref (ip4_config);
|
|
|
|
|
} else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
|
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
|
|
|
|
return FALSE;
|
|
|
|
|
} else if (ret == NM_ACT_STAGE_RETURN_STOP) {
|
|
|
|
|
/* Early finish */
|
2013-06-27 17:51:24 +02:00
|
|
|
priv->ip4_state = IP_FAIL;
|
2012-11-15 17:52:24 -06:00
|
|
|
} else if (ret == NM_ACT_STAGE_RETURN_WAIT) {
|
|
|
|
|
/* Wait for something to try IP config again */
|
|
|
|
|
priv->ip4_state = IP_WAIT;
|
|
|
|
|
} else
|
|
|
|
|
g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE);
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_activate_stage3_ip6_start:
|
|
|
|
|
* @self: the device
|
|
|
|
|
*
|
|
|
|
|
* Try starting IPv6 configuration.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
|
|
|
|
nm_device_activate_stage3_ip6_start (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMActStageReturn ret;
|
|
|
|
|
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
|
|
|
|
NMIP6Config *ip6_config = NULL;
|
|
|
|
|
|
|
|
|
|
g_assert (priv->ip6_state == IP_WAIT);
|
|
|
|
|
|
|
|
|
|
priv->ip6_state = IP_CONF;
|
|
|
|
|
ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip6_config_start (self, &ip6_config, &reason);
|
|
|
|
|
if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
|
|
|
|
|
g_assert (ip6_config);
|
2013-06-14 21:42:22 +02:00
|
|
|
/* Here we get a static IPv6 config, like for Shared where it's
|
|
|
|
|
* autogenerated or from modems where it comes from ModemManager.
|
|
|
|
|
*/
|
|
|
|
|
g_warn_if_fail (priv->ac_ip6_config == NULL);
|
|
|
|
|
priv->ac_ip6_config = ip6_config;
|
|
|
|
|
nm_device_activate_schedule_ip6_config_result (self);
|
2012-11-15 17:52:24 -06:00
|
|
|
} else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
|
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
|
|
|
|
return FALSE;
|
|
|
|
|
} else if (ret == NM_ACT_STAGE_RETURN_STOP) {
|
|
|
|
|
/* Early finish */
|
2013-06-27 17:51:24 +02:00
|
|
|
priv->ip6_state = IP_FAIL;
|
2012-11-15 17:52:24 -06:00
|
|
|
} else if (ret == NM_ACT_STAGE_RETURN_WAIT) {
|
|
|
|
|
/* Wait for something to try IP config again */
|
|
|
|
|
priv->ip6_state = IP_WAIT;
|
|
|
|
|
} else
|
|
|
|
|
g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE);
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
2006-01-03 17:47:38 +00:00
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
/*
|
|
|
|
|
* nm_device_activate_stage3_ip_config_start
|
|
|
|
|
*
|
2009-07-29 12:12:41 -04:00
|
|
|
* Begin automatic/manual IP configuration
|
2005-12-31 08:21:24 +00:00
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
static gboolean
|
2007-01-04 12:06:26 +00:00
|
|
|
nm_device_activate_stage3_ip_config_start (gpointer user_data)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2007-06-11 13:36:34 +00:00
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
2011-10-09 22:50:04 -05:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-08-27 12:16:57 -05:00
|
|
|
NMActiveConnection *master;
|
|
|
|
|
NMDevice *master_device;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-01-04 12:06:26 +00:00
|
|
|
/* Clear the activation source ID now that this stage has run */
|
2009-07-29 12:12:41 -04:00
|
|
|
activation_source_clear (self, FALSE, 0);
|
|
|
|
|
|
2013-10-21 12:50:58 -04:00
|
|
|
priv->ip4_state = priv->ip6_state = IP_WAIT;
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) started...");
|
2008-07-11 10:28:53 +00:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
core: don't up devices during IP configuration stages
Assumed connections shouldn't require touching the device, and the
device should was already set IFF_UP during stage2 (which is
skipped for assumed connections). Instead, what the code was really
trying to do, was to ensure tha the IP interface the device was
going to use was up.
The only cases where the IP interface might *not* be up after stage2
is where the IP interface is different than the device's interface,
like for Bluetooth, ADSL, WWAN, and PPPoE. Move the call to
nm_platform_link_set_up() into nm_device_set_ip_iface() which all
those device types will call.
Thus, only the device types that really need to up their IP interface
will do so, but other devices (including when activating assumed
connections) that don't need to do this, won't do it.
2013-11-08 10:58:35 -06:00
|
|
|
/* Device should be up before we can do anything with it */
|
2014-02-12 23:54:26 +01:00
|
|
|
if (!nm_platform_link_is_up (nm_device_get_ip_ifindex (self)))
|
|
|
|
|
_LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
|
2011-10-09 22:50:04 -05:00
|
|
|
|
2012-11-14 14:05:30 -06:00
|
|
|
/* If the device is a slave, then we don't do any IP configuration but we
|
|
|
|
|
* use the IP config stage to indicate to the master we're ready for
|
2013-10-21 12:50:58 -04:00
|
|
|
* enslavement. If the master is already activating, it will have tried to
|
|
|
|
|
* enslave us when we changed state to IP_CONFIG, causing us to queue a
|
|
|
|
|
* transition to SECONDARIES (or FAILED if the enslavement failed), with
|
|
|
|
|
* our IP states set to IP_DONE either way. If the master isn't yet
|
|
|
|
|
* activating, then they'll still be in IP_WAIT. Either way, we bail out
|
|
|
|
|
* of IP config here.
|
2012-11-14 14:05:30 -06:00
|
|
|
*/
|
2012-08-22 09:38:01 -05:00
|
|
|
master = nm_active_connection_get_master (NM_ACTIVE_CONNECTION (priv->act_request));
|
2012-11-14 14:05:30 -06:00
|
|
|
if (master) {
|
2013-08-27 12:16:57 -05:00
|
|
|
master_device = nm_active_connection_get_device (master);
|
2013-10-21 12:50:58 -04:00
|
|
|
if (priv->ip4_state == IP_WAIT && priv->ip6_state == IP_WAIT) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: connection '%s' waiting on master '%s'",
|
|
|
|
|
nm_connection_get_id (nm_device_get_connection (self)),
|
|
|
|
|
master_device ? nm_device_get_iface (master_device) : "(unknown)");
|
2012-11-14 14:05:30 -06:00
|
|
|
}
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* IPv4 */
|
2012-11-15 17:52:24 -06:00
|
|
|
if (!nm_device_activate_stage3_ip4_start (self))
|
2005-12-31 08:21:24 +00:00
|
|
|
goto out;
|
|
|
|
|
|
2012-11-14 14:05:30 -06:00
|
|
|
/* IPv6 */
|
2012-11-15 17:52:24 -06:00
|
|
|
if (!nm_device_activate_stage3_ip6_start (self))
|
2009-07-29 12:12:41 -04:00
|
|
|
goto out;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2013-11-26 12:17:12 -05:00
|
|
|
if (priv->ip4_state == IP_FAIL && priv->ip6_state == IP_FAIL) {
|
|
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
|
|
|
|
|
}
|
|
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
out:
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) complete.");
|
2005-12-31 08:21:24 +00:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-03-21 15:03:23 -05:00
|
|
|
static void
|
2014-06-03 08:58:20 +02:00
|
|
|
fw_change_zone_cb (GError *error, gpointer user_data)
|
2012-03-21 15:03:23 -05:00
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
priv->fw_call = NULL;
|
|
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
|
/* FIXME: fail the device activation? */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
activation_source_schedule (self, nm_device_activate_stage3_ip_config_start, 0);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) scheduled.");
|
2012-03-21 15:03:23 -05:00
|
|
|
}
|
|
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
/*
|
|
|
|
|
* nm_device_activate_schedule_stage3_ip_config_start
|
|
|
|
|
*
|
|
|
|
|
* Schedule IP configuration start
|
|
|
|
|
*/
|
2006-01-07 16:22:17 +00:00
|
|
|
void
|
2007-06-11 13:36:34 +00:00
|
|
|
nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2007-06-11 13:36:34 +00:00
|
|
|
NMDevicePrivate *priv;
|
2012-03-21 15:03:23 -05:00
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingConnection *s_con = NULL;
|
|
|
|
|
const char *zone;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-06-11 13:36:34 +00:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-06-11 13:36:34 +00:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
g_return_if_fail (priv->act_request);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2012-03-21 15:03:23 -05:00
|
|
|
/* Add the interface to the specified firewall zone */
|
|
|
|
|
connection = nm_device_get_connection (self);
|
|
|
|
|
g_assert (connection);
|
|
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
|
|
|
|
|
|
|
|
|
zone = nm_setting_connection_get_zone (s_con);
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "Activation: setting firewall zone '%s'", zone ? zone : "default");
|
2014-07-02 15:19:58 +02:00
|
|
|
priv->fw_call = nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
|
2012-03-21 15:03:23 -05:00
|
|
|
nm_device_get_ip_iface (self),
|
|
|
|
|
zone,
|
2014-06-03 08:58:20 +02:00
|
|
|
FALSE,
|
|
|
|
|
fw_change_zone_cb,
|
2012-03-21 15:03:23 -05:00
|
|
|
self);
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2006-01-03 17:47:38 +00:00
|
|
|
static NMActStageReturn
|
2012-09-27 12:12:15 -04:00
|
|
|
act_stage4_ip4_config_timeout (NMDevice *self, NMDeviceStateReason *reason)
|
2006-01-03 17:47:38 +00:00
|
|
|
{
|
2010-05-03 01:19:54 -07:00
|
|
|
if (nm_device_ip_config_should_fail (self, FALSE)) {
|
|
|
|
|
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
|
|
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
2006-01-03 17:47:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
/*
|
2009-07-29 12:12:41 -04:00
|
|
|
* nm_device_activate_stage4_ip4_config_timeout
|
2005-12-31 08:21:24 +00:00
|
|
|
*
|
2009-07-29 12:12:41 -04:00
|
|
|
* Time out on retrieving the IPv4 config.
|
2005-12-31 08:21:24 +00:00
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
static gboolean
|
2011-10-09 22:50:04 -05:00
|
|
|
nm_device_activate_ip4_config_timeout (gpointer user_data)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2007-06-11 13:36:34 +00:00
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
2011-07-25 17:43:48 -04:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2007-01-04 12:06:26 +00:00
|
|
|
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
2008-07-11 10:28:53 +00:00
|
|
|
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-01-04 12:06:26 +00:00
|
|
|
/* Clear the activation source ID now that this stage has run */
|
2009-07-29 12:12:41 -04:00
|
|
|
activation_source_clear (self, FALSE, AF_INET);
|
2007-01-04 12:06:26 +00:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | LOGD_IP4,
|
|
|
|
|
"Activation: Stage 4 of 5 (IPv4 Configure Timeout) started...");
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2011-10-07 13:08:43 -05:00
|
|
|
ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip4_config_timeout (self, &reason);
|
2010-05-03 01:19:54 -07:00
|
|
|
if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
|
2006-01-03 17:47:38 +00:00
|
|
|
goto out;
|
2010-05-03 01:19:54 -07:00
|
|
|
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
2008-07-11 10:28:53 +00:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
2006-01-03 17:47:38 +00:00
|
|
|
goto out;
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
2006-01-03 17:47:38 +00:00
|
|
|
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2013-06-27 17:51:24 +02:00
|
|
|
priv->ip4_state = IP_FAIL;
|
2011-10-09 22:50:04 -05:00
|
|
|
|
|
|
|
|
/* If IPv4 failed and IPv6 failed, the activation fails */
|
2013-06-27 17:51:24 +02:00
|
|
|
if (priv->ip6_state == IP_FAIL)
|
2011-10-09 22:50:04 -05:00
|
|
|
nm_device_state_changed (self,
|
2013-06-27 17:51:24 +02:00
|
|
|
NM_DEVICE_STATE_FAILED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
|
2009-07-29 12:12:41 -04:00
|
|
|
|
|
|
|
|
out:
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | LOGD_IP4,
|
|
|
|
|
"Activation: Stage 4 of 5 (IPv4 Configure Timeout) complete.");
|
2009-07-29 12:12:41 -04:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2011-10-09 22:50:04 -05:00
|
|
|
* nm_device_activate_schedule_ip4_config_timeout
|
2009-07-29 12:12:41 -04:00
|
|
|
*
|
|
|
|
|
* Deal with a timeout of the IPv4 configuration
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void
|
2011-10-09 22:50:04 -05:00
|
|
|
nm_device_activate_schedule_ip4_config_timeout (NMDevice *self)
|
2009-07-29 12:12:41 -04:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
|
|
|
|
|
|
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
g_return_if_fail (priv->act_request);
|
|
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
activation_source_schedule (self, nm_device_activate_ip4_config_timeout, AF_INET);
|
2009-07-29 12:12:41 -04:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | LOGD_IP4,
|
|
|
|
|
"Activation: Stage 4 of 5 (IPv4 Configure Timeout) scheduled...");
|
2009-07-29 12:12:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static NMActStageReturn
|
2012-09-27 12:12:15 -04:00
|
|
|
act_stage4_ip6_config_timeout (NMDevice *self, NMDeviceStateReason *reason)
|
2009-07-29 12:12:41 -04:00
|
|
|
{
|
2010-05-03 01:19:54 -07:00
|
|
|
if (nm_device_ip_config_should_fail (self, TRUE)) {
|
|
|
|
|
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
|
|
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
2009-07-29 12:12:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2011-10-09 22:50:04 -05:00
|
|
|
* nm_device_activate_ip6_config_timeout
|
2009-07-29 12:12:41 -04:00
|
|
|
*
|
|
|
|
|
* Time out on retrieving the IPv6 config.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
static gboolean
|
2011-10-09 22:50:04 -05:00
|
|
|
nm_device_activate_ip6_config_timeout (gpointer user_data)
|
2009-07-29 12:12:41 -04:00
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
2011-07-25 17:43:48 -04:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2009-07-29 12:12:41 -04:00
|
|
|
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
|
|
|
|
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
|
|
|
|
|
|
|
|
|
/* Clear the activation source ID now that this stage has run */
|
|
|
|
|
activation_source_clear (self, FALSE, AF_INET6);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | LOGD_IP6,
|
|
|
|
|
"Activation: Stage 4 of 5 (IPv6 Configure Timeout) started...");
|
2009-07-29 12:12:41 -04:00
|
|
|
|
2011-10-07 13:08:43 -05:00
|
|
|
ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip6_config_timeout (self, &reason);
|
2010-05-03 01:19:54 -07:00
|
|
|
if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
|
2009-07-29 12:12:41 -04:00
|
|
|
goto out;
|
2010-05-03 01:19:54 -07:00
|
|
|
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
2009-07-29 12:12:41 -04:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
|
|
|
|
|
|
2013-07-02 16:42:49 +02:00
|
|
|
priv->ip6_state = IP_FAIL;
|
2011-10-09 22:50:04 -05:00
|
|
|
|
|
|
|
|
/* If IPv6 failed and IPv4 failed, the activation fails */
|
2013-06-27 17:51:24 +02:00
|
|
|
if (priv->ip4_state == IP_FAIL)
|
2011-10-09 22:50:04 -05:00
|
|
|
nm_device_state_changed (self,
|
2013-06-27 17:51:24 +02:00
|
|
|
NM_DEVICE_STATE_FAILED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
|
|
|
|
out:
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | LOGD_IP6,
|
|
|
|
|
"Activation: Stage 4 of 5 (IPv6 Configure Timeout) complete.");
|
2005-12-31 08:21:24 +00:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2011-10-09 22:50:04 -05:00
|
|
|
* nm_device_activate_schedule_ip6_config_timeout
|
2005-12-31 08:21:24 +00:00
|
|
|
*
|
2009-07-29 12:12:41 -04:00
|
|
|
* Deal with a timeout of the IPv6 configuration
|
2005-12-31 08:21:24 +00:00
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void
|
2011-10-09 22:50:04 -05:00
|
|
|
nm_device_activate_schedule_ip6_config_timeout (NMDevice *self)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2007-06-11 13:36:34 +00:00
|
|
|
NMDevicePrivate *priv;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-06-11 13:36:34 +00:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-06-11 13:36:34 +00:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
g_return_if_fail (priv->act_request);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
activation_source_schedule (self, nm_device_activate_ip6_config_timeout, AF_INET6);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | LOGD_IP6,
|
|
|
|
|
"Activation: Stage 4 of 5 (IPv6 Configure Timeout) scheduled...");
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2008-08-15 15:34:28 +00:00
|
|
|
static void
|
|
|
|
|
share_child_setup (gpointer user_data G_GNUC_UNUSED)
|
|
|
|
|
{
|
|
|
|
|
/* We are in the child process at this point */
|
|
|
|
|
pid_t pid = getpid ();
|
|
|
|
|
setpgid (pid, pid);
|
2012-05-21 14:10:05 +02:00
|
|
|
|
|
|
|
|
nm_unblock_posix_signals (NULL);
|
2008-08-15 15:34:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
share_init (void)
|
|
|
|
|
{
|
2009-07-29 12:12:41 -04:00
|
|
|
int status;
|
2008-08-15 15:34:28 +00:00
|
|
|
char *modules[] = { "ip_tables", "iptable_nat", "nf_nat_ftp", "nf_nat_irc",
|
|
|
|
|
"nf_nat_sip", "nf_nat_tftp", "nf_nat_pptp", "nf_nat_h323",
|
|
|
|
|
NULL };
|
|
|
|
|
char **iter;
|
2014-02-12 23:54:26 +01:00
|
|
|
int errsv;
|
2008-08-15 15:34:28 +00:00
|
|
|
|
2013-11-08 08:49:06 -05:00
|
|
|
if (!nm_platform_sysctl_set ("/proc/sys/net/ipv4/ip_forward", "1")) {
|
2014-02-12 23:54:26 +01:00
|
|
|
errsv = errno;
|
|
|
|
|
nm_log_err (LOGD_SHARING, "share: error starting IP forwarding: (%d) %s",
|
|
|
|
|
errsv, strerror (errsv));
|
2009-07-29 12:12:41 -04:00
|
|
|
return FALSE;
|
2008-08-15 15:34:28 +00:00
|
|
|
}
|
|
|
|
|
|
2013-11-08 08:49:06 -05:00
|
|
|
if (!nm_platform_sysctl_set ("/proc/sys/net/ipv4/ip_dynaddr", "1")) {
|
2014-02-12 23:54:26 +01:00
|
|
|
errsv = errno;
|
|
|
|
|
nm_log_err (LOGD_SHARING, "share: error starting IP forwarding: (%d) %s",
|
|
|
|
|
errsv, strerror (errsv));
|
2008-08-15 15:34:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (iter = modules; *iter; iter++) {
|
|
|
|
|
char *argv[3] = { "/sbin/modprobe", *iter, NULL };
|
|
|
|
|
char *envp[1] = { NULL };
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
if (!g_spawn_sync ("/", argv, envp, G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
|
|
|
|
|
share_child_setup, NULL, NULL, NULL, &status, &error)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
nm_log_err (LOGD_SHARING, "share: error loading NAT module %s: (%d) %s",
|
2010-04-07 12:31:39 -07:00
|
|
|
*iter, error ? error->code : 0,
|
|
|
|
|
(error && error->message) ? error->message : "unknown");
|
2008-08-15 15:34:28 +00:00
|
|
|
if (error)
|
|
|
|
|
g_error_free (error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
add_share_rule (NMActRequest *req, const char *table, const char *fmt, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list args;
|
|
|
|
|
char *cmd;
|
|
|
|
|
|
|
|
|
|
va_start (args, fmt);
|
|
|
|
|
cmd = g_strdup_vprintf (fmt, args);
|
|
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
|
|
nm_act_request_add_share_rule (req, table, cmd);
|
|
|
|
|
g_free (cmd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2011-10-09 23:48:13 -05:00
|
|
|
start_sharing (NMDevice *self, NMIP4Config *config)
|
2008-08-15 15:34:28 +00:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMActRequest *req;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
char str_addr[INET_ADDRSTRLEN + 1];
|
|
|
|
|
char str_mask[INET_ADDRSTRLEN + 1];
|
|
|
|
|
guint32 netmask, network;
|
2013-06-29 13:33:36 +02:00
|
|
|
const NMPlatformIP4Address *ip4_addr;
|
2008-10-22 16:32:13 +00:00
|
|
|
const char *ip_iface;
|
2008-08-15 15:34:28 +00:00
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
g_return_val_if_fail (config != NULL, FALSE);
|
2008-08-15 15:34:28 +00:00
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
ip_iface = nm_device_get_ip_iface (self);
|
2008-08-15 15:34:28 +00:00
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
ip4_addr = nm_ip4_config_get_address (config, 0);
|
2013-06-29 13:33:36 +02:00
|
|
|
if (!ip4_addr || !ip4_addr->address)
|
2008-08-15 15:34:28 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
2013-06-29 13:33:36 +02:00
|
|
|
netmask = nm_utils_ip4_prefix_to_netmask (ip4_addr->plen);
|
2008-08-15 15:34:28 +00:00
|
|
|
if (!inet_ntop (AF_INET, &netmask, str_mask, sizeof (str_mask)))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2013-06-29 13:33:36 +02:00
|
|
|
network = ip4_addr->address & netmask;
|
2008-08-15 15:34:28 +00:00
|
|
|
if (!inet_ntop (AF_INET, &network, str_addr, sizeof (str_addr)))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (!share_init ())
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
req = nm_device_get_act_request (self);
|
|
|
|
|
g_assert (req);
|
|
|
|
|
|
2008-10-22 16:32:13 +00:00
|
|
|
add_share_rule (req, "filter", "INPUT --in-interface %s --protocol tcp --destination-port 53 --jump ACCEPT", ip_iface);
|
|
|
|
|
add_share_rule (req, "filter", "INPUT --in-interface %s --protocol udp --destination-port 53 --jump ACCEPT", ip_iface);
|
|
|
|
|
add_share_rule (req, "filter", "INPUT --in-interface %s --protocol tcp --destination-port 67 --jump ACCEPT", ip_iface);
|
|
|
|
|
add_share_rule (req, "filter", "INPUT --in-interface %s --protocol udp --destination-port 67 --jump ACCEPT", ip_iface);
|
|
|
|
|
add_share_rule (req, "filter", "FORWARD --in-interface %s --jump REJECT", ip_iface);
|
|
|
|
|
add_share_rule (req, "filter", "FORWARD --out-interface %s --jump REJECT", ip_iface);
|
|
|
|
|
add_share_rule (req, "filter", "FORWARD --in-interface %s --out-interface %s --jump ACCEPT", ip_iface, ip_iface);
|
|
|
|
|
add_share_rule (req, "filter", "FORWARD --source %s/%s --in-interface %s --jump ACCEPT", str_addr, str_mask, ip_iface);
|
|
|
|
|
add_share_rule (req, "filter", "FORWARD --destination %s/%s --out-interface %s --match state --state ESTABLISHED,RELATED --jump ACCEPT", str_addr, str_mask, ip_iface);
|
2011-09-06 18:31:40 -05:00
|
|
|
add_share_rule (req, "nat", "POSTROUTING --source %s/%s ! --destination %s/%s --jump MASQUERADE", str_addr, str_mask, str_addr, str_mask);
|
2008-08-15 15:34:28 +00:00
|
|
|
|
|
|
|
|
nm_act_request_set_shared (req, TRUE);
|
|
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, config, &error)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGE (LOGD_SHARING, "share: (%s) failed to start dnsmasq: %s",
|
|
|
|
|
ip_iface, (error && error->message) ? error->message : "(unknown)");
|
2008-08-15 15:34:28 +00:00
|
|
|
g_error_free (error);
|
|
|
|
|
nm_act_request_set_shared (req, FALSE);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
priv->dnsmasq_state_id = g_signal_connect (priv->dnsmasq_manager, "state-changed",
|
|
|
|
|
G_CALLBACK (dnsmasq_state_changed_cb),
|
|
|
|
|
self);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-03-19 12:39:38 -04:00
|
|
|
static void
|
|
|
|
|
send_arps (NMDevice *self, const char *mode_arg)
|
|
|
|
|
{
|
2014-09-03 15:47:55 -05:00
|
|
|
const char *argv[] = { NULL, mode_arg, "-q", "-I", nm_device_get_ip_iface (self), "-c", "1", NULL, NULL };
|
2014-03-19 12:39:38 -04:00
|
|
|
int ip_arg = G_N_ELEMENTS (argv) - 2;
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingIP4Config *s_ip4;
|
|
|
|
|
int i, num;
|
|
|
|
|
NMIP4Address *addr;
|
|
|
|
|
guint32 ipaddr;
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
connection = nm_device_get_connection (self);
|
|
|
|
|
if (!connection)
|
|
|
|
|
return;
|
|
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
|
|
|
|
if (!s_ip4)
|
|
|
|
|
return;
|
|
|
|
|
num = nm_setting_ip4_config_get_num_addresses (s_ip4);
|
2014-09-03 15:47:55 -05:00
|
|
|
if (num == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
argv[0] = nm_utils_find_helper ("arping", NULL, NULL);
|
|
|
|
|
if (!argv[0]) {
|
|
|
|
|
_LOGW (LOGD_DEVICE | LOGD_IP4, "arping could not be found; no ARPs will be sent");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-03-19 12:39:38 -04:00
|
|
|
|
|
|
|
|
for (i = 0; i < num; i++) {
|
2014-02-12 23:54:26 +01:00
|
|
|
gs_free char *tmp_str = NULL;
|
2014-03-19 12:39:38 -04:00
|
|
|
addr = nm_setting_ip4_config_get_address (s_ip4, i);
|
|
|
|
|
ipaddr = nm_ip4_address_get_address (addr);
|
|
|
|
|
argv[ip_arg] = (char *) nm_utils_inet4_ntop (ipaddr, NULL);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE | LOGD_IP4,
|
|
|
|
|
"arping: run %s", (tmp_str = g_strjoinv (" ", (char **) argv)));
|
2014-03-19 12:39:38 -04:00
|
|
|
g_spawn_async (NULL, (char **) argv, NULL,
|
|
|
|
|
G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
|
|
|
|
|
nm_unblock_posix_signals,
|
|
|
|
|
NULL, NULL, &error);
|
|
|
|
|
if (error) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE | LOGD_IP4,
|
|
|
|
|
"arping: could not send ARP for local address %s: %s",
|
|
|
|
|
argv[ip_arg], error->message);
|
2014-03-19 12:39:38 -04:00
|
|
|
g_clear_error (&error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
arp_announce_round2 (gpointer self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
priv->arp_round2_id = 0;
|
|
|
|
|
|
|
|
|
|
if ( priv->state >= NM_DEVICE_STATE_IP_CONFIG
|
|
|
|
|
&& priv->state <= NM_DEVICE_STATE_ACTIVATED)
|
|
|
|
|
send_arps (self, "-U");
|
|
|
|
|
|
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
arp_cleanup (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->arp_round2_id) {
|
|
|
|
|
g_source_remove (priv->arp_round2_id);
|
|
|
|
|
priv->arp_round2_id = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
arp_announce (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingIP4Config *s_ip4;
|
|
|
|
|
int num;
|
|
|
|
|
|
|
|
|
|
arp_cleanup (self);
|
|
|
|
|
|
|
|
|
|
/* We only care about manually-configured addresses; DHCP- and autoip-configured
|
|
|
|
|
* ones should already have been seen on the network at this point.
|
|
|
|
|
*/
|
|
|
|
|
connection = nm_device_get_connection (self);
|
|
|
|
|
if (!connection)
|
|
|
|
|
return;
|
|
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
|
|
|
|
if (!s_ip4)
|
|
|
|
|
return;
|
|
|
|
|
num = nm_setting_ip4_config_get_num_addresses (s_ip4);
|
|
|
|
|
if (num == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
send_arps (self, "-A");
|
|
|
|
|
priv->arp_round2_id = g_timeout_add_seconds (2, arp_announce_round2, self);
|
|
|
|
|
}
|
|
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
static gboolean
|
2011-10-09 22:50:04 -05:00
|
|
|
nm_device_activate_ip4_config_commit (gpointer user_data)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2007-06-11 13:36:34 +00:00
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
2009-08-05 18:03:09 -04:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2011-10-09 22:50:04 -05:00
|
|
|
NMActRequest *req;
|
2014-08-02 00:48:35 +02:00
|
|
|
const char *method;
|
2008-05-29 20:58:52 +00:00
|
|
|
NMConnection *connection;
|
2008-07-11 10:28:53 +00:00
|
|
|
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-01-04 12:06:26 +00:00
|
|
|
/* Clear the activation source ID now that this stage has run */
|
2011-12-06 17:17:34 -06:00
|
|
|
activation_source_clear (self, FALSE, AF_INET);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: Stage 5 of 5 (IPv4 Commit) started...");
|
2011-12-06 16:36:37 -06:00
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
req = nm_device_get_act_request (self);
|
|
|
|
|
g_assert (req);
|
|
|
|
|
connection = nm_act_request_get_connection (req);
|
|
|
|
|
g_assert (connection);
|
|
|
|
|
|
core: don't up devices during IP configuration stages
Assumed connections shouldn't require touching the device, and the
device should was already set IFF_UP during stage2 (which is
skipped for assumed connections). Instead, what the code was really
trying to do, was to ensure tha the IP interface the device was
going to use was up.
The only cases where the IP interface might *not* be up after stage2
is where the IP interface is different than the device's interface,
like for Bluetooth, ADSL, WWAN, and PPPoE. Move the call to
nm_platform_link_set_up() into nm_device_set_ip_iface() which all
those device types will call.
Thus, only the device types that really need to up their IP interface
will do so, but other devices (including when activating assumed
connections) that don't need to do this, won't do it.
2013-11-08 10:58:35 -06:00
|
|
|
/* Device should be up before we can do anything with it */
|
2014-02-12 23:54:26 +01:00
|
|
|
if (!nm_platform_link_is_up (nm_device_get_ip_ifindex (self)))
|
|
|
|
|
_LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
|
2009-08-05 18:03:09 -04:00
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
/* NULL to use the existing priv->dev_ip4_config */
|
2013-08-01 15:44:53 -05:00
|
|
|
if (!ip4_config_merge_and_apply (self, NULL, TRUE, &reason)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | LOGD_IP4,
|
|
|
|
|
"Activation: Stage 5 of 5 (IPv4 Commit) failed");
|
2008-07-11 10:28:53 +00:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
2008-05-29 20:58:52 +00:00
|
|
|
goto out;
|
|
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
/* Start IPv4 sharing if we need it */
|
core: don't have IP4 and IP6 configs on slaves
Although it's convenient in some places to have IP configs on all
connections, it makes more sense in other places to not have IP
configs on slaves. (eg, it's confusing for nmcli, etc, to report a
full NMSettingIP4Config on a slave device). So revert parts of the
earlier patch. However, it's still safe to assume that s_ip4 != NULL
if method != DISABLED, so some of the earlier simplifications can
stay.
Also, add nm_utils_get_ip_config_method(), which returns the correct
IP config method for a connection, whether the connection has IP4 and
IP6 settings objects or not, and use that to keep some more of the
simplifications from the earlier patch.
2013-10-14 10:38:56 -04:00
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
2011-10-09 22:50:04 -05:00
|
|
|
|
2013-09-26 17:34:23 -04:00
|
|
|
if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) {
|
2013-08-01 10:34:46 -05:00
|
|
|
if (!start_sharing (self, priv->ip4_config)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_SHARING, "Activation: Stage 5 of 5 (IPv4 Commit) start sharing failed.");
|
2011-10-09 22:50:04 -05:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
2009-07-29 12:12:41 -04:00
|
|
|
}
|
|
|
|
|
|
2014-04-29 16:42:57 -05:00
|
|
|
/* If IPv4 wasn't the first to complete, and DHCP was used, then ensure
|
|
|
|
|
* dispatcher scripts get the DHCP lease information.
|
|
|
|
|
*/
|
|
|
|
|
if ( priv->dhcp4_client
|
|
|
|
|
&& nm_device_activate_ip4_state_in_conf (self)
|
|
|
|
|
&& (nm_device_get_state (self) > NM_DEVICE_STATE_IP_CONFIG)) {
|
|
|
|
|
/* Notify dispatcher scripts of new DHCP4 config */
|
|
|
|
|
nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE,
|
|
|
|
|
nm_device_get_connection (self),
|
|
|
|
|
self,
|
|
|
|
|
NULL,
|
2014-05-14 21:21:10 -05:00
|
|
|
NULL,
|
2014-04-29 16:42:57 -05:00
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-19 12:39:38 -04:00
|
|
|
arp_announce (self);
|
|
|
|
|
|
2013-06-11 17:05:49 -05:00
|
|
|
/* Enter the IP_CHECK state if this is the first method to complete */
|
2011-10-09 23:48:13 -05:00
|
|
|
priv->ip4_state = IP_DONE;
|
2014-04-14 17:57:56 +02:00
|
|
|
|
|
|
|
|
nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
|
|
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG)
|
2013-06-11 17:05:49 -05:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
|
2011-10-09 22:50:04 -05:00
|
|
|
|
|
|
|
|
out:
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: Stage 5 of 5 (IPv4 Commit) complete.");
|
2008-10-29 14:35:25 +00:00
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_device_activate_schedule_ip4_config_result (NMDevice *self, NMIP4Config *config)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
|
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
2013-08-01 10:34:46 -05:00
|
|
|
g_clear_object (&priv->dev_ip4_config);
|
2013-10-15 21:03:42 -05:00
|
|
|
if (config)
|
|
|
|
|
priv->dev_ip4_config = g_object_ref (config);
|
2011-10-09 22:50:04 -05:00
|
|
|
|
2012-03-21 15:03:23 -05:00
|
|
|
activation_source_schedule (self, nm_device_activate_ip4_config_commit, AF_INET);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | LOGD_IP4,
|
|
|
|
|
"Activation: Stage 5 of 5 (IPv4 Configure Commit) scheduled...");
|
2011-10-09 22:50:04 -05:00
|
|
|
}
|
|
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
gboolean
|
|
|
|
|
nm_device_activate_ip4_state_in_conf (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, FALSE);
|
|
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_CONF;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-28 13:34:44 -06:00
|
|
|
gboolean
|
|
|
|
|
nm_device_activate_ip4_state_in_wait (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, FALSE);
|
|
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
static gboolean
|
|
|
|
|
nm_device_activate_ip6_config_commit (gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-01-23 13:02:16 -06:00
|
|
|
guint level = (priv->ip6_state == IP_DONE) ? LOGL_DEBUG : LOGL_INFO;
|
2011-10-09 22:50:04 -05:00
|
|
|
NMActRequest *req;
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
|
|
|
|
|
|
|
|
|
/* Clear the activation source ID now that this stage has run */
|
2011-12-06 17:17:34 -06:00
|
|
|
activation_source_clear (self, FALSE, AF_INET6);
|
2011-10-09 22:50:04 -05:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOG (level, LOGD_DEVICE, "Activation: Stage 5 of 5 (IPv6 Commit) started...");
|
2011-12-06 16:36:37 -06:00
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
req = nm_device_get_act_request (self);
|
|
|
|
|
g_assert (req);
|
|
|
|
|
connection = nm_act_request_get_connection (req);
|
|
|
|
|
g_assert (connection);
|
|
|
|
|
|
core: don't up devices during IP configuration stages
Assumed connections shouldn't require touching the device, and the
device should was already set IFF_UP during stage2 (which is
skipped for assumed connections). Instead, what the code was really
trying to do, was to ensure tha the IP interface the device was
going to use was up.
The only cases where the IP interface might *not* be up after stage2
is where the IP interface is different than the device's interface,
like for Bluetooth, ADSL, WWAN, and PPPoE. Move the call to
nm_platform_link_set_up() into nm_device_set_ip_iface() which all
those device types will call.
Thus, only the device types that really need to up their IP interface
will do so, but other devices (including when activating assumed
connections) that don't need to do this, won't do it.
2013-11-08 10:58:35 -06:00
|
|
|
/* Device should be up before we can do anything with it */
|
|
|
|
|
g_warn_if_fail (nm_platform_link_is_up (nm_device_get_ip_ifindex (self)));
|
2011-10-09 22:50:04 -05:00
|
|
|
|
2013-08-15 12:55:56 -05:00
|
|
|
if (ip6_config_merge_and_apply (self, TRUE, &reason)) {
|
2014-04-29 16:42:57 -05:00
|
|
|
/* If IPv6 wasn't the first IP to complete, and DHCP was used,
|
|
|
|
|
* then ensure dispatcher scripts get the DHCP lease information.
|
|
|
|
|
*/
|
|
|
|
|
if ( priv->dhcp6_client
|
|
|
|
|
&& nm_device_activate_ip6_state_in_conf (self)
|
|
|
|
|
&& (nm_device_get_state (self) > NM_DEVICE_STATE_IP_CONFIG)) {
|
|
|
|
|
/* Notify dispatcher scripts of new DHCP6 config */
|
|
|
|
|
nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE,
|
|
|
|
|
nm_device_get_connection (self),
|
|
|
|
|
self,
|
|
|
|
|
NULL,
|
2014-05-14 21:21:10 -05:00
|
|
|
NULL,
|
2014-04-29 16:42:57 -05:00
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-11 17:05:49 -05:00
|
|
|
/* Enter the IP_CHECK state if this is the first method to complete */
|
2011-10-21 14:25:35 -05:00
|
|
|
priv->ip6_state = IP_DONE;
|
2014-04-14 17:57:56 +02:00
|
|
|
|
|
|
|
|
nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
|
|
|
|
|
nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE);
|
|
|
|
|
|
2011-10-21 14:25:35 -05:00
|
|
|
if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG)
|
2013-06-11 17:05:49 -05:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
|
2011-10-21 14:25:35 -05:00
|
|
|
} else {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE | LOGD_IP6,
|
|
|
|
|
"Activation: Stage 5 of 5 (IPv6 Commit) failed");
|
2011-10-09 22:50:04 -05:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOG (level, LOGD_DEVICE, "Activation: Stage 5 of 5 (IPv6 Commit) complete.");
|
2008-09-05 02:55:40 +00:00
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
void
|
2013-06-14 21:42:22 +02:00
|
|
|
nm_device_activate_schedule_ip6_config_result (NMDevice *self)
|
2011-10-09 22:50:04 -05:00
|
|
|
{
|
2014-01-23 13:02:16 -06:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
guint level = (priv->ip6_state == IP_DONE) ? LOGL_DEBUG : LOGL_INFO;
|
|
|
|
|
|
2011-10-09 22:50:04 -05:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
|
|
|
|
|
2014-08-13 09:40:08 -05:00
|
|
|
/* If IP had previously failed, move it back to IP_CONF since we
|
|
|
|
|
* clearly now have configuration.
|
|
|
|
|
*/
|
|
|
|
|
if (priv->ip6_state == IP_FAIL)
|
|
|
|
|
priv->ip6_state = IP_CONF;
|
|
|
|
|
|
2012-03-21 15:03:23 -05:00
|
|
|
activation_source_schedule (self, nm_device_activate_ip6_config_commit, AF_INET6);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOG (level, LOGD_DEVICE | LOGD_IP6,
|
|
|
|
|
"Activation: Stage 5 of 5 (IPv6 Commit) scheduled...");
|
2011-10-09 22:50:04 -05:00
|
|
|
}
|
|
|
|
|
|
2011-10-09 23:48:13 -05:00
|
|
|
gboolean
|
|
|
|
|
nm_device_activate_ip6_state_in_conf (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, FALSE);
|
|
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_CONF;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-28 13:34:44 -06:00
|
|
|
gboolean
|
|
|
|
|
nm_device_activate_ip6_state_in_wait (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, FALSE);
|
|
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT;
|
|
|
|
|
}
|
|
|
|
|
|
2007-09-11 18:02:27 +00:00
|
|
|
static void
|
|
|
|
|
clear_act_request (NMDevice *self)
|
|
|
|
|
{
|
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
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2007-09-11 18:02:27 +00:00
|
|
|
|
2007-09-11 19:20:34 +00:00
|
|
|
if (!priv->act_request)
|
2007-09-11 18:02:27 +00:00
|
|
|
return;
|
|
|
|
|
|
2012-02-03 14:53:09 -06:00
|
|
|
nm_active_connection_set_default (NM_ACTIVE_CONNECTION (priv->act_request), FALSE);
|
2008-06-10 02:01:13 +00:00
|
|
|
|
2013-09-11 09:21:17 -05:00
|
|
|
if (priv->master_ready_id) {
|
|
|
|
|
g_signal_handler_disconnect (priv->act_request, priv->master_ready_id);
|
|
|
|
|
priv->master_ready_id = 0;
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
g_clear_object (&priv->act_request);
|
2014-03-18 15:37:12 -05:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_ACTIVE_CONNECTION);
|
2007-09-11 18:02:27 +00:00
|
|
|
}
|
|
|
|
|
|
2010-01-13 17:59:54 -08:00
|
|
|
static void
|
2014-05-20 15:03:27 -05:00
|
|
|
dnsmasq_cleanup (NMDevice *self)
|
2010-01-14 00:45:10 -08:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (!priv->dnsmasq_manager)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (priv->dnsmasq_state_id) {
|
|
|
|
|
g_signal_handler_disconnect (priv->dnsmasq_manager, priv->dnsmasq_state_id);
|
|
|
|
|
priv->dnsmasq_state_id = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_dnsmasq_manager_stop (priv->dnsmasq_manager);
|
|
|
|
|
g_object_unref (priv->dnsmasq_manager);
|
|
|
|
|
priv->dnsmasq_manager = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-17 22:39:34 -06:00
|
|
|
static void
|
|
|
|
|
_update_ip4_address (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
struct ifreq req;
|
|
|
|
|
guint32 new_address;
|
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (self != NULL);
|
|
|
|
|
|
|
|
|
|
fd = socket (PF_INET, SOCK_DGRAM, 0);
|
|
|
|
|
if (fd < 0) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGE (LOGD_IP4, "couldn't open control socket.");
|
2011-11-17 22:39:34 -06:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset (&req, 0, sizeof (struct ifreq));
|
|
|
|
|
strncpy (req.ifr_name, nm_device_get_ip_iface (self), IFNAMSIZ);
|
|
|
|
|
if (ioctl (fd, SIOCGIFADDR, &req) == 0) {
|
|
|
|
|
new_address = ((struct sockaddr_in *)(&req.ifr_addr))->sin_addr.s_addr;
|
|
|
|
|
if (new_address != priv->ip4_address)
|
|
|
|
|
priv->ip4_address = new_address;
|
|
|
|
|
}
|
|
|
|
|
close (fd);
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-20 16:39:57 -05:00
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_get_is_nm_owned (NMDevice *self)
|
2014-05-20 16:39:57 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
|
2014-05-20 16:39:57 -05:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 16:56:29 -05:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_nm_owned (NMDevice *self)
|
2014-05-20 16:39:57 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2014-05-20 16:39:57 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
NM_DEVICE_GET_PRIVATE (self)->is_nm_owned = TRUE;
|
2014-05-20 16:39:57 -05:00
|
|
|
}
|
|
|
|
|
|
2013-08-07 11:41:40 +02:00
|
|
|
/*
|
|
|
|
|
* delete_on_deactivate_link_delete
|
|
|
|
|
*
|
|
|
|
|
* Function will be queued with g_idle_add to call
|
|
|
|
|
* nm_platform_link_delete for the underlying resources
|
|
|
|
|
* of the device.
|
|
|
|
|
*/
|
|
|
|
|
static gboolean
|
|
|
|
|
delete_on_deactivate_link_delete (gpointer user_data)
|
|
|
|
|
{
|
2014-03-05 22:20:14 +01:00
|
|
|
DeleteOnDeactivateData *data = user_data;
|
2014-02-12 23:54:26 +01:00
|
|
|
NMDevice *self = data->device;
|
2014-03-05 22:20:14 +01:00
|
|
|
|
|
|
|
|
if (data->device) {
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (data->device);
|
|
|
|
|
|
|
|
|
|
g_object_remove_weak_pointer (G_OBJECT (data->device), (void **) &data->device);
|
|
|
|
|
priv->delete_on_deactivate_data = NULL;
|
|
|
|
|
}
|
2013-08-07 11:41:40 +02:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)",
|
|
|
|
|
data->ifindex, data->idle_add_id);
|
2014-03-05 22:20:14 +01:00
|
|
|
nm_platform_link_delete (data->ifindex);
|
|
|
|
|
g_free (data);
|
2013-08-07 11:41:40 +02:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-03-05 22:20:14 +01:00
|
|
|
delete_on_deactivate_unschedule (NMDevice *self)
|
2013-08-07 11:41:40 +02:00
|
|
|
{
|
2014-03-05 22:20:14 +01:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->delete_on_deactivate_data) {
|
|
|
|
|
DeleteOnDeactivateData *data = priv->delete_on_deactivate_data;
|
|
|
|
|
|
|
|
|
|
priv->delete_on_deactivate_data = NULL;
|
|
|
|
|
|
|
|
|
|
g_source_remove (data->idle_add_id);
|
|
|
|
|
g_object_remove_weak_pointer (G_OBJECT (self), (void **) &data->device);
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "delete_on_deactivate: cancel cleanup and delete virtual link #%d (id=%u)",
|
|
|
|
|
data->ifindex, data->idle_add_id);
|
2014-03-05 22:20:14 +01:00
|
|
|
g_free (data);
|
2013-08-07 11:41:40 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
delete_on_deactivate_check_and_schedule (NMDevice *self, int ifindex)
|
|
|
|
|
{
|
2014-05-20 16:39:57 -05:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-03-05 22:20:14 +01:00
|
|
|
DeleteOnDeactivateData *data;
|
2013-08-07 11:41:40 +02:00
|
|
|
|
|
|
|
|
if (ifindex <= 0)
|
|
|
|
|
return;
|
2014-05-20 16:39:57 -05:00
|
|
|
if (!priv->is_nm_owned)
|
2013-08-07 11:41:40 +02:00
|
|
|
return;
|
|
|
|
|
if (!nm_device_is_software (self))
|
|
|
|
|
return;
|
|
|
|
|
if (nm_device_get_state (self) == NM_DEVICE_STATE_UNMANAGED)
|
|
|
|
|
return;
|
2013-12-03 09:37:58 +01:00
|
|
|
if (nm_device_get_state (self) == NM_DEVICE_STATE_UNAVAILABLE)
|
|
|
|
|
return;
|
2014-03-05 22:20:14 +01:00
|
|
|
delete_on_deactivate_unschedule (self); /* always cancel and reschedule */
|
|
|
|
|
|
|
|
|
|
data = g_new (DeleteOnDeactivateData, 1);
|
|
|
|
|
g_object_add_weak_pointer (G_OBJECT (self), (void **) &data->device);
|
|
|
|
|
data->device = self;
|
|
|
|
|
data->ifindex = ifindex;
|
|
|
|
|
data->idle_add_id = g_idle_add (delete_on_deactivate_link_delete, data);
|
|
|
|
|
priv->delete_on_deactivate_data = data;
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "delete_on_deactivate: schedule cleanup and delete virtual link #%d (id=%u)",
|
|
|
|
|
ifindex, data->idle_add_id);
|
2013-08-07 11:41:40 +02:00
|
|
|
}
|
|
|
|
|
|
2012-06-01 16:53:23 -05:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
disconnect_cb (NMDevice *self,
|
2012-06-01 16:53:23 -05:00
|
|
|
DBusGMethodInvocation *context,
|
|
|
|
|
GError *error,
|
|
|
|
|
gpointer user_data)
|
2009-09-16 13:18:24 +02:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2012-06-01 16:53:23 -05:00
|
|
|
GError *local = NULL;
|
2011-11-17 23:44:17 -06:00
|
|
|
|
2014-01-17 11:18:23 -06:00
|
|
|
if (error) {
|
2012-06-01 16:53:23 -05:00
|
|
|
dbus_g_method_return_error (context, error);
|
2014-01-17 11:18:23 -06:00
|
|
|
return;
|
|
|
|
|
}
|
2013-10-18 12:32:01 +02:00
|
|
|
|
2014-01-17 11:18:23 -06:00
|
|
|
/* Authorized */
|
|
|
|
|
if (priv->state <= NM_DEVICE_STATE_DISCONNECTED) {
|
|
|
|
|
local = g_error_new_literal (NM_DEVICE_ERROR,
|
|
|
|
|
NM_DEVICE_ERROR_NOT_ACTIVE,
|
|
|
|
|
"Device is not active");
|
|
|
|
|
dbus_g_method_return_error (context, local);
|
|
|
|
|
g_error_free (local);
|
|
|
|
|
} else {
|
|
|
|
|
priv->autoconnect = FALSE;
|
2013-10-18 12:32:01 +02:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_state_changed (self,
|
2014-01-03 13:58:05 -05:00
|
|
|
NM_DEVICE_STATE_DEACTIVATING,
|
2014-01-17 11:18:23 -06:00
|
|
|
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
|
|
|
|
dbus_g_method_return (context);
|
2011-11-17 23:44:17 -06:00
|
|
|
}
|
2009-09-16 13:18:24 +02:00
|
|
|
}
|
|
|
|
|
|
2011-11-18 00:34:08 -06:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
impl_device_disconnect (NMDevice *self, DBusGMethodInvocation *context)
|
2011-11-18 00:34:08 -06:00
|
|
|
{
|
2014-01-17 11:18:23 -06:00
|
|
|
NMConnection *connection;
|
2012-06-01 16:53:23 -05:00
|
|
|
GError *error = NULL;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (NM_DEVICE_GET_PRIVATE (self)->act_request == NULL) {
|
2012-06-01 16:53:23 -05:00
|
|
|
error = g_error_new_literal (NM_DEVICE_ERROR,
|
|
|
|
|
NM_DEVICE_ERROR_NOT_ACTIVE,
|
|
|
|
|
"This device is not active");
|
|
|
|
|
dbus_g_method_return_error (context, error);
|
|
|
|
|
g_error_free (error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
connection = nm_device_get_connection (self);
|
2014-01-17 11:18:23 -06:00
|
|
|
g_assert (connection);
|
|
|
|
|
|
2012-06-01 16:53:23 -05:00
|
|
|
/* Ask the manager to authenticate this request for us */
|
2014-07-15 13:36:24 +02:00
|
|
|
g_signal_emit (self, signals[AUTH_REQUEST], 0,
|
2012-06-01 16:53:23 -05:00
|
|
|
context,
|
2014-01-17 11:18:23 -06:00
|
|
|
connection,
|
2012-06-01 16:53:23 -05:00
|
|
|
NM_AUTH_PERMISSION_NETWORK_CONTROL,
|
|
|
|
|
TRUE,
|
|
|
|
|
disconnect_cb,
|
|
|
|
|
NULL);
|
2011-11-18 00:34:08 -06:00
|
|
|
}
|
|
|
|
|
|
2014-06-19 12:37:49 +02:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
delete_cb (NMDevice *self,
|
2014-06-19 12:37:49 +02:00
|
|
|
DBusGMethodInvocation *context,
|
|
|
|
|
GError *error,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
if (error) {
|
|
|
|
|
dbus_g_method_return_error (context, error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Authorized */
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_platform_link_delete (nm_device_get_ifindex (self));
|
2014-06-19 12:37:49 +02:00
|
|
|
dbus_g_method_return (context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
impl_device_delete (NMDevice *self, DBusGMethodInvocation *context)
|
2014-06-19 12:37:49 +02:00
|
|
|
{
|
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (!nm_device_is_software (self)) {
|
2014-06-19 12:37:49 +02:00
|
|
|
error = g_error_new_literal (NM_DEVICE_ERROR,
|
|
|
|
|
NM_DEVICE_ERROR_NOT_SOFTWARE,
|
|
|
|
|
"This device is not a software device");
|
|
|
|
|
dbus_g_method_return_error (context, error);
|
|
|
|
|
g_error_free (error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Ask the manager to authenticate this request for us */
|
2014-07-15 13:36:24 +02:00
|
|
|
g_signal_emit (self, signals[AUTH_REQUEST], 0,
|
2014-06-19 12:37:49 +02:00
|
|
|
context,
|
|
|
|
|
NULL,
|
|
|
|
|
NM_AUTH_PERMISSION_NETWORK_CONTROL,
|
|
|
|
|
TRUE,
|
|
|
|
|
delete_cb,
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
static void
|
|
|
|
|
_device_activate (NMDevice *self, NMActRequest *req)
|
2007-09-14 19:51:04 +00:00
|
|
|
{
|
2011-11-17 23:50:13 -06:00
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
|
2012-11-13 17:36:39 -06:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
|
|
|
|
g_return_if_fail (NM_IS_ACT_REQUEST (req));
|
2011-11-17 23:50:13 -06:00
|
|
|
|
|
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
connection = nm_act_request_get_connection (req);
|
|
|
|
|
g_assert (connection);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: starting connection '%s'",
|
|
|
|
|
nm_connection_get_id (connection));
|
2007-09-14 19:51:04 +00:00
|
|
|
|
2014-03-05 22:20:14 +01:00
|
|
|
delete_on_deactivate_unschedule (self);
|
2014-03-05 22:07:19 +01:00
|
|
|
|
2013-11-04 19:51:28 -06:00
|
|
|
/* Move default unmanaged devices to DISCONNECTED state here */
|
2014-03-31 21:45:54 -05:00
|
|
|
if (nm_device_get_default_unmanaged (self) && priv->state == NM_DEVICE_STATE_UNMANAGED) {
|
2013-11-04 19:51:28 -06:00
|
|
|
nm_device_state_changed (self,
|
|
|
|
|
NM_DEVICE_STATE_DISCONNECTED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_NOW_MANAGED);
|
2013-04-24 10:40:58 -04:00
|
|
|
}
|
|
|
|
|
|
2014-03-20 11:22:19 -05:00
|
|
|
/* note: don't notify D-Bus of the new AC here, but do it later when
|
|
|
|
|
* changing state to PREPARE so that the two properties change together.
|
|
|
|
|
*/
|
2007-10-01 15:38:39 +00:00
|
|
|
priv->act_request = g_object_ref (req);
|
2007-09-27 04:52:03 +00:00
|
|
|
|
2013-11-07 01:08:02 -06:00
|
|
|
nm_device_activate_schedule_stage1_device_prepare (self);
|
2007-09-14 19:51:04 +00:00
|
|
|
}
|
|
|
|
|
|
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 *self, NMActRequest *req)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (!priv->act_request) {
|
|
|
|
|
/* Just activate immediately */
|
|
|
|
|
_device_activate (self, req);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* supercede any already-queued request */
|
|
|
|
|
g_clear_object (&priv->queued_act_request);
|
|
|
|
|
priv->queued_act_request = g_object_ref (req);
|
|
|
|
|
|
|
|
|
|
/* Deactivate existing activation request first */
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "disconnecting for new activation request.");
|
core: queue re-activations to allow DEACTIVATING state
If a device is already activated, queue the new activation to allow
the transition through the DEACTIVATING state.
---
Also remove the "HACK" bits in nm_device_deactivate(). This hack was
added on 2007-09-25 in commit 9c2848d. At the time, with user settings
services, if a client created a connection and requested that NM
activate it, NM may not have read the connection from the client over
D-Bus yet. So NM created a "deferred" activation request which waited
until the connection was read from the client, and then began activation.
The Policy watched for device state changes and other events (like
it does now) and activated a new device if the old one was no longer
valid. It specifically checked for deferred activations and then
did nothing. However, when the client's connection was read, then
nm-device.c cleared the deferred activation bit, leading to a short
period of time where the device was in DISCONNECTED state but there
was no deferred activation, because the device only changes state to
PREPARE from the idle handler for stage1. If other events happened
during this time, the policy would tear down the device that was
about to be activated. This early state transition to PREPARE
worked around that.
We need to remove it now though, because (a) the reason for its
existence is no longer valid, and (b) _device_activate() may now
be called from inside nm_device_state_changed() and thus it cannot
change to a new state inside the function.
2014-02-17 17:16:08 -06:00
|
|
|
nm_device_state_changed (self,
|
|
|
|
|
NM_DEVICE_STATE_DEACTIVATING,
|
|
|
|
|
NM_DEVICE_STATE_REASON_NONE);
|
|
|
|
|
}
|
|
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
/*
|
|
|
|
|
* nm_device_is_activating
|
|
|
|
|
*
|
|
|
|
|
* Return whether or not the device is currently activating itself.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_is_activating (NMDevice *self)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2011-03-17 13:39:31 -05:00
|
|
|
NMDeviceState state;
|
2007-09-21 03:49:28 +00:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
state = nm_device_get_state (self);
|
2011-03-17 13:39:31 -05:00
|
|
|
if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_SECONDARIES)
|
2007-02-05 12:14:09 +00:00
|
|
|
return TRUE;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-09-21 03:49:28 +00:00
|
|
|
/* There's a small race between the time when stage 1 is scheduled
|
|
|
|
|
* and when the device actually sets STATE_PREPARE when the activation
|
|
|
|
|
* handler is actually run. If there's an activation handler scheduled
|
|
|
|
|
* we're activating anyway.
|
|
|
|
|
*/
|
2011-03-17 13:39:31 -05:00
|
|
|
return priv->act_source_id ? TRUE : FALSE;
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* IP Configuration stuff */
|
|
|
|
|
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
NMDhcp4Config *
|
2008-09-18 Dan Williams <dcbw@redhat.com>
Implement support for honoring configured and automatic hostnames, and for
setting the configured hostname.
* introspection/nm-ip4-config.xml
src/nm-ip4-config.c
src/nm-ip4-config.h
src/dhcp-manager/nm-dhcp-manager.c
- Remove useless hostname property; it's not really part of the IPv4
config
* introspection/nm-settings-system.xml
libnm-glib/nm-dbus-settings-system.c
libnm-glib/nm-dbus-settings-system.h
- Add SetHostname() call to system settings D-Bus interface
- Add Hostname property to system settings D-Bus interface
- (nm_dbus_settings_system_save_hostname,
nm_dbus_settings_system_get_hostname): implement
* src/nm-device.c
src/nm-device.h
- (nm_device_get_dhcp4_config): implement
* src/nm-manager.c
src/nm-manager.h
- Fetch and track system settings service hostname changes, and proxy
the changes via a GObject property of the manager
* system-settings/src/nm-system-config-interface.c
system-settings/src/nm-system-config-interface.h
- Replace nm_system_config_interface_supports_add() with a capabilities
bitfield
* system-settings/src/nm-system-config-error.c
system-settings/src/nm-system-config-error.h
- Add additional errors
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (get_property, nm_sysconfig_settings_class_init): add hostname
property; first plugin returning a hostname wins
- (impl_settings_add_connection): use plugin capabilities instead of
nm_system_config_interface_supports_add()
- (impl_settings_save_hostname): implement hostname saving
* src/NetworkManagerPolicy.c
- (lookup_thread_run_cb, lookup_thread_worker, lookup_thread_new,
lookup_thread_die): implement an asynchronous hostname lookup thread
which given an IPv4 address tries to look up the hostname for that
address with reverse DNS
- (get_best_device): split out best device code from
update_routing_and_dns()
- (update_etc_hosts): update /etc/hosts with the machine's new hostname
to preserve the 127.0.0.1 reverse mapping that so many things require
- (set_system_hostname): set a given hostname
- (update_system_hostname): implement hostname policy; a configured
hostname (from the system settings service) is used if available,
otherwise an automatically determined hostname from DHCP, VPN, etc.
If there was no automatically determined hostname, reverse DNS of
the best device's IP address will be used, and as a last resort the
hostname 'localhost.localdomain' is set.
- (update_routing_and_dns): use get_best_device(); update the system
hostname when the network config changes
- (hostname_changed): update system hostname if the system settings
service signals a hostname change
- (nm_policy_new): list for system settings service hostname changes
- (nm_policy_destroy): ensure that an in-progress hostname lookup thread
gets told to die
* system-settings/plugins/keyfile/plugin.c
system-settings/plugins/ifcfg-suse/plugin.c
- (get_property, sc_plugin_ifcfg_class_init): implement hostname and
capabilities properties
* system-settings/plugins/ifcfg-fedora/shvar.c
- (svOpenFile): re-enable R/W access of ifcfg files since the plugin
writes out /etc/sysconfig/network now
* system-settings/plugins/ifcfg-fedora/plugin.c
- (plugin_get_hostname): get hostname from /etc/sysconfig/network
- (plugin_set_hostname): save hostname to /etc/sysconfig/network
- (sc_network_changed_cb): handle changes to /etc/sysconfig/network
- (sc_plugin_ifcfg_init): monitor /etc/sysconfig/network for changes
- (get_property, set_property, sc_plugin_ifcfg_class_init): implement
hostname get/set and capabilities get
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4077 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-09-18 15:16:44 +00:00
|
|
|
nm_device_get_dhcp4_config (NMDevice *self)
|
|
|
|
|
{
|
2010-01-14 00:45:10 -08:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
2008-09-18 Dan Williams <dcbw@redhat.com>
Implement support for honoring configured and automatic hostnames, and for
setting the configured hostname.
* introspection/nm-ip4-config.xml
src/nm-ip4-config.c
src/nm-ip4-config.h
src/dhcp-manager/nm-dhcp-manager.c
- Remove useless hostname property; it's not really part of the IPv4
config
* introspection/nm-settings-system.xml
libnm-glib/nm-dbus-settings-system.c
libnm-glib/nm-dbus-settings-system.h
- Add SetHostname() call to system settings D-Bus interface
- Add Hostname property to system settings D-Bus interface
- (nm_dbus_settings_system_save_hostname,
nm_dbus_settings_system_get_hostname): implement
* src/nm-device.c
src/nm-device.h
- (nm_device_get_dhcp4_config): implement
* src/nm-manager.c
src/nm-manager.h
- Fetch and track system settings service hostname changes, and proxy
the changes via a GObject property of the manager
* system-settings/src/nm-system-config-interface.c
system-settings/src/nm-system-config-interface.h
- Replace nm_system_config_interface_supports_add() with a capabilities
bitfield
* system-settings/src/nm-system-config-error.c
system-settings/src/nm-system-config-error.h
- Add additional errors
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (get_property, nm_sysconfig_settings_class_init): add hostname
property; first plugin returning a hostname wins
- (impl_settings_add_connection): use plugin capabilities instead of
nm_system_config_interface_supports_add()
- (impl_settings_save_hostname): implement hostname saving
* src/NetworkManagerPolicy.c
- (lookup_thread_run_cb, lookup_thread_worker, lookup_thread_new,
lookup_thread_die): implement an asynchronous hostname lookup thread
which given an IPv4 address tries to look up the hostname for that
address with reverse DNS
- (get_best_device): split out best device code from
update_routing_and_dns()
- (update_etc_hosts): update /etc/hosts with the machine's new hostname
to preserve the 127.0.0.1 reverse mapping that so many things require
- (set_system_hostname): set a given hostname
- (update_system_hostname): implement hostname policy; a configured
hostname (from the system settings service) is used if available,
otherwise an automatically determined hostname from DHCP, VPN, etc.
If there was no automatically determined hostname, reverse DNS of
the best device's IP address will be used, and as a last resort the
hostname 'localhost.localdomain' is set.
- (update_routing_and_dns): use get_best_device(); update the system
hostname when the network config changes
- (hostname_changed): update system hostname if the system settings
service signals a hostname change
- (nm_policy_new): list for system settings service hostname changes
- (nm_policy_destroy): ensure that an in-progress hostname lookup thread
gets told to die
* system-settings/plugins/keyfile/plugin.c
system-settings/plugins/ifcfg-suse/plugin.c
- (get_property, sc_plugin_ifcfg_class_init): implement hostname and
capabilities properties
* system-settings/plugins/ifcfg-fedora/shvar.c
- (svOpenFile): re-enable R/W access of ifcfg files since the plugin
writes out /etc/sysconfig/network now
* system-settings/plugins/ifcfg-fedora/plugin.c
- (plugin_get_hostname): get hostname from /etc/sysconfig/network
- (plugin_set_hostname): save hostname to /etc/sysconfig/network
- (sc_network_changed_cb): handle changes to /etc/sysconfig/network
- (sc_plugin_ifcfg_init): monitor /etc/sysconfig/network for changes
- (get_property, set_property, sc_plugin_ifcfg_class_init): implement
hostname get/set and capabilities get
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4077 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-09-18 15:16:44 +00:00
|
|
|
|
2010-01-14 00:45:10 -08:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->dhcp4_config;
|
2008-09-18 Dan Williams <dcbw@redhat.com>
Implement support for honoring configured and automatic hostnames, and for
setting the configured hostname.
* introspection/nm-ip4-config.xml
src/nm-ip4-config.c
src/nm-ip4-config.h
src/dhcp-manager/nm-dhcp-manager.c
- Remove useless hostname property; it's not really part of the IPv4
config
* introspection/nm-settings-system.xml
libnm-glib/nm-dbus-settings-system.c
libnm-glib/nm-dbus-settings-system.h
- Add SetHostname() call to system settings D-Bus interface
- Add Hostname property to system settings D-Bus interface
- (nm_dbus_settings_system_save_hostname,
nm_dbus_settings_system_get_hostname): implement
* src/nm-device.c
src/nm-device.h
- (nm_device_get_dhcp4_config): implement
* src/nm-manager.c
src/nm-manager.h
- Fetch and track system settings service hostname changes, and proxy
the changes via a GObject property of the manager
* system-settings/src/nm-system-config-interface.c
system-settings/src/nm-system-config-interface.h
- Replace nm_system_config_interface_supports_add() with a capabilities
bitfield
* system-settings/src/nm-system-config-error.c
system-settings/src/nm-system-config-error.h
- Add additional errors
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- (get_property, nm_sysconfig_settings_class_init): add hostname
property; first plugin returning a hostname wins
- (impl_settings_add_connection): use plugin capabilities instead of
nm_system_config_interface_supports_add()
- (impl_settings_save_hostname): implement hostname saving
* src/NetworkManagerPolicy.c
- (lookup_thread_run_cb, lookup_thread_worker, lookup_thread_new,
lookup_thread_die): implement an asynchronous hostname lookup thread
which given an IPv4 address tries to look up the hostname for that
address with reverse DNS
- (get_best_device): split out best device code from
update_routing_and_dns()
- (update_etc_hosts): update /etc/hosts with the machine's new hostname
to preserve the 127.0.0.1 reverse mapping that so many things require
- (set_system_hostname): set a given hostname
- (update_system_hostname): implement hostname policy; a configured
hostname (from the system settings service) is used if available,
otherwise an automatically determined hostname from DHCP, VPN, etc.
If there was no automatically determined hostname, reverse DNS of
the best device's IP address will be used, and as a last resort the
hostname 'localhost.localdomain' is set.
- (update_routing_and_dns): use get_best_device(); update the system
hostname when the network config changes
- (hostname_changed): update system hostname if the system settings
service signals a hostname change
- (nm_policy_new): list for system settings service hostname changes
- (nm_policy_destroy): ensure that an in-progress hostname lookup thread
gets told to die
* system-settings/plugins/keyfile/plugin.c
system-settings/plugins/ifcfg-suse/plugin.c
- (get_property, sc_plugin_ifcfg_class_init): implement hostname and
capabilities properties
* system-settings/plugins/ifcfg-fedora/shvar.c
- (svOpenFile): re-enable R/W access of ifcfg files since the plugin
writes out /etc/sysconfig/network now
* system-settings/plugins/ifcfg-fedora/plugin.c
- (plugin_get_hostname): get hostname from /etc/sysconfig/network
- (plugin_set_hostname): save hostname to /etc/sysconfig/network
- (sc_network_changed_cb): handle changes to /etc/sysconfig/network
- (sc_plugin_ifcfg_init): monitor /etc/sysconfig/network for changes
- (get_property, set_property, sc_plugin_ifcfg_class_init): implement
hostname get/set and capabilities get
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4077 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-09-18 15:16:44 +00:00
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
|
|
|
|
NMIP4Config *
|
|
|
|
|
nm_device_get_ip4_config (NMDevice *self)
|
|
|
|
|
{
|
2010-01-14 00:45:10 -08:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2008-03-11 22:26:46 +00:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->ip4_config;
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-11-07 13:57:39 +00:00
|
|
|
static gboolean
|
|
|
|
|
nm_device_set_ip4_config (NMDevice *self,
|
|
|
|
|
NMIP4Config *new_config,
|
2013-06-26 00:16:45 +02:00
|
|
|
gboolean commit,
|
2008-11-07 13:57:39 +00:00
|
|
|
NMDeviceStateReason *reason)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2007-12-06 14:51:43 +00:00
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
const char *ip_iface;
|
2008-11-07 13:57:39 +00:00
|
|
|
NMIP4Config *old_config = NULL;
|
2013-09-06 11:56:41 +02:00
|
|
|
gboolean has_changes = FALSE;
|
2008-11-07 13:57:39 +00:00
|
|
|
gboolean success = TRUE;
|
2013-09-06 11:56:41 +02:00
|
|
|
NMDeviceStateReason reason_local = NM_DEVICE_STATE_REASON_NONE;
|
2011-07-22 14:09:16 -05:00
|
|
|
int ip_ifindex;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2007-12-06 14:51:43 +00:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
|
|
|
|
|
|
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
2008-08-12 08:05:16 +00:00
|
|
|
ip_iface = nm_device_get_ip_iface (self);
|
2012-05-29 09:56:50 -05:00
|
|
|
ip_ifindex = nm_device_get_ip_ifindex (self);
|
2007-02-16 11:23:49 +00:00
|
|
|
|
2008-11-07 13:57:39 +00:00
|
|
|
old_config = priv->ip4_config;
|
2008-03-11 02:46:35 +00:00
|
|
|
|
2013-07-02 22:22:57 +02:00
|
|
|
/* Always commit to nm-platform to update lifetimes */
|
2013-09-06 11:56:41 +02:00
|
|
|
if (commit && new_config) {
|
2014-06-04 11:14:55 -04:00
|
|
|
success = nm_ip4_config_commit (new_config, ip_ifindex);
|
2013-09-06 11:56:41 +02:00
|
|
|
if (!success)
|
|
|
|
|
reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
|
|
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2008-11-07 13:57:39 +00:00
|
|
|
if (new_config) {
|
2013-09-06 11:56:41 +02:00
|
|
|
if (old_config) {
|
|
|
|
|
/* has_changes is set only on relevant changes, because when the configuration changes,
|
|
|
|
|
* this causes a re-read and reset. This should only happen for relevant changes */
|
|
|
|
|
nm_ip4_config_replace (old_config, new_config, &has_changes);
|
|
|
|
|
if (has_changes) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_IP4, "update IP4Config instance (%s)",
|
|
|
|
|
nm_ip4_config_get_dbus_path (old_config));
|
2013-09-06 11:56:41 +02:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
has_changes = TRUE;
|
|
|
|
|
priv->ip4_config = g_object_ref (new_config);
|
2007-12-06 14:51:43 +00:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
if (success && !nm_ip4_config_get_dbus_path (new_config)) {
|
|
|
|
|
/* Export over D-Bus */
|
2008-11-07 13:57:39 +00:00
|
|
|
nm_ip4_config_export (new_config);
|
2013-09-06 11:56:41 +02:00
|
|
|
}
|
2014-03-17 20:36:48 +01:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_IP4, "set IP4Config instance (%s)",
|
|
|
|
|
nm_ip4_config_get_dbus_path (new_config));
|
2008-11-07 13:57:39 +00:00
|
|
|
}
|
2013-09-06 11:56:41 +02:00
|
|
|
} else if (old_config) {
|
|
|
|
|
has_changes = TRUE;
|
|
|
|
|
priv->ip4_config = NULL;
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_IP4, "clear IP4Config instance (%s)",
|
|
|
|
|
nm_ip4_config_get_dbus_path (old_config));
|
2013-08-01 10:34:46 -05:00
|
|
|
/* Device config is invalid if combined config is invalid */
|
|
|
|
|
g_clear_object (&priv->dev_ip4_config);
|
2008-11-07 13:57:39 +00:00
|
|
|
}
|
2007-12-06 14:51:43 +00:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
if (has_changes) {
|
|
|
|
|
_update_ip4_address (self);
|
|
|
|
|
|
|
|
|
|
if (old_config != priv->ip4_config)
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_IP4_CONFIG);
|
|
|
|
|
g_signal_emit (self, signals[IP4_CONFIG_CHANGED], 0, priv->ip4_config, old_config);
|
|
|
|
|
|
|
|
|
|
if (old_config != priv->ip4_config && old_config)
|
|
|
|
|
g_object_unref (old_config);
|
2014-05-27 16:42:19 -04:00
|
|
|
|
|
|
|
|
if (nm_device_uses_generated_connection (self)) {
|
|
|
|
|
NMConnection *connection = nm_device_get_connection (self);
|
|
|
|
|
NMSetting *s_ip4;
|
|
|
|
|
|
|
|
|
|
g_object_freeze_notify (G_OBJECT (connection));
|
|
|
|
|
nm_connection_remove_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
|
|
|
|
s_ip4 = nm_ip4_config_create_setting (priv->ip4_config);
|
|
|
|
|
nm_connection_add_setting (connection, s_ip4);
|
|
|
|
|
g_object_thaw_notify (G_OBJECT (connection));
|
|
|
|
|
}
|
2014-05-28 10:18:34 -04:00
|
|
|
|
|
|
|
|
nm_device_queue_recheck_assume (self);
|
2013-09-06 11:56:41 +02:00
|
|
|
}
|
2012-05-29 09:56:50 -05:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
if (reason)
|
|
|
|
|
*reason = reason_local;
|
2008-03-11 22:26:46 +00:00
|
|
|
|
2007-12-06 14:51:43 +00:00
|
|
|
return success;
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2013-08-01 10:59:42 -05:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_vpn4_config (NMDevice *self, NMIP4Config *config)
|
2013-08-01 10:59:42 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-08-01 10:59:42 -05:00
|
|
|
|
|
|
|
|
if (priv->vpn4_config == config)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_clear_object (&priv->vpn4_config);
|
|
|
|
|
if (config)
|
|
|
|
|
priv->vpn4_config = g_object_ref (config);
|
|
|
|
|
|
|
|
|
|
/* NULL to use existing configs */
|
2014-02-12 23:54:26 +01:00
|
|
|
if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL))
|
|
|
|
|
_LOGW (LOGD_IP4, "failed to set VPN routes for device");
|
2013-08-01 10:59:42 -05:00
|
|
|
}
|
|
|
|
|
|
2014-07-15 17:16:56 -05:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_wwan_ip4_config (NMDevice *self, NMIP4Config *config)
|
2014-07-15 17:16:56 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-07-15 17:16:56 -05:00
|
|
|
|
|
|
|
|
if (priv->wwan_ip4_config == config)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_clear_object (&priv->wwan_ip4_config);
|
|
|
|
|
if (config)
|
|
|
|
|
priv->wwan_ip4_config = g_object_ref (config);
|
|
|
|
|
|
|
|
|
|
/* NULL to use existing configs */
|
2014-02-12 23:54:26 +01:00
|
|
|
if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL))
|
|
|
|
|
_LOGW (LOGD_IP4, "failed to set WWAN IPv4 configuration");
|
2014-07-15 17:16:56 -05:00
|
|
|
}
|
|
|
|
|
|
2009-07-29 12:12:41 -04:00
|
|
|
static gboolean
|
|
|
|
|
nm_device_set_ip6_config (NMDevice *self,
|
|
|
|
|
NMIP6Config *new_config,
|
2013-06-26 00:16:45 +02:00
|
|
|
gboolean commit,
|
2009-07-29 12:12:41 -04:00
|
|
|
NMDeviceStateReason *reason)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
const char *ip_iface;
|
|
|
|
|
NMIP6Config *old_config = NULL;
|
2013-09-06 11:56:41 +02:00
|
|
|
gboolean has_changes = FALSE;
|
2009-07-29 12:12:41 -04:00
|
|
|
gboolean success = TRUE;
|
2013-09-06 11:56:41 +02:00
|
|
|
NMDeviceStateReason reason_local = NM_DEVICE_STATE_REASON_NONE;
|
2011-07-22 14:24:18 -05:00
|
|
|
int ip_ifindex;
|
2009-07-29 12:12:41 -04:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
|
|
|
|
|
|
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
ip_iface = nm_device_get_ip_iface (self);
|
2011-07-22 14:24:18 -05:00
|
|
|
ip_ifindex = nm_device_get_ip_ifindex (self);
|
2009-07-29 12:12:41 -04:00
|
|
|
|
|
|
|
|
old_config = priv->ip6_config;
|
|
|
|
|
|
2013-07-02 22:22:57 +02:00
|
|
|
/* Always commit to nm-platform to update lifetimes */
|
2013-09-06 11:56:41 +02:00
|
|
|
if (commit && new_config) {
|
2014-06-04 11:14:55 -04:00
|
|
|
success = nm_ip6_config_commit (new_config, ip_ifindex);
|
2013-09-06 11:56:41 +02:00
|
|
|
if (!success)
|
|
|
|
|
reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
|
|
|
|
|
}
|
2009-07-29 12:12:41 -04:00
|
|
|
|
|
|
|
|
if (new_config) {
|
2013-09-06 11:56:41 +02:00
|
|
|
if (old_config) {
|
|
|
|
|
/* has_changes is set only on relevant changes, because when the configuration changes,
|
|
|
|
|
* this causes a re-read and reset. This should only happen for relevant changes */
|
|
|
|
|
nm_ip6_config_replace (old_config, new_config, &has_changes);
|
|
|
|
|
if (has_changes) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_IP6, "update IP6Config instance (%s)",
|
|
|
|
|
nm_ip6_config_get_dbus_path (old_config));
|
2013-09-06 11:56:41 +02:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
has_changes = TRUE;
|
|
|
|
|
priv->ip6_config = g_object_ref (new_config);
|
2009-07-29 12:12:41 -04:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
if (success && !nm_ip6_config_get_dbus_path (new_config)) {
|
|
|
|
|
/* Export over D-Bus */
|
2009-07-29 12:12:41 -04:00
|
|
|
nm_ip6_config_export (new_config);
|
2013-09-06 11:56:41 +02:00
|
|
|
}
|
2014-03-17 20:36:48 +01:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_IP4, "set IP6Config instance (%s)",
|
|
|
|
|
nm_ip6_config_get_dbus_path (new_config));
|
2009-07-29 12:12:41 -04:00
|
|
|
}
|
2013-09-06 11:56:41 +02:00
|
|
|
} else if (old_config) {
|
|
|
|
|
has_changes = TRUE;
|
|
|
|
|
priv->ip6_config = NULL;
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_IP6, "clear IP6Config instance (%s)",
|
|
|
|
|
nm_ip6_config_get_dbus_path (old_config));
|
2009-07-29 12:12:41 -04:00
|
|
|
}
|
|
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
if (has_changes) {
|
|
|
|
|
if (old_config != priv->ip6_config)
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_IP6_CONFIG);
|
|
|
|
|
g_signal_emit (self, signals[IP6_CONFIG_CHANGED], 0, priv->ip6_config, old_config);
|
|
|
|
|
|
|
|
|
|
if (old_config != priv->ip6_config && old_config)
|
|
|
|
|
g_object_unref (old_config);
|
2014-05-27 16:42:19 -04:00
|
|
|
|
|
|
|
|
if (nm_device_uses_generated_connection (self)) {
|
|
|
|
|
NMConnection *connection = nm_device_get_connection (self);
|
|
|
|
|
NMSetting *s_ip6;
|
|
|
|
|
|
|
|
|
|
g_object_freeze_notify (G_OBJECT (connection));
|
|
|
|
|
nm_connection_remove_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
|
|
|
|
s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
|
|
|
|
|
nm_connection_add_setting (connection, s_ip6);
|
|
|
|
|
g_object_thaw_notify (G_OBJECT (connection));
|
|
|
|
|
}
|
2014-05-28 10:18:34 -04:00
|
|
|
|
|
|
|
|
nm_device_queue_recheck_assume (self);
|
2013-09-06 11:56:41 +02:00
|
|
|
}
|
2012-05-29 09:56:50 -05:00
|
|
|
|
2013-09-06 11:56:41 +02:00
|
|
|
if (reason)
|
|
|
|
|
*reason = reason_local;
|
2009-07-29 12:12:41 -04:00
|
|
|
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-01 10:59:42 -05:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_vpn6_config (NMDevice *self, NMIP6Config *config)
|
2013-08-01 10:59:42 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-08-01 10:59:42 -05:00
|
|
|
|
|
|
|
|
if (priv->vpn6_config == config)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_clear_object (&priv->vpn6_config);
|
|
|
|
|
if (config)
|
|
|
|
|
priv->vpn6_config = g_object_ref (config);
|
|
|
|
|
|
|
|
|
|
/* NULL to use existing configs */
|
2014-02-12 23:54:26 +01:00
|
|
|
if (!ip6_config_merge_and_apply (self, TRUE, NULL))
|
|
|
|
|
_LOGW (LOGD_IP6, "failed to set VPN routes for device");
|
2013-08-01 10:59:42 -05:00
|
|
|
}
|
|
|
|
|
|
2013-10-15 21:03:42 -05:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_wwan_ip6_config (NMDevice *self, NMIP6Config *config)
|
2013-10-15 21:03:42 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-10-15 21:03:42 -05:00
|
|
|
|
|
|
|
|
if (priv->wwan_ip6_config == config)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_clear_object (&priv->wwan_ip6_config);
|
|
|
|
|
if (config)
|
|
|
|
|
priv->wwan_ip6_config = g_object_ref (config);
|
|
|
|
|
|
|
|
|
|
/* NULL to use existing configs */
|
2014-02-12 23:54:26 +01:00
|
|
|
if (!ip6_config_merge_and_apply (self, TRUE, NULL))
|
|
|
|
|
_LOGW (LOGD_IP6, "failed to set WWAN IPv6 configuration");
|
2013-10-15 21:03:42 -05:00
|
|
|
}
|
|
|
|
|
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
NMDhcp6Config *
|
2010-01-14 00:45:10 -08:00
|
|
|
nm_device_get_dhcp6_config (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
|
|
|
|
|
|
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->dhcp6_config;
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-29 12:12:41 -04:00
|
|
|
NMIP6Config *
|
|
|
|
|
nm_device_get_ip6_config (NMDevice *self)
|
|
|
|
|
{
|
2010-01-14 00:45:10 -08:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
2009-07-29 12:12:41 -04:00
|
|
|
|
|
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->ip6_config;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-11 17:05:49 -05:00
|
|
|
/****************************************************************/
|
|
|
|
|
|
2014-06-12 14:04:42 +02:00
|
|
|
static void
|
|
|
|
|
dispatcher_cleanup (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
2014-06-12 14:20:14 +02:00
|
|
|
if (priv->dispatcher.call_id) {
|
|
|
|
|
nm_dispatcher_call_cancel (priv->dispatcher.call_id);
|
|
|
|
|
priv->dispatcher.call_id = 0;
|
|
|
|
|
priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN;
|
|
|
|
|
priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
|
2014-06-12 14:04:42 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-21 12:49:23 -05:00
|
|
|
static void
|
2014-06-12 14:20:14 +02:00
|
|
|
dispatcher_complete_proceed_state (guint call_id, gpointer user_data)
|
2014-05-21 12:49:23 -05:00
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
2014-06-12 14:20:14 +02:00
|
|
|
g_return_if_fail (call_id == priv->dispatcher.call_id);
|
2014-05-21 12:49:23 -05:00
|
|
|
|
2014-06-12 14:20:14 +02:00
|
|
|
priv->dispatcher.call_id = 0;
|
|
|
|
|
nm_device_queue_state (self, priv->dispatcher.post_state,
|
|
|
|
|
priv->dispatcher.post_state_reason);
|
|
|
|
|
priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN;
|
|
|
|
|
priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
|
2014-05-21 12:49:23 -05:00
|
|
|
}
|
|
|
|
|
|
2014-06-12 14:20:14 +02:00
|
|
|
/****************************************************************/
|
|
|
|
|
|
2014-05-21 12:49:23 -05:00
|
|
|
static void
|
|
|
|
|
ip_check_pre_up (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
2014-06-12 14:20:14 +02:00
|
|
|
if (priv->dispatcher.call_id != 0) {
|
|
|
|
|
g_warn_if_reached ();
|
|
|
|
|
dispatcher_cleanup (self);
|
|
|
|
|
}
|
2014-05-21 12:49:23 -05:00
|
|
|
|
2014-06-12 14:20:14 +02:00
|
|
|
priv->dispatcher.post_state = NM_DEVICE_STATE_SECONDARIES;
|
|
|
|
|
priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
|
2014-05-21 12:49:23 -05:00
|
|
|
if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_UP,
|
|
|
|
|
nm_device_get_connection (self),
|
|
|
|
|
self,
|
2014-06-12 14:20:14 +02:00
|
|
|
dispatcher_complete_proceed_state,
|
2014-05-21 12:49:23 -05:00
|
|
|
self,
|
2014-06-12 14:20:14 +02:00
|
|
|
&priv->dispatcher.call_id)) {
|
2014-05-21 12:49:23 -05:00
|
|
|
/* Just proceed on errors */
|
2014-06-12 14:20:14 +02:00
|
|
|
dispatcher_complete_proceed_state (0, self);
|
2014-05-21 12:49:23 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-11 17:05:49 -05:00
|
|
|
static void
|
|
|
|
|
ip_check_gw_ping_cleanup (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
if (priv->gw_ping.watch) {
|
|
|
|
|
g_source_remove (priv->gw_ping.watch);
|
|
|
|
|
priv->gw_ping.watch = 0;
|
|
|
|
|
}
|
|
|
|
|
if (priv->gw_ping.timeout) {
|
|
|
|
|
g_source_remove (priv->gw_ping.timeout);
|
|
|
|
|
priv->gw_ping.timeout = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (priv->gw_ping.pid) {
|
2014-02-14 11:58:06 +01:00
|
|
|
nm_utils_kill_child_async (priv->gw_ping.pid, SIGTERM, priv->gw_ping.log_domain, "ping", 1000, NULL, NULL);
|
2013-06-11 17:05:49 -05:00
|
|
|
priv->gw_ping.pid = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
guint log_domain = priv->gw_ping.log_domain;
|
|
|
|
|
|
|
|
|
|
if (!priv->gw_ping.watch)
|
|
|
|
|
return;
|
|
|
|
|
priv->gw_ping.watch = 0;
|
|
|
|
|
priv->gw_ping.pid = 0;
|
|
|
|
|
|
|
|
|
|
if (WIFEXITED (status)) {
|
|
|
|
|
if (WEXITSTATUS (status) == 0)
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (log_domain, "ping: gateway ping succeeded");
|
2013-06-11 17:05:49 -05:00
|
|
|
else {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (log_domain, "ping: gateway ping failed with error code %d",
|
|
|
|
|
WEXITSTATUS (status));
|
2013-06-11 17:05:49 -05:00
|
|
|
}
|
|
|
|
|
} else
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (log_domain, "ping: stopped unexpectedly with status %d", status);
|
2013-06-11 17:05:49 -05:00
|
|
|
|
2014-05-21 12:49:23 -05:00
|
|
|
/* We've got connectivity, proceed to pre_up */
|
2013-06-11 17:05:49 -05:00
|
|
|
ip_check_gw_ping_cleanup (self);
|
2014-05-21 12:49:23 -05:00
|
|
|
ip_check_pre_up (self);
|
2013-06-11 17:05:49 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
ip_check_ping_timeout_cb (gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
priv->gw_ping.timeout = 0;
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (priv->gw_ping.log_domain, "ping: gateway ping timed out");
|
2013-06-11 17:05:49 -05:00
|
|
|
|
|
|
|
|
ip_check_gw_ping_cleanup (self);
|
2014-05-21 12:49:23 -05:00
|
|
|
ip_check_pre_up (self);
|
2013-06-11 17:05:49 -05:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
spawn_ping (NMDevice *self,
|
|
|
|
|
guint log_domain,
|
|
|
|
|
const char *binary,
|
|
|
|
|
const char *address,
|
|
|
|
|
guint timeout)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
const char *args[] = { binary, "-I", nm_device_get_ip_iface (self), "-c", "1", "-w", NULL, address, NULL };
|
|
|
|
|
GError *error = NULL;
|
2014-02-12 23:54:26 +01:00
|
|
|
char *str_timeout;
|
|
|
|
|
gs_free char *tmp_str = NULL;
|
2013-06-11 17:05:49 -05:00
|
|
|
gboolean success;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (priv->gw_ping.watch == 0, FALSE);
|
|
|
|
|
g_return_val_if_fail (priv->gw_ping.timeout == 0, FALSE);
|
|
|
|
|
|
|
|
|
|
args[6] = str_timeout = g_strdup_printf ("%u", timeout);
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (log_domain, "ping: running '%s'",
|
|
|
|
|
(tmp_str = g_strjoinv (" ", (gchar **) args)));
|
2013-06-11 17:05:49 -05:00
|
|
|
|
|
|
|
|
success = g_spawn_async ("/",
|
|
|
|
|
(gchar **) args,
|
|
|
|
|
NULL,
|
|
|
|
|
G_SPAWN_DO_NOT_REAP_CHILD,
|
|
|
|
|
nm_unblock_posix_signals,
|
|
|
|
|
NULL,
|
|
|
|
|
&priv->gw_ping.pid,
|
|
|
|
|
&error);
|
|
|
|
|
if (success) {
|
|
|
|
|
priv->gw_ping.log_domain = log_domain;
|
|
|
|
|
priv->gw_ping.watch = g_child_watch_add (priv->gw_ping.pid, ip_check_ping_watch_cb, self);
|
|
|
|
|
priv->gw_ping.timeout = g_timeout_add_seconds (timeout + 1, ip_check_ping_timeout_cb, self);
|
|
|
|
|
} else {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (log_domain, "ping: could not spawn %s: %s", binary, error->message);
|
2013-06-11 17:05:49 -05:00
|
|
|
g_clear_error (&error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_free (str_timeout);
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
nm_device_start_ip_check (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
guint timeout = 0;
|
|
|
|
|
const char *ping_binary = NULL;
|
|
|
|
|
char buf[INET6_ADDRSTRLEN] = { 0 };
|
|
|
|
|
guint log_domain = LOGD_IP4;
|
|
|
|
|
|
|
|
|
|
/* Shouldn't be any active ping here, since IP_CHECK happens after the
|
|
|
|
|
* first IP method completes. Any subsequently completing IP method doesn't
|
|
|
|
|
* get checked.
|
|
|
|
|
*/
|
|
|
|
|
g_assert (!priv->gw_ping.watch);
|
|
|
|
|
g_assert (!priv->gw_ping.timeout);
|
|
|
|
|
g_assert (!priv->gw_ping.pid);
|
|
|
|
|
g_assert (priv->ip4_state == IP_DONE || priv->ip6_state == IP_DONE);
|
|
|
|
|
|
|
|
|
|
connection = nm_device_get_connection (self);
|
|
|
|
|
g_assert (connection);
|
|
|
|
|
|
|
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
timeout = nm_setting_connection_get_gateway_ping_timeout (s_con);
|
|
|
|
|
|
|
|
|
|
if (timeout) {
|
2013-06-27 17:51:24 +02:00
|
|
|
if (priv->ip4_state == IP_DONE) {
|
2013-06-11 17:05:49 -05:00
|
|
|
guint gw = 0;
|
|
|
|
|
|
|
|
|
|
ping_binary = "/usr/bin/ping";
|
|
|
|
|
log_domain = LOGD_IP4;
|
|
|
|
|
|
|
|
|
|
gw = nm_ip4_config_get_gateway (priv->ip4_config);
|
|
|
|
|
if (gw && !inet_ntop (AF_INET, &gw, buf, sizeof (buf)))
|
|
|
|
|
buf[0] = '\0';
|
|
|
|
|
} else if (priv->ip6_config && priv->ip6_state == IP_DONE) {
|
|
|
|
|
const struct in6_addr *gw = NULL;
|
|
|
|
|
|
|
|
|
|
ping_binary = "/usr/bin/ping6";
|
|
|
|
|
log_domain = LOGD_IP6;
|
|
|
|
|
|
|
|
|
|
gw = nm_ip6_config_get_gateway (priv->ip6_config);
|
|
|
|
|
if (gw && !inet_ntop (AF_INET6, gw, buf, sizeof (buf)))
|
|
|
|
|
buf[0] = '\0';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (buf[0])
|
|
|
|
|
spawn_ping (self, log_domain, ping_binary, buf, timeout);
|
|
|
|
|
|
2014-05-21 12:49:23 -05:00
|
|
|
/* If no ping was started, just advance to pre_up */
|
2013-06-11 17:05:49 -05:00
|
|
|
if (!priv->gw_ping.pid)
|
2014-05-21 12:49:23 -05:00
|
|
|
ip_check_pre_up (self);
|
2013-06-11 17:05:49 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/****************************************************************/
|
|
|
|
|
|
2013-12-09 16:32:36 -06:00
|
|
|
static gboolean
|
|
|
|
|
carrier_wait_timeout (gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
|
|
|
|
|
NM_DEVICE_GET_PRIVATE (self)->carrier_wait_id = 0;
|
2014-04-28 11:18:05 +02:00
|
|
|
nm_device_remove_pending_action (self, "carrier wait", TRUE);
|
2013-12-09 16:32:36 -06:00
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-20 16:09:22 -05:00
|
|
|
static gboolean
|
|
|
|
|
nm_device_is_up (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
|
|
|
|
|
|
|
|
|
if (NM_DEVICE_GET_CLASS (self)->is_up)
|
|
|
|
|
return NM_DEVICE_GET_CLASS (self)->is_up (self);
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
is_up (NMDevice *self)
|
2014-05-20 16:09:22 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
int ifindex = nm_device_get_ip_ifindex (self);
|
2014-05-20 16:09:22 -05:00
|
|
|
|
|
|
|
|
return ifindex > 0 ? nm_platform_link_is_up (ifindex) : TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-05-14 01:55:49 +00:00
|
|
|
gboolean
|
2013-06-13 15:13:58 -05:00
|
|
|
nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2013-12-09 16:32:36 -06:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-02-11 14:00:20 +01:00
|
|
|
gboolean device_is_up = FALSE;
|
2007-03-12 04:49:29 +00:00
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_HW, "bringing up device.");
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2013-06-13 15:13:58 -05:00
|
|
|
if (NM_DEVICE_GET_CLASS (self)->bring_up) {
|
2014-02-11 14:00:20 +01:00
|
|
|
if (!NM_DEVICE_GET_CLASS (self)->bring_up (self, no_firmware))
|
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
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-11 14:00:20 +01:00
|
|
|
device_is_up = nm_device_is_up (self);
|
|
|
|
|
if (block && !device_is_up) {
|
|
|
|
|
int ifindex = nm_device_get_ip_ifindex (self);
|
|
|
|
|
gint64 wait_until = nm_utils_get_monotonic_timestamp_us () + 10000 /* microseconds */;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
g_usleep (200);
|
|
|
|
|
if (!nm_platform_link_refresh (ifindex))
|
|
|
|
|
return FALSE;
|
|
|
|
|
device_is_up = nm_device_is_up (self);
|
|
|
|
|
} while (!device_is_up && nm_utils_get_monotonic_timestamp_us () < wait_until);
|
|
|
|
|
}
|
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
|
|
|
|
2014-02-11 14:00:20 +01:00
|
|
|
if (!device_is_up) {
|
|
|
|
|
if (block)
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_HW, "device not up after timeout!");
|
2014-02-11 14:00:20 +01:00
|
|
|
else
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_HW, "device not up immediately");
|
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
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-09 16:32:36 -06:00
|
|
|
/* Devices that support carrier detect must be IFF_UP to report carrier
|
|
|
|
|
* changes; so after setting the device IFF_UP we must suppress startup
|
|
|
|
|
* complete (via a pending action) until either the carrier turns on, or
|
|
|
|
|
* a timeout is reached.
|
|
|
|
|
*/
|
|
|
|
|
if (device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
|
|
|
|
|
if (priv->carrier_wait_id) {
|
|
|
|
|
g_source_remove (priv->carrier_wait_id);
|
2014-04-28 11:18:05 +02:00
|
|
|
nm_device_remove_pending_action (self, "carrier wait", TRUE);
|
2013-12-09 16:32:36 -06:00
|
|
|
}
|
|
|
|
|
priv->carrier_wait_id = g_timeout_add_seconds (5, carrier_wait_timeout, self);
|
2014-04-28 11:18:05 +02:00
|
|
|
nm_device_add_pending_action (self, "carrier wait", TRUE);
|
2013-12-09 16:32:36 -06:00
|
|
|
}
|
|
|
|
|
|
2008-04-07 Dan Williams <dcbw@redhat.com>
* include/NetworkManager.h
- Remove the DOWN and CANCELLED device states
- Add UNMANAGED and UNAVAILABLE device states
- Document the device states
* introspection/nm-device.xml
src/nm-device-interface.c
src/nm-device-interface.h
- Add the 'managed' property
* test/nm-tool.c
- (detail_device): print out device state
* src/NetworkManagerSystem.h
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerDebian.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerMandriva.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerSuSE.c
- (nm_system_device_get_system_config, nm_system_device_get_disabled
nm_system_device_free_system_config): remove; they were unused and
their functionality should be re-implemented in each distro's
system settings service plugin
* src/nm-gsm-device.c
src/nm-gsm-device.h
src/nm-cdma-device.c
src/nm-cdma-device.h
- (*_new): take the 'managed' argument
* src/nm-device.c
- (nm_device_set_address): remove, fold into nm_device_bring_up()
- (nm_device_init): start in unmanaged state, not disconnected
- (constructor): don't start device until the system settings service
has had a chance to figure out if the device is managed or not
- (nm_device_deactivate, nm_device_bring_up, nm_device_bring_down):
don't set device state here, let callers handle that as appropriate
- (nm_device_dispose): don't touch the device if it's not managed
- (set_property, get_property, nm_device_class_init): implement the
'managed' property
- (nm_device_state_changed): bring the device up if its now managed,
and deactivate it if it used to be active
- (nm_device_get_managed, nm_device_set_managed): do the right thing
with the managed state
* src/nm-hal-manager.c
- (wired_device_creator, wireless_device_creator, modem_device_creator):
take initial managed state and pass it along to device constructors
- (create_device_and_add_to_list): get managed state and pass to
type creators
* src/nm-device-802-11-wireless.c
- (real_can_activate): fold in most of
nm_device_802_11_wireless_can_activate()
- (can_scan): can't scan in UNAVAILABLE or UNMANAGED
- (link_timeout_cb): instead of deactivating, change device state and
let the device state handler to it
- (real_update_hw_address): clean up
- (state_changed_cb): when entering UNAVAILABLE state, schedule an idle
handler to transition to DISCONNECTED if the device isn't rfkilled
* src/nm-device-802-3-ethernet.c
- (set_carrier): move above callers and get rid of prototype
- (device_state_changed): when entering UNAVAILABLE state, schedule an
idle handler to transition to DISCONNECTED if the device has a
carrier
- (real_update_hw_address): clean up
- (link_timeout_cb, ppp_state_changed): change state instead of calling
deactivation directly as deactivation doesn't change state anymore
* src/NetworkManagerPolicy.c
- (schedule_activate_check): yay, remove wireless_enabled hack since
the NMManager and wireless devices work that out themselves now
- (device_state_changed): change to a switch and update for new device
states
- (device_carrier_changed): remove; device handles this now through
state changes
- (device_added): don't care about carrier any more; the initial
activation check will happen when the device transitions to
DISCONNECTED
* src/nm-manager.c
- (dispose): clear unmanaged devices
- (handle_unmanaged_devices): update unmanaged device list and toggle
the managed property on each device when needed
- (system_settings_properties_changed_cb): handle signals from the
system settings service
- (system_settings_get_unmanaged_devices_cb): handle callback from
getting the unmanaged device list method call
- (query_unmanaged_devices): ask the system settings service for its
list of unmanaged devices
- (nm_manager_name_owner_changed, initial_get_connections): get unmanaged
devices
- (manager_set_wireless_enabled): push rfkill state down to wireless
devices directly and let them handle the necessary state transitions
- (manager_device_state_changed): update for new device states
- (nm_manager_add_device): set initial rfkill state on wireless devices
- (nm_manager_remove_device): don't touch the device if it's unmanaged
- (nm_manager_activate_connection): return error if the device is
unmanaged
- (nm_manager_sleep): handle new device states correctly; don't change
the state of unavailable/unmanaged devices
* libnm-glib/nm-device-802-11-wireless.c
- (state_changed_cb): update for new device states
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3540 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 02:58:02 +00:00
|
|
|
/* Can only get HW address of some devices when they are up */
|
2013-05-01 09:28:16 -04:00
|
|
|
nm_device_update_hw_address (self);
|
2007-03-02 Tambet Ingo <tambet@ximian.com>
* libnm-glib/nm-device-802-11-wireless.c: Cache networks (bssids) list.
We get signalled when it changes.
* libnm-glib/nm-client.c: Cache NMState and device list, we get signalled
when it changes.
* libnm-glib/nm-device.c: Cache the device state property.
* libnm-glib/nm-access-point.c: Cache the strength property.
* src/nm-device-802-11-wireless.c: Fix wireless device scanning scheduler.
The new algorithm is to start from SCAN_INTERVAL_MIN (currently defined as 0)
and add a SCAN_INTERVAL_STEP (currently 20 seconds) with each successful scan
until SCAN_INTERVAL_MAX (currently 120 seconds) is reached. Do not scan while
the device is down, activating, or activated (in case of A/B/G cards).
Remove some old dead ifdef'ed out code that used to configure wireless devices,
it's all done through supplicant now.
* src/supplicant-manager/nm-supplicant-interface.c: Fix the reference
counting issues with pending calls which caused leaks and crashes when
interface was removed (now that the interface actually gets removed).
* src/nm-call-store.c: Make a copy of data before running a foreach
with user callback on it - The most common usage pattern is to cancel
(and thus remove) all pending calls with foreach which would modify
the hash table we're iterating over.
* src/nm-manager.c: When a device is added, make sure it is "up". When
it's removed or disabled due to disabling wireless or networking, bring
it down.
* include/NetworkManager.h: Add new device state NM_DEVICE_STATE_DOWN.
* src/nm-device-802-11-wireless.c:
* src/nm-device-802-3-ethernet.c:
* src/nm-device.c:
- Remove "init" virtual function, all gobjects have a place for that
already (constructor).
- Replace "start" virtual function with "bring_up", devices can be
brought up and down more than just on startup now.
- Add "is_up" virtual function.
- Implement one way to bring a device down instead of previous 4 different
ways, each of witch did something different.
* src/NetworkManagerUtils.c (nm_dev_sock_open): This doesn't need an NMDevice,
all it needs is the device interface.
Get rid of NMData.dev_list (3 members to go).
Get rif of NMData in a lot of places.
* gnome/libnm_glib/libnm_glib.c: Make it compile again.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2395 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2007-03-02 09:30:48 +00:00
|
|
|
|
2011-11-17 22:39:34 -06:00
|
|
|
_update_ip4_address (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
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-20 16:09:22 -05:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
check_carrier (NMDevice *self)
|
2014-05-20 16:09:22 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
int ifindex = nm_device_get_ip_ifindex (self);
|
2014-05-20 16:09:22 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (!device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER))
|
|
|
|
|
nm_device_set_carrier (self, nm_platform_link_is_connected (ifindex));
|
2014-05-20 16:09:22 -05:00
|
|
|
}
|
|
|
|
|
|
2013-01-22 16:43:15 +01:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
bring_up (NMDevice *self, gboolean *no_firmware)
|
2013-01-22 16:43:15 +01:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
int ifindex = nm_device_get_ip_ifindex (self);
|
2013-05-07 10:23:44 -04:00
|
|
|
gboolean result;
|
2013-01-22 16:43:15 +01:00
|
|
|
|
2014-02-11 14:00:20 +01:00
|
|
|
if (ifindex <= 0) {
|
|
|
|
|
if (no_firmware)
|
|
|
|
|
*no_firmware = FALSE;
|
2013-05-07 10:23:44 -04:00
|
|
|
return TRUE;
|
2014-02-11 14:00:20 +01:00
|
|
|
}
|
2013-05-07 10:23:44 -04:00
|
|
|
|
2013-01-21 15:12:24 +01:00
|
|
|
result = nm_platform_link_set_up (ifindex);
|
2013-05-31 15:08:06 -05:00
|
|
|
if (no_firmware)
|
|
|
|
|
*no_firmware = nm_platform_get_error () == NM_PLATFORM_ERROR_NO_FIRMWARE;
|
2013-05-07 10:23:44 -04:00
|
|
|
|
|
|
|
|
/* Store carrier immediately. */
|
2014-07-15 13:36:24 +02:00
|
|
|
if (result && device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT))
|
|
|
|
|
check_carrier (self);
|
2013-05-07 10:23:44 -04:00
|
|
|
|
|
|
|
|
return result;
|
2013-01-22 16:43:15 +01:00
|
|
|
}
|
|
|
|
|
|
2008-05-14 01:55:49 +00:00
|
|
|
void
|
2013-06-13 15:13:58 -05:00
|
|
|
nm_device_take_down (NMDevice *self, gboolean block)
|
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
|
|
|
{
|
2014-02-11 14:00:20 +01:00
|
|
|
gboolean device_is_up;
|
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
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
|
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_HW, "taking down device.");
|
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
|
|
|
|
2014-02-11 14:00:20 +01:00
|
|
|
if (NM_DEVICE_GET_CLASS (self)->take_down) {
|
|
|
|
|
if (!NM_DEVICE_GET_CLASS (self)->take_down (self))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
device_is_up = nm_device_is_up (self);
|
|
|
|
|
if (block && device_is_up) {
|
|
|
|
|
int ifindex = nm_device_get_ip_ifindex (self);
|
|
|
|
|
gint64 wait_until = nm_utils_get_monotonic_timestamp_us () + 10000 /* microseconds */;
|
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
|
|
|
|
2014-02-11 14:00:20 +01:00
|
|
|
do {
|
|
|
|
|
g_usleep (200);
|
|
|
|
|
if (!nm_platform_link_refresh (ifindex))
|
|
|
|
|
return;
|
|
|
|
|
device_is_up = nm_device_is_up (self);
|
|
|
|
|
} while (device_is_up && nm_utils_get_monotonic_timestamp_us () < wait_until);
|
|
|
|
|
}
|
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
|
|
|
|
2014-02-11 14:00:20 +01:00
|
|
|
if (device_is_up) {
|
|
|
|
|
if (block)
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_HW, "device not down after timeout!");
|
2014-02-11 14:00:20 +01:00
|
|
|
else
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_HW, "device not down immediately");
|
2014-02-11 14:00:20 +01:00
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
2014-02-11 14:00:20 +01:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
take_down (NMDevice *self)
|
2013-01-22 16:43:15 +01:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
int ifindex = nm_device_get_ip_ifindex (self);
|
2013-03-13 09:28:38 +01:00
|
|
|
|
2014-02-23 22:29:09 +01:00
|
|
|
if (ifindex > 0)
|
2014-02-11 14:00:20 +01:00
|
|
|
return nm_platform_link_set_down (ifindex);
|
|
|
|
|
|
|
|
|
|
/* devices without ifindex are always up. */
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_HW, "cannot take down device without ifindex");
|
2014-02-11 14:00:20 +01:00
|
|
|
return FALSE;
|
2013-01-22 16:43:15 +01:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
void
|
|
|
|
|
nm_device_set_firmware_missing (NMDevice *self, gboolean new_missing)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2014-05-20 15:03:27 -05:00
|
|
|
NMDevicePrivate *priv;
|
2008-04-17 23:04:34 +00:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2009-08-03 17:15:03 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
if (priv->firmware_missing != new_missing) {
|
|
|
|
|
priv->firmware_missing = new_missing;
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_FIRMWARE_MISSING);
|
2009-08-03 17:15:03 -04:00
|
|
|
}
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
2009-08-03 17:15:03 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
gboolean
|
|
|
|
|
nm_device_get_firmware_missing (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->firmware_missing;
|
|
|
|
|
}
|
2013-06-11 17:05:49 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static NMIP4Config *
|
2014-07-15 13:36:24 +02:00
|
|
|
find_ip4_lease_config (NMDevice *self,
|
2014-05-20 15:03:27 -05:00
|
|
|
NMConnection *connection,
|
|
|
|
|
NMIP4Config *ext_ip4_config)
|
|
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
const char *ip_iface = nm_device_get_ip_iface (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
GSList *leases, *liter;
|
|
|
|
|
NMIP4Config *found = NULL;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_return_val_if_fail (NM_IS_IP4_CONFIG (ext_ip4_config), NULL);
|
|
|
|
|
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
2010-01-13 17:59:54 -08:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
leases = nm_dhcp_manager_get_lease_ip_configs (nm_dhcp_manager_get (),
|
|
|
|
|
ip_iface,
|
|
|
|
|
nm_connection_get_uuid (connection),
|
|
|
|
|
FALSE);
|
|
|
|
|
for (liter = leases; liter && !found; liter = liter->next) {
|
|
|
|
|
NMIP4Config *lease_config = liter->data;
|
|
|
|
|
const NMPlatformIP4Address *address = nm_ip4_config_get_address (lease_config, 0);
|
|
|
|
|
guint32 gateway = nm_ip4_config_get_gateway (lease_config);
|
2012-11-14 14:05:30 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_assert (address);
|
|
|
|
|
if (!nm_ip4_config_address_exists (ext_ip4_config, address))
|
|
|
|
|
continue;
|
|
|
|
|
if (gateway != nm_ip4_config_get_gateway (ext_ip4_config))
|
|
|
|
|
continue;
|
|
|
|
|
found = g_object_ref (lease_config);
|
|
|
|
|
}
|
2008-07-11 10:28:53 +00:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_slist_free_full (leases, g_object_unref);
|
|
|
|
|
return found;
|
|
|
|
|
}
|
2013-06-12 10:48:03 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
capture_lease_config (NMDevice *self,
|
2014-05-20 15:03:27 -05:00
|
|
|
NMIP4Config *ext_ip4_config,
|
|
|
|
|
NMIP4Config **out_ip4_config,
|
|
|
|
|
NMIP6Config *ext_ip6_config,
|
|
|
|
|
NMIP6Config **out_ip6_config)
|
|
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
const GSList *connections, *citer;
|
|
|
|
|
guint i;
|
|
|
|
|
gboolean dhcp_used = FALSE;
|
2013-10-24 13:55:06 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* Ensure at least one address on the device has a non-infinite lifetime,
|
|
|
|
|
* otherwise DHCP cannot possibly be active on the device right now.
|
|
|
|
|
*/
|
|
|
|
|
if (ext_ip4_config && out_ip4_config) {
|
|
|
|
|
for (i = 0; i < nm_ip4_config_get_num_addresses (ext_ip4_config); i++) {
|
|
|
|
|
const NMPlatformIP4Address *addr = nm_ip4_config_get_address (ext_ip4_config, i);
|
2013-10-24 13:55:06 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (addr->lifetime != NM_PLATFORM_LIFETIME_PERMANENT) {
|
|
|
|
|
dhcp_used = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (ext_ip6_config && out_ip6_config) {
|
|
|
|
|
for (i = 0; i < nm_ip6_config_get_num_addresses (ext_ip6_config); i++) {
|
|
|
|
|
const NMPlatformIP6Address *addr = nm_ip6_config_get_address (ext_ip6_config, i);
|
|
|
|
|
|
|
|
|
|
if (addr->lifetime != NM_PLATFORM_LIFETIME_PERMANENT) {
|
|
|
|
|
dhcp_used = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
g_return_if_fail ( (ext_ip6_config && out_ip6_config)
|
|
|
|
|
|| (ext_ip4_config && out_ip4_config));
|
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
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (!dhcp_used)
|
|
|
|
|
return;
|
2013-08-01 10:59:42 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
connections = nm_connection_provider_get_connections (priv->con_provider);
|
|
|
|
|
for (citer = connections; citer; citer = citer->next) {
|
|
|
|
|
NMConnection *candidate = citer->data;
|
|
|
|
|
const char *method;
|
2012-02-21 15:44:19 +01:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (!nm_device_check_connection_compatible (self, candidate))
|
2014-05-20 15:03:27 -05:00
|
|
|
continue;
|
2014-05-28 10:18:34 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* IPv4 leases */
|
|
|
|
|
method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP4_CONFIG);
|
|
|
|
|
if (out_ip4_config && strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) {
|
2014-07-15 13:36:24 +02:00
|
|
|
*out_ip4_config = find_ip4_lease_config (self, candidate, ext_ip4_config);
|
2014-05-20 15:03:27 -05:00
|
|
|
if (*out_ip4_config)
|
|
|
|
|
return;
|
|
|
|
|
}
|
2013-05-07 10:23:44 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* IPv6 leases */
|
|
|
|
|
method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP6_CONFIG);
|
|
|
|
|
if (out_ip6_config && strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
|
|
|
|
|
/* FIXME: implement find_ip6_lease_config() */
|
|
|
|
|
}
|
2012-08-01 11:16:48 -06:00
|
|
|
}
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static void
|
|
|
|
|
update_ip_config (NMDevice *self, gboolean initial)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
int ifindex;
|
|
|
|
|
gboolean linklocal6_just_completed = FALSE;
|
|
|
|
|
gboolean capture_resolv_conf;
|
|
|
|
|
NMDnsManagerResolvConfMode resolv_conf_mode;
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
ifindex = nm_device_get_ip_ifindex (self);
|
|
|
|
|
if (!ifindex)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
resolv_conf_mode = nm_dns_manager_get_resolv_conf_mode (nm_dns_manager_get ());
|
|
|
|
|
capture_resolv_conf = initial && (resolv_conf_mode == NM_DNS_MANAGER_RESOLV_CONF_EXPLICIT);
|
|
|
|
|
|
|
|
|
|
/* IPv4 */
|
|
|
|
|
g_clear_object (&priv->ext_ip4_config);
|
|
|
|
|
priv->ext_ip4_config = nm_ip4_config_capture (ifindex, capture_resolv_conf);
|
|
|
|
|
|
|
|
|
|
if (priv->ext_ip4_config) {
|
|
|
|
|
if (initial) {
|
|
|
|
|
g_clear_object (&priv->dev_ip4_config);
|
|
|
|
|
capture_lease_config (self, priv->ext_ip4_config, &priv->dev_ip4_config, NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
if (priv->dev_ip4_config)
|
|
|
|
|
nm_ip4_config_subtract (priv->ext_ip4_config, priv->dev_ip4_config);
|
|
|
|
|
if (priv->vpn4_config)
|
|
|
|
|
nm_ip4_config_subtract (priv->ext_ip4_config, priv->vpn4_config);
|
2014-07-15 17:16:56 -05:00
|
|
|
if (priv->wwan_ip4_config)
|
|
|
|
|
nm_ip4_config_subtract (priv->ext_ip4_config, priv->wwan_ip4_config);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
ip4_config_merge_and_apply (self, NULL, FALSE, NULL);
|
2013-12-09 16:32:36 -06:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* IPv6 */
|
|
|
|
|
g_clear_object (&priv->ext_ip6_config);
|
|
|
|
|
priv->ext_ip6_config = nm_ip6_config_capture (ifindex, capture_resolv_conf, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
|
|
|
|
|
if (priv->ext_ip6_config) {
|
2013-10-11 14:59:26 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* Check this before modifying ext_ip6_config */
|
|
|
|
|
linklocal6_just_completed = priv->linklocal6_timeout_id &&
|
2014-08-13 14:44:22 -05:00
|
|
|
have_ip6_address (priv->ext_ip6_config, TRUE);
|
2006-12-28 22:13:59 +00:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (priv->ac_ip6_config)
|
|
|
|
|
nm_ip6_config_subtract (priv->ext_ip6_config, priv->ac_ip6_config);
|
|
|
|
|
if (priv->dhcp6_ip6_config)
|
|
|
|
|
nm_ip6_config_subtract (priv->ext_ip6_config, priv->dhcp6_ip6_config);
|
2013-10-15 21:03:42 -05:00
|
|
|
if (priv->wwan_ip6_config)
|
|
|
|
|
nm_ip6_config_subtract (priv->ext_ip6_config, priv->wwan_ip6_config);
|
2014-05-20 15:03:27 -05:00
|
|
|
if (priv->vpn6_config)
|
|
|
|
|
nm_ip6_config_subtract (priv->ext_ip6_config, priv->vpn6_config);
|
2008-05-29 20:58:52 +00:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
ip6_config_merge_and_apply (self, FALSE, NULL);
|
|
|
|
|
}
|
2013-04-04 10:20:24 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (linklocal6_just_completed) {
|
|
|
|
|
/* linklocal6 is ready now, do the state transition... we are also
|
|
|
|
|
* invoked as g_idle_add, so no problems with reentrance doing it now.
|
|
|
|
|
*/
|
|
|
|
|
linklocal6_complete (self);
|
|
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_capture_initial_config (NMDevice *self)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
update_ip_config (self, TRUE);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
queued_ip_config_change (gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
2009-07-07 14:34:01 -04:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* Wait for any queued state changes */
|
|
|
|
|
if (priv->queued_state.id)
|
|
|
|
|
return TRUE;
|
2011-10-07 15:58:08 +02:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
priv->queued_ip_config_id = 0;
|
|
|
|
|
update_ip_config (self, FALSE);
|
2014-07-24 17:14:30 -05:00
|
|
|
|
|
|
|
|
/* If no IPv6 link-local address exists but other addresses do then we
|
|
|
|
|
* must add the LL address to remain conformant with RFC 3513 chapter 2.1
|
|
|
|
|
* ("Addressing Model"): "All interfaces are required to have at least
|
|
|
|
|
* one link-local unicast address".
|
|
|
|
|
*/
|
|
|
|
|
if (priv->ip6_config && nm_ip6_config_get_num_addresses (priv->ip6_config))
|
|
|
|
|
check_and_add_ipv6ll_addr (self);
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
2013-12-09 12:55:04 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static void
|
2014-07-24 17:14:30 -05:00
|
|
|
device_ip_changed (NMPlatform *platform,
|
|
|
|
|
int ifindex,
|
|
|
|
|
gpointer platform_object,
|
|
|
|
|
NMPlatformSignalChangeType change_type,
|
|
|
|
|
NMPlatformReason reason,
|
|
|
|
|
NMDevice *self)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
2014-07-24 17:14:30 -05:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (nm_device_get_ip_ifindex (self) == ifindex) {
|
|
|
|
|
if (!priv->queued_ip_config_id)
|
|
|
|
|
priv->queued_ip_config_id = g_idle_add (queued_ip_config_change, self);
|
2007-02-05 12:14:09 +00:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "queued IP config change");
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
}
|
2007-02-05 12:14:09 +00:00
|
|
|
|
|
|
|
|
static void
|
2014-05-20 15:03:27 -05:00
|
|
|
nm_device_queued_ip_config_change_clear (NMDevice *self)
|
2007-02-05 12:14:09 +00:00
|
|
|
{
|
2014-05-20 15:03:27 -05:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-05-29 12:57:13 -03:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (priv->queued_ip_config_id) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "clearing queued IP config change");
|
2014-05-20 15:03:27 -05:00
|
|
|
g_source_remove (priv->queued_ip_config_id);
|
|
|
|
|
priv->queued_ip_config_id = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-05-01 09:28:16 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/**
|
|
|
|
|
* nm_device_get_managed():
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the #NMDevice
|
2014-05-20 15:03:27 -05:00
|
|
|
*
|
|
|
|
|
* Returns: %TRUE if the device is managed
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_get_managed (NMDevice *self)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
gboolean managed;
|
2013-05-01 09:28:16 -04:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
/* Return the composite of all managed flags. However, if the device
|
|
|
|
|
* is a default-unmanaged device, and would be managed except for the
|
|
|
|
|
* default-unmanaged flag (eg, only NM_UNMANAGED_DEFAULT is set) then
|
|
|
|
|
* the device is managed whenever it's not in the UNMANAGED state.
|
|
|
|
|
*/
|
|
|
|
|
managed = !(priv->unmanaged_flags & ~NM_UNMANAGED_DEFAULT);
|
|
|
|
|
if (managed && (priv->unmanaged_flags & NM_UNMANAGED_DEFAULT))
|
|
|
|
|
managed = (priv->state > NM_DEVICE_STATE_UNMANAGED);
|
|
|
|
|
|
|
|
|
|
return managed;
|
2007-02-05 12:14:09 +00:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/**
|
2014-05-20 16:39:57 -05:00
|
|
|
* nm_device_get_unmanaged_flag():
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the #NMDevice
|
2014-05-20 15:03:27 -05:00
|
|
|
*
|
2014-05-20 16:39:57 -05:00
|
|
|
* Returns: %TRUE if the device is unmanaged for @flag.
|
2014-05-20 15:03:27 -05:00
|
|
|
*/
|
|
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_get_unmanaged_flag (NMDevice *self, NMUnmanagedFlags flag)
|
2011-03-17 13:39:31 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->unmanaged_flags & flag;
|
2011-03-17 13:39:31 -05:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/**
|
2014-05-20 16:39:57 -05:00
|
|
|
* nm_device_get_default_unmanaged():
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the #NMDevice
|
2014-05-20 15:03:27 -05:00
|
|
|
*
|
2014-05-20 16:39:57 -05:00
|
|
|
* Returns: %TRUE if the device is by default unmanaged
|
2014-05-20 15:03:27 -05:00
|
|
|
*/
|
2014-05-20 16:39:57 -05:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_get_default_unmanaged (NMDevice *self)
|
2007-02-05 12:14:09 +00:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
return nm_device_get_unmanaged_flag (self, NM_UNMANAGED_DEFAULT);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
2007-02-05 12:14:09 +00:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_unmanaged (NMDevice *self,
|
2014-05-20 15:03:27 -05:00
|
|
|
NMUnmanagedFlags flag,
|
|
|
|
|
gboolean unmanaged,
|
|
|
|
|
NMDeviceStateReason reason)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
gboolean was_managed, now_managed;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2014-05-20 15:03:27 -05:00
|
|
|
g_return_if_fail (flag <= NM_UNMANAGED_LAST);
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
was_managed = nm_device_get_managed (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
if (unmanaged)
|
|
|
|
|
priv->unmanaged_flags |= flag;
|
|
|
|
|
else
|
|
|
|
|
priv->unmanaged_flags &= ~flag;
|
2014-07-15 13:36:24 +02:00
|
|
|
now_managed = nm_device_get_managed (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
if (was_managed != now_managed) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "now %s", unmanaged ? "unmanaged" : "managed");
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_MANAGED);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
if (unmanaged)
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_UNMANAGED, reason);
|
2013-05-01 09:28:16 -04:00
|
|
|
else
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_state_changed (self, NM_DEVICE_STATE_UNAVAILABLE, reason);
|
2007-02-05 12:14:09 +00:00
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2014-05-23 18:25:05 -05:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_unmanaged_quitting (NMDevice *self)
|
2014-05-23 18:25:05 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-23 18:25:05 -05:00
|
|
|
|
|
|
|
|
/* It's OK to block here because we're quitting */
|
2014-07-15 13:36:24 +02:00
|
|
|
if (nm_device_is_activating (self) || priv->state == NM_DEVICE_STATE_ACTIVATED)
|
|
|
|
|
_set_state_full (self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_REMOVED, TRUE);
|
2014-05-23 18:25:05 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_unmanaged (self,
|
2014-05-23 18:25:05 -05:00
|
|
|
NM_UNMANAGED_INTERNAL,
|
|
|
|
|
TRUE,
|
|
|
|
|
NM_DEVICE_STATE_REASON_REMOVED);
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/**
|
|
|
|
|
* nm_device_set_initial_unmanaged_flag():
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the #NMDevice
|
2014-05-20 15:03:27 -05:00
|
|
|
* @flag: an #NMUnmanagedFlag
|
|
|
|
|
* @unmanaged: %TRUE or %FALSE to set or clear @flag
|
|
|
|
|
*
|
|
|
|
|
* Like nm_device_set_unmanaged() but must be set before the device is exported
|
|
|
|
|
* and does not trigger state changes. Should only be used when initializing
|
|
|
|
|
* a device.
|
|
|
|
|
*/
|
|
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_initial_unmanaged_flag (NMDevice *self,
|
2014-05-20 15:03:27 -05:00
|
|
|
NMUnmanagedFlags flag,
|
|
|
|
|
gboolean unmanaged)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2014-05-20 15:03:27 -05:00
|
|
|
NMDevicePrivate *priv;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2014-05-20 15:03:27 -05:00
|
|
|
g_return_if_fail (flag <= NM_UNMANAGED_LAST);
|
2007-02-05 12:14:09 +00:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
g_return_if_fail (priv->path == NULL);
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (unmanaged)
|
|
|
|
|
priv->unmanaged_flags |= flag;
|
|
|
|
|
else
|
|
|
|
|
priv->unmanaged_flags &= ~flag;
|
|
|
|
|
}
|
2013-07-27 10:41:44 +02:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_dhcp_timeout (NMDevice *self, guint32 timeout)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2013-01-25 11:59:05 -06:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
NM_DEVICE_GET_PRIVATE (self)->dhcp_timeout = timeout;
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
void
|
2014-07-30 10:57:45 -04:00
|
|
|
nm_device_set_dhcp_anycast_address (NMDevice *self, const char *addr)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv;
|
2013-05-29 12:57:13 -03:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2014-07-30 10:57:45 -04:00
|
|
|
g_return_if_fail (!addr || nm_utils_hwaddr_valid (addr, ETH_ALEN));
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-07-30 10:57:45 -04:00
|
|
|
g_free (priv->dhcp_anycast_address);
|
|
|
|
|
priv->dhcp_anycast_address = g_strdup (addr);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_device_connection_is_available():
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the #NMDevice
|
2014-05-20 15:03:27 -05:00
|
|
|
* @connection: the #NMConnection to check for availability
|
|
|
|
|
* @allow_device_override: set to %TRUE to let the device do specific checks
|
|
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* Check if @connection is available to be activated on @self. Normally this
|
|
|
|
|
* only checks if the connection is in @self's AvailableConnections property.
|
2014-05-20 15:03:27 -05:00
|
|
|
* If @allow_device_override is %TRUE then the device is asked to do specific
|
|
|
|
|
* checks that may bypass the AvailableConnections property.
|
|
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* Returns: %TRUE if @connection can be activated on @self
|
2014-05-20 15:03:27 -05:00
|
|
|
*/
|
|
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_connection_is_available (NMDevice *self,
|
2014-05-20 15:03:27 -05:00
|
|
|
NMConnection *connection,
|
|
|
|
|
gboolean allow_device_override)
|
|
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
gboolean available = FALSE;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (nm_device_get_default_unmanaged (self) && (priv->state == NM_DEVICE_STATE_UNMANAGED)) {
|
2014-05-20 15:03:27 -05:00
|
|
|
/* default-unmanaged devices in UNMANAGED state have no available connections
|
|
|
|
|
* so we must manually check whether the connection is available here.
|
|
|
|
|
*/
|
2014-07-15 13:36:24 +02:00
|
|
|
if ( nm_device_check_connection_compatible (self, connection)
|
|
|
|
|
&& NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, NULL))
|
2014-05-20 15:03:27 -05:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
available = !!g_hash_table_lookup (priv->available_connections, connection);
|
|
|
|
|
if (!available && allow_device_override) {
|
|
|
|
|
/* FIXME: hack for hidden WiFi becuase clients didn't consistently
|
|
|
|
|
* set the 'hidden' property to indicate hidden SSID networks. If
|
|
|
|
|
* activating but the network isn't available let the device recheck
|
|
|
|
|
* availability.
|
|
|
|
|
*/
|
2014-07-15 13:36:24 +02:00
|
|
|
if ( nm_device_check_connection_compatible (self, connection)
|
|
|
|
|
&& NM_DEVICE_GET_CLASS (self)->check_connection_available_wifi_hidden)
|
|
|
|
|
available = NM_DEVICE_GET_CLASS (self)->check_connection_available_wifi_hidden (self, connection);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return available;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
_signal_available_connections_changed (NMDevice *self)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_AVAILABLE_CONNECTIONS);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
_clear_available_connections (NMDevice *self, gboolean do_signal)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
g_hash_table_remove_all (NM_DEVICE_GET_PRIVATE (self)->available_connections);
|
2014-05-20 15:03:27 -05:00
|
|
|
if (do_signal == TRUE)
|
2014-07-15 13:36:24 +02:00
|
|
|
_signal_available_connections_changed (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
_try_add_available_connection (NMDevice *self, NMConnection *connection)
|
|
|
|
|
{
|
|
|
|
|
if (nm_device_get_state (self) < NM_DEVICE_STATE_DISCONNECTED)
|
|
|
|
|
return FALSE;
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (nm_device_check_connection_compatible (self, connection)) {
|
|
|
|
|
if (NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, NULL)) {
|
|
|
|
|
g_hash_table_insert (NM_DEVICE_GET_PRIVATE (self)->available_connections,
|
|
|
|
|
g_object_ref (connection),
|
|
|
|
|
GUINT_TO_POINTER (1));
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
_del_available_connection (NMDevice *self, NMConnection *connection)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
return g_hash_table_remove (NM_DEVICE_GET_PRIVATE (self)->available_connections, connection);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static gboolean
|
|
|
|
|
connection_requires_carrier (NMConnection *connection)
|
|
|
|
|
{
|
|
|
|
|
NMSettingIP4Config *s_ip4;
|
|
|
|
|
NMSettingIP6Config *s_ip6;
|
|
|
|
|
const char *method;
|
|
|
|
|
gboolean ip4_carrier_wanted = FALSE, ip6_carrier_wanted = FALSE;
|
|
|
|
|
gboolean ip4_used = FALSE, ip6_used = FALSE;
|
2012-06-01 16:48:57 +02:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
|
|
|
|
if ( strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) != 0
|
|
|
|
|
&& strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) != 0) {
|
|
|
|
|
ip4_carrier_wanted = TRUE;
|
2012-06-01 16:48:57 +02:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* If IPv4 wants a carrier and cannot fail, the whole connection
|
|
|
|
|
* requires a carrier regardless of the IPv6 method.
|
|
|
|
|
*/
|
|
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
|
|
|
|
if (s_ip4 && !nm_setting_ip4_config_get_may_fail (s_ip4))
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
ip4_used = (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) != 0);
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
|
|
|
|
if ( strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) != 0
|
|
|
|
|
&& strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) != 0) {
|
|
|
|
|
ip6_carrier_wanted = TRUE;
|
2013-05-07 10:23:44 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* If IPv6 wants a carrier and cannot fail, the whole connection
|
|
|
|
|
* requires a carrier regardless of the IPv4 method.
|
|
|
|
|
*/
|
|
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
|
|
|
|
if (s_ip6 && !nm_setting_ip6_config_get_may_fail (s_ip6))
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
ip6_used = (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) != 0);
|
2013-12-16 15:16:43 +01:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* If an IP version wants a carrier and and the other IP version isn't
|
|
|
|
|
* used, the connection requires carrier since it will just fail without one.
|
|
|
|
|
*/
|
|
|
|
|
if (ip4_carrier_wanted && !ip6_used)
|
|
|
|
|
return TRUE;
|
|
|
|
|
if (ip6_carrier_wanted && !ip4_used)
|
|
|
|
|
return TRUE;
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* If both want a carrier, the whole connection wants a carrier */
|
|
|
|
|
return ip4_carrier_wanted && ip6_carrier_wanted;
|
|
|
|
|
}
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
check_connection_available (NMDevice *self,
|
2014-05-20 15:03:27 -05:00
|
|
|
NMConnection *connection,
|
|
|
|
|
const char *specific_object)
|
|
|
|
|
{
|
|
|
|
|
/* Connections which require a network connection are not available when
|
|
|
|
|
* the device has no carrier, even with ignore-carrer=TRUE.
|
|
|
|
|
*/
|
2014-07-15 13:36:24 +02:00
|
|
|
if (NM_DEVICE_GET_PRIVATE (self)->carrier == FALSE)
|
2014-05-20 15:03:27 -05:00
|
|
|
return connection_requires_carrier (connection) ? FALSE : TRUE;
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_recheck_available_connections (NMDevice *self)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
const GSList *connections, *iter;
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE(self);
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (priv->con_provider) {
|
2014-07-15 13:36:24 +02:00
|
|
|
_clear_available_connections (self, FALSE);
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
connections = nm_connection_provider_get_connections (priv->con_provider);
|
|
|
|
|
for (iter = connections; iter; iter = g_slist_next (iter))
|
2014-07-15 13:36:24 +02:00
|
|
|
_try_add_available_connection (self, NM_CONNECTION (iter->data));
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
_signal_available_connections_changed (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
}
|
2012-05-14 15:32:54 +02:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/**
|
|
|
|
|
* nm_device_get_available_connections:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the #NMDevice
|
2014-05-20 15:03:27 -05:00
|
|
|
* @specific_object: a specific object path if any
|
|
|
|
|
*
|
|
|
|
|
* Returns a list of connections available to activate on the device, taking
|
|
|
|
|
* into account any device-specific details given by @specific_object (like
|
|
|
|
|
* WiFi access point path).
|
|
|
|
|
*
|
|
|
|
|
* Returns: caller-owned #GPtrArray of #NMConnections
|
|
|
|
|
*/
|
|
|
|
|
GPtrArray *
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_get_available_connections (NMDevice *self, const char *specific_object)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
GHashTableIter iter;
|
|
|
|
|
guint num_available;
|
|
|
|
|
NMConnection *connection = NULL;
|
|
|
|
|
GPtrArray *array = NULL;
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
num_available = g_hash_table_size (priv->available_connections);
|
|
|
|
|
if (num_available > 0) {
|
|
|
|
|
array = g_ptr_array_sized_new (num_available);
|
|
|
|
|
g_hash_table_iter_init (&iter, priv->available_connections);
|
|
|
|
|
while (g_hash_table_iter_next (&iter, (gpointer) &connection, NULL)) {
|
|
|
|
|
/* If a specific object is given, only include connections that are
|
|
|
|
|
* compatible with it.
|
|
|
|
|
*/
|
|
|
|
|
if ( !specific_object
|
2014-07-15 13:36:24 +02:00
|
|
|
|| NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, specific_object))
|
2014-05-20 15:03:27 -05:00
|
|
|
g_ptr_array_add (array, connection);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return array;
|
|
|
|
|
}
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static void
|
|
|
|
|
cp_connection_added (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
if (_try_add_available_connection (NM_DEVICE (user_data), connection))
|
|
|
|
|
_signal_available_connections_changed (NM_DEVICE (user_data));
|
|
|
|
|
}
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static void
|
|
|
|
|
cp_connection_removed (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
if (_del_available_connection (NM_DEVICE (user_data), connection))
|
|
|
|
|
_signal_available_connections_changed (NM_DEVICE (user_data));
|
|
|
|
|
}
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static void
|
|
|
|
|
cp_connection_updated (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
gboolean added, deleted;
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* FIXME: don't remove it from the hash if it's just going to get re-added */
|
|
|
|
|
deleted = _del_available_connection (NM_DEVICE (user_data), connection);
|
|
|
|
|
added = _try_add_available_connection (NM_DEVICE (user_data), connection);
|
2013-10-11 14:59:26 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* Only signal if the connection was removed OR added, but not both */
|
|
|
|
|
if (added != deleted)
|
|
|
|
|
_signal_available_connections_changed (NM_DEVICE (user_data));
|
|
|
|
|
}
|
2013-01-24 17:47:59 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_supports_vlans (NMDevice *self)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
return nm_platform_link_supports_vlans (nm_device_get_ifindex (self));
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
2014-01-02 14:46:02 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/**
|
|
|
|
|
* nm_device_add_pending_action():
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the #NMDevice to add the pending action to
|
2014-05-20 15:03:27 -05:00
|
|
|
* @action: a static string that identifies the action
|
|
|
|
|
* @assert_not_yet_pending: if %TRUE, assert that the @action is currently not yet pending.
|
|
|
|
|
* Otherwise, ignore duplicate scheduling of the same action silently.
|
|
|
|
|
*
|
|
|
|
|
* Adds a pending action to the device.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE if the action was added (and not already added before). %FALSE
|
|
|
|
|
* if the same action is already scheduled. In the latter case, the action was not scheduled
|
|
|
|
|
* a second time.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_add_pending_action (NMDevice *self, const char *action, gboolean assert_not_yet_pending)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
GSList *iter;
|
|
|
|
|
guint count = 0;
|
2013-05-01 09:28:16 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_return_val_if_fail (action, FALSE);
|
2013-08-13 17:45:34 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* Check if the action is already pending. Cannot add duplicate actions */
|
|
|
|
|
for (iter = priv->pending_actions; iter; iter = iter->next) {
|
|
|
|
|
if (!strcmp (action, iter->data)) {
|
|
|
|
|
if (assert_not_yet_pending) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE, "add_pending_action (%d): '%s' already pending",
|
|
|
|
|
count + g_slist_length (iter), action);
|
2014-05-20 15:03:27 -05:00
|
|
|
g_return_val_if_reached (FALSE);
|
|
|
|
|
} else {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s' already pending (expected)",
|
|
|
|
|
count + g_slist_length (iter), action);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
count++;
|
|
|
|
|
}
|
2011-11-18 00:09:37 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
priv->pending_actions = g_slist_append (priv->pending_actions, g_strdup (action));
|
|
|
|
|
count++;
|
2011-11-18 00:05:37 -06:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s'", count, action);
|
2012-06-01 15:27:39 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (count == 1)
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_HAS_PENDING_ACTION);
|
2012-05-29 09:56:50 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
2012-05-29 09:56:50 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/**
|
|
|
|
|
* nm_device_remove_pending_action():
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: the #NMDevice to remove the pending action from
|
2014-05-20 15:03:27 -05:00
|
|
|
* @action: a static string that identifies the action
|
|
|
|
|
* @assert_is_pending: if %TRUE, assert that the @action is pending.
|
|
|
|
|
* If %FALSE, don't do anything if the current action is not pending and
|
|
|
|
|
* return %FALSE.
|
|
|
|
|
*
|
|
|
|
|
* Removes a pending action previously added by nm_device_add_pending_action().
|
|
|
|
|
*
|
|
|
|
|
* Returns: whether the @action was pending and is now removed.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_remove_pending_action (NMDevice *self, const char *action, gboolean assert_is_pending)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
GSList *iter;
|
|
|
|
|
guint count = 0;
|
2014-02-10 08:49:47 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_return_val_if_fail (action, FALSE);
|
2014-02-24 18:10:18 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
for (iter = priv->pending_actions; iter; iter = iter->next) {
|
|
|
|
|
if (!strcmp (action, iter->data)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s'",
|
|
|
|
|
count + g_slist_length (iter->next), /* length excluding 'iter' */
|
|
|
|
|
action);
|
2014-05-20 15:03:27 -05:00
|
|
|
g_free (iter->data);
|
|
|
|
|
priv->pending_actions = g_slist_delete_link (priv->pending_actions, iter);
|
|
|
|
|
if (priv->pending_actions == NULL)
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_HAS_PENDING_ACTION);
|
2014-05-20 15:03:27 -05:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
count++;
|
|
|
|
|
}
|
2014-05-28 10:18:34 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (assert_is_pending) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending", count, action);
|
2014-05-20 15:03:27 -05:00
|
|
|
g_return_val_if_reached (FALSE);
|
2014-02-12 23:54:26 +01:00
|
|
|
} else
|
|
|
|
|
_LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending (expected)", count, action);
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
2011-11-18 00:34:08 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_has_pending_action (NMDevice *self)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
return !!priv->pending_actions;
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/***********************************************************/
|
|
|
|
|
|
2014-05-22 14:51:55 -05:00
|
|
|
static void
|
|
|
|
|
_cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
|
|
|
|
|
{
|
2014-07-02 15:19:58 +02:00
|
|
|
NMConnection *connection;
|
2014-05-22 14:51:55 -05:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
/* Clean up when device was deactivated during call to firewall */
|
|
|
|
|
|
2014-07-02 15:19:58 +02:00
|
|
|
if (priv->fw_call) {
|
|
|
|
|
nm_firewall_manager_cancel_call (nm_firewall_manager_get (), priv->fw_call);
|
|
|
|
|
priv->fw_call = NULL;
|
|
|
|
|
}
|
2014-05-22 14:51:55 -05:00
|
|
|
|
2014-07-02 15:19:58 +02:00
|
|
|
connection = nm_device_get_connection (self);
|
|
|
|
|
if (deconfigure && connection) {
|
|
|
|
|
nm_firewall_manager_remove_from_zone (nm_firewall_manager_get (),
|
|
|
|
|
nm_device_get_ip_iface (self),
|
|
|
|
|
NULL);
|
2014-05-22 14:51:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ip_check_gw_ping_cleanup (self);
|
|
|
|
|
|
|
|
|
|
/* Break the activation chain */
|
|
|
|
|
activation_source_clear (self, TRUE, AF_INET);
|
|
|
|
|
activation_source_clear (self, TRUE, AF_INET6);
|
|
|
|
|
|
|
|
|
|
/* Clear any queued transitions */
|
|
|
|
|
nm_device_queued_state_clear (self);
|
|
|
|
|
nm_device_queued_ip_config_change_clear (self);
|
|
|
|
|
|
|
|
|
|
priv->ip4_state = priv->ip6_state = IP_NONE;
|
|
|
|
|
|
|
|
|
|
dhcp4_cleanup (self, deconfigure, FALSE);
|
|
|
|
|
arp_cleanup (self);
|
|
|
|
|
dhcp6_cleanup (self, deconfigure, FALSE);
|
|
|
|
|
linklocal6_cleanup (self);
|
|
|
|
|
addrconf6_cleanup (self);
|
|
|
|
|
dnsmasq_cleanup (self);
|
|
|
|
|
aipd_cleanup (self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cleanup_generic_post (NMDevice *self, gboolean deconfigure)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE;
|
|
|
|
|
|
|
|
|
|
/* Clean up IP configs; this does not actually deconfigure the
|
|
|
|
|
* interface; the caller must flush routes and addresses explicitly.
|
|
|
|
|
*/
|
|
|
|
|
nm_device_set_ip4_config (self, NULL, TRUE, &ignored);
|
|
|
|
|
nm_device_set_ip6_config (self, NULL, TRUE, &ignored);
|
|
|
|
|
g_clear_object (&priv->dev_ip4_config);
|
|
|
|
|
g_clear_object (&priv->ext_ip4_config);
|
2014-07-15 17:16:56 -05:00
|
|
|
g_clear_object (&priv->wwan_ip4_config);
|
2014-05-22 14:51:55 -05:00
|
|
|
g_clear_object (&priv->vpn4_config);
|
|
|
|
|
g_clear_object (&priv->ip4_config);
|
|
|
|
|
g_clear_object (&priv->ac_ip6_config);
|
|
|
|
|
g_clear_object (&priv->ext_ip6_config);
|
|
|
|
|
g_clear_object (&priv->vpn6_config);
|
2013-10-15 21:03:42 -05:00
|
|
|
g_clear_object (&priv->wwan_ip6_config);
|
2014-05-22 14:51:55 -05:00
|
|
|
g_clear_object (&priv->ip6_config);
|
|
|
|
|
|
|
|
|
|
clear_act_request (self);
|
|
|
|
|
|
|
|
|
|
/* Clear legacy IPv4 address property */
|
|
|
|
|
if (priv->ip4_address) {
|
|
|
|
|
priv->ip4_address = 0;
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_IP4_ADDRESS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (deconfigure) {
|
|
|
|
|
/* Check if the device was deactivated, and if so, delete_link.
|
|
|
|
|
* Don't call delete_link synchronously because we are currently
|
|
|
|
|
* handling a state change -- which is not reentrant. */
|
|
|
|
|
delete_on_deactivate_check_and_schedule (self, nm_device_get_ip_ifindex (self));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ip_iface should be cleared after flushing all routes and addreses, since
|
|
|
|
|
* those are identified by ip_iface, not by iface (which might be a tty
|
|
|
|
|
* or ATM device).
|
|
|
|
|
*/
|
|
|
|
|
nm_device_set_ip_iface (self, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/*
|
|
|
|
|
* nm_device_cleanup
|
|
|
|
|
*
|
|
|
|
|
* Remove a device's routing table entries and IP addresses.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason)
|
2010-05-25 10:52:25 -07:00
|
|
|
{
|
2010-07-01 10:32:11 -07:00
|
|
|
NMDevicePrivate *priv;
|
2014-05-20 15:03:27 -05:00
|
|
|
int ifindex;
|
2010-07-01 10:32:11 -07:00
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2010-05-25 10:52:25 -07:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
if (reason == NM_DEVICE_STATE_REASON_NOW_MANAGED)
|
|
|
|
|
_LOGI (LOGD_DEVICE, "preparing device");
|
|
|
|
|
else
|
|
|
|
|
_LOGI (LOGD_DEVICE, "deactivating device (reason '%s') [%d]", reason_to_string (reason), reason);
|
2010-05-25 10:52:25 -07:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* Save whether or not we tried IPv6 for later */
|
|
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
2010-07-01 10:32:11 -07:00
|
|
|
|
2014-05-22 14:51:55 -05:00
|
|
|
_cleanup_generic_pre (self, TRUE);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
/* Turn off kernel IPv6 */
|
2014-07-24 17:14:30 -05:00
|
|
|
set_disable_ipv6 (self, "1");
|
2014-05-20 15:03:27 -05:00
|
|
|
nm_device_ipv6_sysctl_set (self, "accept_ra", "0");
|
|
|
|
|
nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0");
|
|
|
|
|
|
|
|
|
|
/* Call device type-specific deactivation */
|
|
|
|
|
if (NM_DEVICE_GET_CLASS (self)->deactivate)
|
|
|
|
|
NM_DEVICE_GET_CLASS (self)->deactivate (self);
|
|
|
|
|
|
|
|
|
|
/* master: release slaves */
|
|
|
|
|
nm_device_master_release_slaves (self);
|
|
|
|
|
|
|
|
|
|
/* slave: mark no longer enslaved */
|
|
|
|
|
g_clear_object (&priv->master);
|
|
|
|
|
priv->enslaved = FALSE;
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_MASTER);
|
|
|
|
|
|
|
|
|
|
/* Take out any entries in the routing table and any IP address the device had. */
|
|
|
|
|
ifindex = nm_device_get_ip_ifindex (self);
|
|
|
|
|
if (ifindex > 0) {
|
|
|
|
|
nm_platform_route_flush (ifindex);
|
|
|
|
|
nm_platform_address_flush (ifindex);
|
2011-05-03 11:57:26 -05:00
|
|
|
}
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-05-22 14:51:55 -05:00
|
|
|
_cleanup_generic_post (self, TRUE);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***********************************************************/
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
ip_config_valid (NMDeviceState state)
|
|
|
|
|
{
|
|
|
|
|
return (state == NM_DEVICE_STATE_UNMANAGED) ||
|
|
|
|
|
(state >= NM_DEVICE_STATE_IP_CHECK &&
|
|
|
|
|
state <= NM_DEVICE_STATE_DEACTIVATING);
|
2011-05-03 11:57:26 -05:00
|
|
|
}
|
|
|
|
|
|
2013-10-09 13:55:05 -05:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
notify_ip_properties (NMDevice *self)
|
2013-10-09 13:55:05 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE);
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_IP4_CONFIG);
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP4_CONFIG);
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_IP6_CONFIG);
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG);
|
2013-10-09 13:55:05 -05:00
|
|
|
}
|
|
|
|
|
|
2014-05-23 18:25:05 -05:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
_set_state_full (NMDevice *self,
|
2014-05-23 18:25:05 -05:00
|
|
|
NMDeviceState state,
|
|
|
|
|
NMDeviceStateReason reason,
|
|
|
|
|
gboolean quitting)
|
2007-02-05 12:14:09 +00:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2007-03-02 Tambet Ingo <tambet@ximian.com>
* libnm-glib/nm-device-802-11-wireless.c: Cache networks (bssids) list.
We get signalled when it changes.
* libnm-glib/nm-client.c: Cache NMState and device list, we get signalled
when it changes.
* libnm-glib/nm-device.c: Cache the device state property.
* libnm-glib/nm-access-point.c: Cache the strength property.
* src/nm-device-802-11-wireless.c: Fix wireless device scanning scheduler.
The new algorithm is to start from SCAN_INTERVAL_MIN (currently defined as 0)
and add a SCAN_INTERVAL_STEP (currently 20 seconds) with each successful scan
until SCAN_INTERVAL_MAX (currently 120 seconds) is reached. Do not scan while
the device is down, activating, or activated (in case of A/B/G cards).
Remove some old dead ifdef'ed out code that used to configure wireless devices,
it's all done through supplicant now.
* src/supplicant-manager/nm-supplicant-interface.c: Fix the reference
counting issues with pending calls which caused leaks and crashes when
interface was removed (now that the interface actually gets removed).
* src/nm-call-store.c: Make a copy of data before running a foreach
with user callback on it - The most common usage pattern is to cancel
(and thus remove) all pending calls with foreach which would modify
the hash table we're iterating over.
* src/nm-manager.c: When a device is added, make sure it is "up". When
it's removed or disabled due to disabling wireless or networking, bring
it down.
* include/NetworkManager.h: Add new device state NM_DEVICE_STATE_DOWN.
* src/nm-device-802-11-wireless.c:
* src/nm-device-802-3-ethernet.c:
* src/nm-device.c:
- Remove "init" virtual function, all gobjects have a place for that
already (constructor).
- Replace "start" virtual function with "bring_up", devices can be
brought up and down more than just on startup now.
- Add "is_up" virtual function.
- Implement one way to bring a device down instead of previous 4 different
ways, each of witch did something different.
* src/NetworkManagerUtils.c (nm_dev_sock_open): This doesn't need an NMDevice,
all it needs is the device interface.
Get rid of NMData.dev_list (3 members to go).
Get rif of NMData in a lot of places.
* gnome/libnm_glib/libnm_glib.c: Make it compile again.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2395 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2007-03-02 09:30:48 +00:00
|
|
|
NMDeviceState old_state;
|
2008-04-27 14:30:06 +00:00
|
|
|
NMActRequest *req;
|
2008-08-18 18:29:47 +00:00
|
|
|
gboolean no_firmware = FALSE;
|
2012-06-28 12:09:03 -05:00
|
|
|
NMConnection *connection;
|
2007-03-02 Tambet Ingo <tambet@ximian.com>
* libnm-glib/nm-device-802-11-wireless.c: Cache networks (bssids) list.
We get signalled when it changes.
* libnm-glib/nm-client.c: Cache NMState and device list, we get signalled
when it changes.
* libnm-glib/nm-device.c: Cache the device state property.
* libnm-glib/nm-access-point.c: Cache the strength property.
* src/nm-device-802-11-wireless.c: Fix wireless device scanning scheduler.
The new algorithm is to start from SCAN_INTERVAL_MIN (currently defined as 0)
and add a SCAN_INTERVAL_STEP (currently 20 seconds) with each successful scan
until SCAN_INTERVAL_MAX (currently 120 seconds) is reached. Do not scan while
the device is down, activating, or activated (in case of A/B/G cards).
Remove some old dead ifdef'ed out code that used to configure wireless devices,
it's all done through supplicant now.
* src/supplicant-manager/nm-supplicant-interface.c: Fix the reference
counting issues with pending calls which caused leaks and crashes when
interface was removed (now that the interface actually gets removed).
* src/nm-call-store.c: Make a copy of data before running a foreach
with user callback on it - The most common usage pattern is to cancel
(and thus remove) all pending calls with foreach which would modify
the hash table we're iterating over.
* src/nm-manager.c: When a device is added, make sure it is "up". When
it's removed or disabled due to disabling wireless or networking, bring
it down.
* include/NetworkManager.h: Add new device state NM_DEVICE_STATE_DOWN.
* src/nm-device-802-11-wireless.c:
* src/nm-device-802-3-ethernet.c:
* src/nm-device.c:
- Remove "init" virtual function, all gobjects have a place for that
already (constructor).
- Replace "start" virtual function with "bring_up", devices can be
brought up and down more than just on startup now.
- Add "is_up" virtual function.
- Implement one way to bring a device down instead of previous 4 different
ways, each of witch did something different.
* src/NetworkManagerUtils.c (nm_dev_sock_open): This doesn't need an NMDevice,
all it needs is the device interface.
Get rid of NMData.dev_list (3 members to go).
Get rif of NMData in a lot of places.
* gnome/libnm_glib/libnm_glib.c: Make it compile again.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2395 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2007-03-02 09:30:48 +00:00
|
|
|
|
2012-10-06 12:37:34 -05:00
|
|
|
/* Track re-entry */
|
2013-05-20 16:15:37 -03:00
|
|
|
g_warn_if_fail (priv->in_state_changed == FALSE);
|
|
|
|
|
priv->in_state_changed = TRUE;
|
2012-10-06 12:37:34 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
2007-02-05 12:14:09 +00:00
|
|
|
|
2010-07-01 10:32:11 -07:00
|
|
|
/* Do nothing if state isn't changing, but as a special case allow
|
|
|
|
|
* re-setting UNAVAILABLE if the device is missing firmware so that we
|
|
|
|
|
* can retry device initialization.
|
|
|
|
|
*/
|
|
|
|
|
if ( (priv->state == state)
|
2012-10-10 17:30:46 +02:00
|
|
|
&& !(state == NM_DEVICE_STATE_UNAVAILABLE && priv->firmware_missing)) {
|
2013-05-20 16:15:37 -03:00
|
|
|
priv->in_state_changed = FALSE;
|
2008-03-24 02:56:25 +00:00
|
|
|
return;
|
2012-10-10 17:30:46 +02:00
|
|
|
}
|
2008-03-24 02:56:25 +00:00
|
|
|
|
2008-04-27 14:30:06 +00:00
|
|
|
old_state = priv->state;
|
|
|
|
|
priv->state = state;
|
2012-01-29 22:40:37 +01:00
|
|
|
priv->state_reason = reason;
|
2009-05-12 12:05:47 -04:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "device state change: %s -> %s (reason '%s') [%d %d %d]",
|
|
|
|
|
state_to_string (old_state),
|
|
|
|
|
state_to_string (state),
|
|
|
|
|
reason_to_string (reason),
|
|
|
|
|
old_state,
|
|
|
|
|
state,
|
|
|
|
|
reason);
|
2007-02-05 12:14:09 +00:00
|
|
|
|
2011-12-08 11:46:58 -06:00
|
|
|
/* Clear any queued transitions */
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_queued_state_clear (self);
|
2007-06-13 11:58:25 +00:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
dispatcher_cleanup (self);
|
2014-05-20 17:10:42 -05:00
|
|
|
|
2008-04-27 14:30:06 +00:00
|
|
|
/* Cache the activation request for the dispatcher */
|
|
|
|
|
req = priv->act_request ? g_object_ref (priv->act_request) : NULL;
|
|
|
|
|
|
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
|
|
|
if (state <= NM_DEVICE_STATE_UNAVAILABLE) {
|
2014-07-15 13:36:24 +02:00
|
|
|
_clear_available_connections (self, TRUE);
|
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
|
|
|
g_clear_object (&priv->queued_act_request);
|
|
|
|
|
}
|
2012-08-01 11:16:48 -06:00
|
|
|
|
|
|
|
|
/* Update the available connections list when a device first becomes available */
|
|
|
|
|
if ( state >= NM_DEVICE_STATE_DISCONNECTED
|
|
|
|
|
&& old_state < NM_DEVICE_STATE_DISCONNECTED)
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_recheck_available_connections (self);
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2008-04-17 23:04:34 +00:00
|
|
|
/* Handle the new state here; but anything that could trigger
|
|
|
|
|
* another state change should be done below.
|
|
|
|
|
*/
|
2007-02-05 12:14:09 +00:00
|
|
|
switch (state) {
|
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
|
|
|
case NM_DEVICE_STATE_UNMANAGED:
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_firmware_missing (self, FALSE);
|
2013-06-12 10:48:03 -05:00
|
|
|
if (old_state > NM_DEVICE_STATE_UNMANAGED) {
|
|
|
|
|
/* Clean up if the device is now unmanaged but was activated */
|
2014-07-15 13:36:24 +02:00
|
|
|
if (nm_device_get_act_request (self))
|
|
|
|
|
nm_device_cleanup (self, reason);
|
|
|
|
|
nm_device_take_down (self, TRUE);
|
2014-07-24 17:14:30 -05:00
|
|
|
set_nm_ipv6ll (self, FALSE);
|
2014-07-15 13:36:24 +02:00
|
|
|
restore_ip6_properties (self);
|
2013-06-12 10:48:03 -05:00
|
|
|
}
|
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
|
|
|
break;
|
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
|
|
|
case NM_DEVICE_STATE_UNAVAILABLE:
|
2013-10-24 13:55:06 -04:00
|
|
|
if (old_state == NM_DEVICE_STATE_UNMANAGED) {
|
2014-07-15 13:36:24 +02:00
|
|
|
save_ip6_properties (self);
|
2014-02-21 17:12:00 -05:00
|
|
|
if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) {
|
2014-07-24 17:14:30 -05:00
|
|
|
set_nm_ipv6ll (self, TRUE);
|
|
|
|
|
set_disable_ipv6 (self, "1");
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0");
|
|
|
|
|
nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0");
|
|
|
|
|
nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0");
|
|
|
|
|
nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0");
|
2014-02-21 17:12:00 -05:00
|
|
|
}
|
2013-10-24 13:55:06 -04:00
|
|
|
}
|
|
|
|
|
|
2010-07-01 10:32:11 -07:00
|
|
|
if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) {
|
2014-07-15 13:36:24 +02:00
|
|
|
if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware)
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_HW, "firmware may be missing.");
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_set_firmware_missing (self, no_firmware ? TRUE : FALSE);
|
2008-08-18 18:29:47 +00:00
|
|
|
}
|
2009-08-05 18:03:09 -04:00
|
|
|
/* Ensure the device gets deactivated in response to stuff like
|
|
|
|
|
* carrier changes or rfkill. But don't deactivate devices that are
|
|
|
|
|
* about to assume a connection since that defeats the purpose of
|
|
|
|
|
* assuming the device's existing connection.
|
2013-10-24 12:36:22 -04:00
|
|
|
*
|
|
|
|
|
* Note that we "deactivate" the device even when coming from
|
|
|
|
|
* UNMANAGED, to ensure that it's in a clean state.
|
2009-08-05 18:03:09 -04:00
|
|
|
*/
|
2013-10-24 12:36:22 -04:00
|
|
|
if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED)
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_cleanup (self, reason);
|
2009-08-05 18:03:09 -04:00
|
|
|
break;
|
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
|
|
|
case NM_DEVICE_STATE_DISCONNECTED:
|
2014-07-24 17:14:30 -05:00
|
|
|
/* Ensure devices that previously assumed a connection now have
|
|
|
|
|
* userspace IPv6LL enabled.
|
|
|
|
|
*/
|
|
|
|
|
if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED)
|
|
|
|
|
set_nm_ipv6ll (self, TRUE);
|
|
|
|
|
|
2013-11-04 19:51:28 -06:00
|
|
|
if (old_state > NM_DEVICE_STATE_UNAVAILABLE)
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_cleanup (self, reason);
|
2007-03-02 Tambet Ingo <tambet@ximian.com>
* libnm-glib/nm-device-802-11-wireless.c: Cache networks (bssids) list.
We get signalled when it changes.
* libnm-glib/nm-client.c: Cache NMState and device list, we get signalled
when it changes.
* libnm-glib/nm-device.c: Cache the device state property.
* libnm-glib/nm-access-point.c: Cache the strength property.
* src/nm-device-802-11-wireless.c: Fix wireless device scanning scheduler.
The new algorithm is to start from SCAN_INTERVAL_MIN (currently defined as 0)
and add a SCAN_INTERVAL_STEP (currently 20 seconds) with each successful scan
until SCAN_INTERVAL_MAX (currently 120 seconds) is reached. Do not scan while
the device is down, activating, or activated (in case of A/B/G cards).
Remove some old dead ifdef'ed out code that used to configure wireless devices,
it's all done through supplicant now.
* src/supplicant-manager/nm-supplicant-interface.c: Fix the reference
counting issues with pending calls which caused leaks and crashes when
interface was removed (now that the interface actually gets removed).
* src/nm-call-store.c: Make a copy of data before running a foreach
with user callback on it - The most common usage pattern is to cancel
(and thus remove) all pending calls with foreach which would modify
the hash table we're iterating over.
* src/nm-manager.c: When a device is added, make sure it is "up". When
it's removed or disabled due to disabling wireless or networking, bring
it down.
* include/NetworkManager.h: Add new device state NM_DEVICE_STATE_DOWN.
* src/nm-device-802-11-wireless.c:
* src/nm-device-802-3-ethernet.c:
* src/nm-device.c:
- Remove "init" virtual function, all gobjects have a place for that
already (constructor).
- Replace "start" virtual function with "bring_up", devices can be
brought up and down more than just on startup now.
- Add "is_up" virtual function.
- Implement one way to bring a device down instead of previous 4 different
ways, each of witch did something different.
* src/NetworkManagerUtils.c (nm_dev_sock_open): This doesn't need an NMDevice,
all it needs is the device interface.
Get rid of NMData.dev_list (3 members to go).
Get rif of NMData in a lot of places.
* gnome/libnm_glib/libnm_glib.c: Make it compile again.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2395 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2007-03-02 09:30:48 +00:00
|
|
|
break;
|
2008-04-17 23:04:34 +00:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-13 14:37:26 +01:00
|
|
|
/* Reset autoconnect flag when the device is activating or connected. */
|
|
|
|
|
if ( state >= NM_DEVICE_STATE_PREPARE
|
|
|
|
|
&& state <= NM_DEVICE_STATE_ACTIVATED)
|
|
|
|
|
priv->autoconnect = TRUE;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_STATE);
|
|
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_STATE_REASON);
|
|
|
|
|
g_signal_emit_by_name (self, "state-changed", state, old_state, reason);
|
2008-04-17 23:04:34 +00:00
|
|
|
|
2008-04-27 14:30:06 +00:00
|
|
|
/* Post-process the event after internal notification */
|
|
|
|
|
|
2008-04-17 23:04:34 +00:00
|
|
|
switch (state) {
|
2009-09-14 13:24:29 -07:00
|
|
|
case NM_DEVICE_STATE_UNAVAILABLE:
|
|
|
|
|
/* If the device can activate now (ie, it's got a carrier, the supplicant
|
|
|
|
|
* is active, or whatever) schedule a delayed transition to DISCONNECTED
|
2010-09-25 00:34:10 -05:00
|
|
|
* to get things rolling. The device can't transition immediately because
|
2009-09-14 13:24:29 -07:00
|
|
|
* we can't change states again from the state handler for a variety of
|
|
|
|
|
* reasons.
|
|
|
|
|
*/
|
2014-07-15 13:36:24 +02:00
|
|
|
if (nm_device_is_available (self)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "device is available, will transition to DISCONNECTED");
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE);
|
2010-04-08 15:51:54 -07:00
|
|
|
} else {
|
2014-02-12 23:54:26 +01:00
|
|
|
if (old_state == NM_DEVICE_STATE_UNMANAGED)
|
|
|
|
|
_LOGD (LOGD_DEVICE, "device not yet available for transition to DISCONNECTED");
|
|
|
|
|
else if ( old_state > NM_DEVICE_STATE_UNAVAILABLE
|
|
|
|
|
&& nm_device_get_default_unmanaged (self))
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_queue_state (self, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE);
|
2010-04-07 16:41:44 -07:00
|
|
|
}
|
2009-09-14 13:24:29 -07:00
|
|
|
break;
|
2014-01-03 13:58:05 -05:00
|
|
|
case NM_DEVICE_STATE_DEACTIVATING:
|
2014-05-23 18:25:05 -05:00
|
|
|
if (quitting) {
|
|
|
|
|
nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN,
|
|
|
|
|
nm_act_request_get_connection (req),
|
2014-07-15 13:36:24 +02:00
|
|
|
self);
|
2014-05-23 18:25:05 -05:00
|
|
|
} else {
|
2014-06-12 14:20:14 +02:00
|
|
|
priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED;
|
|
|
|
|
priv->dispatcher.post_state_reason = reason;
|
2014-05-23 18:25:05 -05:00
|
|
|
if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN,
|
|
|
|
|
nm_act_request_get_connection (req),
|
2014-07-15 13:36:24 +02:00
|
|
|
self,
|
2014-06-12 14:20:14 +02:00
|
|
|
dispatcher_complete_proceed_state,
|
2014-07-15 13:36:24 +02:00
|
|
|
self,
|
2014-06-12 14:20:14 +02:00
|
|
|
&priv->dispatcher.call_id)) {
|
2014-05-23 18:25:05 -05:00
|
|
|
/* Just proceed on errors */
|
2014-07-15 13:36:24 +02:00
|
|
|
dispatcher_complete_proceed_state (0, self);
|
2014-05-23 18:25:05 -05:00
|
|
|
}
|
2014-05-20 17:10:42 -05:00
|
|
|
}
|
2014-01-03 13:58:05 -05:00
|
|
|
break;
|
2013-04-24 10:40:58 -04:00
|
|
|
case NM_DEVICE_STATE_DISCONNECTED:
|
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
|
|
|
if (priv->queued_act_request) {
|
|
|
|
|
NMActRequest *queued_req;
|
|
|
|
|
|
|
|
|
|
queued_req = priv->queued_act_request;
|
|
|
|
|
priv->queued_act_request = NULL;
|
2014-07-15 13:36:24 +02:00
|
|
|
_device_activate (self, queued_req);
|
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
|
|
|
g_object_unref (queued_req);
|
2014-03-31 21:45:54 -05:00
|
|
|
} else if ( old_state > NM_DEVICE_STATE_DISCONNECTED
|
2014-07-15 13:36:24 +02:00
|
|
|
&& nm_device_get_default_unmanaged (self))
|
|
|
|
|
nm_device_queue_state (self, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE);
|
2013-04-24 10:40:58 -04:00
|
|
|
break;
|
2007-02-05 12:14:09 +00:00
|
|
|
case NM_DEVICE_STATE_ACTIVATED:
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE, "Activation: successful, device activated.");
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_dispatcher_call (DISPATCHER_ACTION_UP, nm_act_request_get_connection (req), self, NULL, NULL, NULL);
|
2007-02-05 12:14:09 +00:00
|
|
|
break;
|
|
|
|
|
case NM_DEVICE_STATE_FAILED:
|
2014-07-15 13:36:24 +02:00
|
|
|
connection = nm_device_get_connection (self);
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE | LOGD_WIFI,
|
|
|
|
|
"Activation: failed for connection '%s'",
|
|
|
|
|
connection ? nm_connection_get_id (connection) : "<unknown>");
|
2012-09-12 22:44:31 -05:00
|
|
|
|
2012-11-14 14:05:30 -06:00
|
|
|
/* Notify any slaves of the unexpected failure */
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_master_release_slaves (self);
|
2012-11-14 14:05:30 -06:00
|
|
|
|
2012-09-12 22:44:31 -05:00
|
|
|
/* If the connection doesn't yet have a timestamp, set it to zero so that
|
|
|
|
|
* we can distinguish between connections we've tried to activate and have
|
|
|
|
|
* failed (zero timestamp), connections that succeeded (non-zero timestamp),
|
|
|
|
|
* and those we haven't tried yet (no timestamp).
|
|
|
|
|
*/
|
2013-09-17 18:59:48 +02:00
|
|
|
if (connection && !nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (connection), NULL)) {
|
2012-09-12 22:44:31 -05:00
|
|
|
nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (connection),
|
|
|
|
|
(guint64) 0,
|
|
|
|
|
TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-14 13:24:29 -07:00
|
|
|
/* Schedule the transition to DISCONNECTED. The device can't transition
|
2010-09-25 00:34:10 -05:00
|
|
|
* immediately because we can't change states again from the state
|
2009-09-14 13:24:29 -07:00
|
|
|
* handler for a variety of reasons.
|
|
|
|
|
*/
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE);
|
2007-02-05 12:14:09 +00:00
|
|
|
break;
|
2013-06-11 17:05:49 -05:00
|
|
|
case NM_DEVICE_STATE_IP_CHECK:
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_start_ip_check (self);
|
2013-10-09 13:55:05 -05:00
|
|
|
|
|
|
|
|
/* IP-related properties are only valid when the device has IP configuration;
|
|
|
|
|
* now that it does, ensure their change notifications are emitted.
|
|
|
|
|
*/
|
2014-07-15 13:36:24 +02:00
|
|
|
notify_ip_properties (self);
|
2013-06-11 17:05:49 -05:00
|
|
|
break;
|
2012-08-21 17:49:41 +02:00
|
|
|
case NM_DEVICE_STATE_SECONDARIES:
|
2014-07-15 13:36:24 +02:00
|
|
|
ip_check_gw_ping_cleanup (self);
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "device entered SECONDARIES state");
|
2012-08-21 17:49:41 +02:00
|
|
|
break;
|
2007-02-05 12:14:09 +00:00
|
|
|
default:
|
|
|
|
|
break;
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
2008-04-27 14:30:06 +00:00
|
|
|
|
2013-08-07 11:41:40 +02:00
|
|
|
if (state > NM_DEVICE_STATE_DISCONNECTED)
|
2014-07-15 13:36:24 +02:00
|
|
|
delete_on_deactivate_unschedule (self);
|
2013-08-07 11:41:40 +02:00
|
|
|
|
2014-05-20 17:10:42 -05:00
|
|
|
if ( (old_state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_DEACTIVATING)
|
2014-05-23 18:25:05 -05:00
|
|
|
&& (state != NM_DEVICE_STATE_DEACTIVATING)) {
|
|
|
|
|
if (quitting)
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_dispatcher_call_sync (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), self);
|
2014-05-23 18:25:05 -05:00
|
|
|
else
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_dispatcher_call (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), self, NULL, NULL, NULL);
|
2014-05-23 18:25:05 -05:00
|
|
|
}
|
2008-04-27 14:30:06 +00:00
|
|
|
|
2013-10-09 13:55:05 -05:00
|
|
|
/* IP-related properties are only valid when the device has IP configuration.
|
|
|
|
|
* If it no longer does, ensure their change notifications are emitted.
|
|
|
|
|
*/
|
|
|
|
|
if (ip_config_valid (old_state) && !ip_config_valid (state))
|
2014-07-15 13:36:24 +02:00
|
|
|
notify_ip_properties (self);
|
2013-10-09 13:55:05 -05:00
|
|
|
|
2008-04-27 14:30:06 +00:00
|
|
|
/* Dispose of the cached activation request */
|
|
|
|
|
if (req)
|
|
|
|
|
g_object_unref (req);
|
2012-10-06 12:37:34 -05:00
|
|
|
|
2013-05-20 16:15:37 -03:00
|
|
|
priv->in_state_changed = FALSE;
|
2007-02-05 12:14:09 +00:00
|
|
|
}
|
|
|
|
|
|
2014-05-23 18:25:05 -05:00
|
|
|
void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_state_changed (NMDevice *self,
|
2014-05-23 18:25:05 -05:00
|
|
|
NMDeviceState state,
|
|
|
|
|
NMDeviceStateReason reason)
|
|
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
_set_state_full (self, state, reason, FALSE);
|
2014-05-23 18:25:05 -05:00
|
|
|
}
|
|
|
|
|
|
2011-12-08 11:46:58 -06:00
|
|
|
static gboolean
|
|
|
|
|
queued_set_state (gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (user_data);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2012-11-14 18:00:22 -06:00
|
|
|
NMDeviceState new_state;
|
|
|
|
|
NMDeviceStateReason new_reason;
|
2011-12-08 11:46:58 -06:00
|
|
|
|
|
|
|
|
if (priv->queued_state.id) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "running queued state change to %s (id %d)",
|
|
|
|
|
state_to_string (priv->queued_state.state),
|
|
|
|
|
priv->queued_state.id);
|
2012-11-14 18:00:22 -06:00
|
|
|
|
|
|
|
|
/* Clear queued state struct before triggering state change, since
|
|
|
|
|
* the state change may queue another state.
|
|
|
|
|
*/
|
2012-03-13 16:42:01 -05:00
|
|
|
priv->queued_state.id = 0;
|
2012-11-14 18:00:22 -06:00
|
|
|
new_state = priv->queued_state.state;
|
|
|
|
|
new_reason = priv->queued_state.reason;
|
|
|
|
|
nm_device_queued_state_clear (self);
|
|
|
|
|
|
|
|
|
|
nm_device_state_changed (self, new_state, new_reason);
|
2014-04-28 11:18:05 +02:00
|
|
|
nm_device_remove_pending_action (self, queued_state_to_string (new_state), TRUE);
|
2012-11-14 18:00:22 -06:00
|
|
|
} else {
|
|
|
|
|
g_warn_if_fail (priv->queued_state.state == NM_DEVICE_STATE_UNKNOWN);
|
|
|
|
|
g_warn_if_fail (priv->queued_state.reason == NM_DEVICE_STATE_REASON_NONE);
|
2011-12-08 11:46:58 -06:00
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_device_queue_state (NMDevice *self,
|
|
|
|
|
NMDeviceState state,
|
|
|
|
|
NMDeviceStateReason reason)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (NM_IS_DEVICE (self));
|
|
|
|
|
|
|
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (priv->queued_state.id && priv->queued_state.state == state)
|
|
|
|
|
return;
|
2013-04-04 10:20:24 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* Add pending action for the new state before clearing the queued states, so
|
|
|
|
|
* that we don't accidently pop all pending states and reach 'startup complete' */
|
|
|
|
|
nm_device_add_pending_action (self, queued_state_to_string (state), TRUE);
|
2013-11-02 10:38:23 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* We should only ever have one delayed state transition at a time */
|
|
|
|
|
if (priv->queued_state.id) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE, "overwriting previously queued state change to %s (%s)",
|
|
|
|
|
state_to_string (priv->queued_state.state),
|
|
|
|
|
reason_to_string (priv->queued_state.reason));
|
2014-05-20 15:03:27 -05:00
|
|
|
nm_device_queued_state_clear (self);
|
|
|
|
|
}
|
2013-04-04 10:20:24 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
priv->queued_state.state = state;
|
|
|
|
|
priv->queued_state.reason = reason;
|
|
|
|
|
priv->queued_state.id = g_idle_add (queued_set_state, self);
|
2013-04-04 10:20:24 -04:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "queued state change to %s due to %s (id %d)",
|
|
|
|
|
state_to_string (state), reason_to_string (reason),
|
|
|
|
|
priv->queued_state.id);
|
2013-04-04 10:20:24 -04:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
NMDeviceState
|
|
|
|
|
nm_device_queued_state_peek (NMDevice *self)
|
2013-04-04 10:20:24 -04:00
|
|
|
{
|
2014-05-20 15:03:27 -05:00
|
|
|
NMDevicePrivate *priv;
|
2013-04-04 10:20:24 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_STATE_UNKNOWN);
|
2013-04-04 10:20:24 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-04-04 10:20:24 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
return priv->queued_state.id ? priv->queued_state.state : NM_DEVICE_STATE_UNKNOWN;
|
2013-04-04 10:20:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2014-05-20 15:03:27 -05:00
|
|
|
nm_device_queued_state_clear (NMDevice *self)
|
2013-04-04 10:20:24 -04:00
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (priv->queued_state.id) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "clearing queued state transition (id %d)",
|
|
|
|
|
priv->queued_state.id);
|
2014-05-20 15:03:27 -05:00
|
|
|
g_source_remove (priv->queued_state.id);
|
|
|
|
|
nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE);
|
2013-04-04 10:20:24 -04:00
|
|
|
}
|
2014-05-20 15:03:27 -05:00
|
|
|
memset (&priv->queued_state, 0, sizeof (priv->queued_state));
|
2013-04-04 10:20:24 -04:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
NMDeviceState
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_get_state (NMDevice *self)
|
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
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_STATE_UNKNOWN);
|
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
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
return NM_DEVICE_GET_PRIVATE (self)->state;
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
2008-04-07 Dan Williams <dcbw@redhat.com>
* include/NetworkManager.h
- Remove the DOWN and CANCELLED device states
- Add UNMANAGED and UNAVAILABLE device states
- Document the device states
* introspection/nm-device.xml
src/nm-device-interface.c
src/nm-device-interface.h
- Add the 'managed' property
* test/nm-tool.c
- (detail_device): print out device state
* src/NetworkManagerSystem.h
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerDebian.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerMandriva.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerSuSE.c
- (nm_system_device_get_system_config, nm_system_device_get_disabled
nm_system_device_free_system_config): remove; they were unused and
their functionality should be re-implemented in each distro's
system settings service plugin
* src/nm-gsm-device.c
src/nm-gsm-device.h
src/nm-cdma-device.c
src/nm-cdma-device.h
- (*_new): take the 'managed' argument
* src/nm-device.c
- (nm_device_set_address): remove, fold into nm_device_bring_up()
- (nm_device_init): start in unmanaged state, not disconnected
- (constructor): don't start device until the system settings service
has had a chance to figure out if the device is managed or not
- (nm_device_deactivate, nm_device_bring_up, nm_device_bring_down):
don't set device state here, let callers handle that as appropriate
- (nm_device_dispose): don't touch the device if it's not managed
- (set_property, get_property, nm_device_class_init): implement the
'managed' property
- (nm_device_state_changed): bring the device up if its now managed,
and deactivate it if it used to be active
- (nm_device_get_managed, nm_device_set_managed): do the right thing
with the managed state
* src/nm-hal-manager.c
- (wired_device_creator, wireless_device_creator, modem_device_creator):
take initial managed state and pass it along to device constructors
- (create_device_and_add_to_list): get managed state and pass to
type creators
* src/nm-device-802-11-wireless.c
- (real_can_activate): fold in most of
nm_device_802_11_wireless_can_activate()
- (can_scan): can't scan in UNAVAILABLE or UNMANAGED
- (link_timeout_cb): instead of deactivating, change device state and
let the device state handler to it
- (real_update_hw_address): clean up
- (state_changed_cb): when entering UNAVAILABLE state, schedule an idle
handler to transition to DISCONNECTED if the device isn't rfkilled
* src/nm-device-802-3-ethernet.c
- (set_carrier): move above callers and get rid of prototype
- (device_state_changed): when entering UNAVAILABLE state, schedule an
idle handler to transition to DISCONNECTED if the device has a
carrier
- (real_update_hw_address): clean up
- (link_timeout_cb, ppp_state_changed): change state instead of calling
deactivation directly as deactivation doesn't change state anymore
* src/NetworkManagerPolicy.c
- (schedule_activate_check): yay, remove wireless_enabled hack since
the NMManager and wireless devices work that out themselves now
- (device_state_changed): change to a switch and update for new device
states
- (device_carrier_changed): remove; device handles this now through
state changes
- (device_added): don't care about carrier any more; the initial
activation check will happen when the device transitions to
DISCONNECTED
* src/nm-manager.c
- (dispose): clear unmanaged devices
- (handle_unmanaged_devices): update unmanaged device list and toggle
the managed property on each device when needed
- (system_settings_properties_changed_cb): handle signals from the
system settings service
- (system_settings_get_unmanaged_devices_cb): handle callback from
getting the unmanaged device list method call
- (query_unmanaged_devices): ask the system settings service for its
list of unmanaged devices
- (nm_manager_name_owner_changed, initial_get_connections): get unmanaged
devices
- (manager_set_wireless_enabled): push rfkill state down to wireless
devices directly and let them handle the necessary state transitions
- (manager_device_state_changed): update for new device states
- (nm_manager_add_device): set initial rfkill state on wireless devices
- (nm_manager_remove_device): don't touch the device if it's unmanaged
- (nm_manager_activate_connection): return error if the device is
unmanaged
- (nm_manager_sleep): handle new device states correctly; don't change
the state of unavailable/unmanaged devices
* libnm-glib/nm-device-802-11-wireless.c
- (state_changed_cb): update for new device states
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3540 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-04-08 02:58:02 +00:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/***********************************************************/
|
|
|
|
|
/* NMConfigDevice interface related stuff */
|
2014-03-31 21:45:54 -05:00
|
|
|
|
2014-06-21 12:44:56 -04:00
|
|
|
const char *
|
|
|
|
|
nm_device_get_hw_address (NMDevice *self)
|
2013-04-24 10:40:58 -04:00
|
|
|
{
|
2014-05-20 15:03:27 -05:00
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
|
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-07-14 17:59:45 -05:00
|
|
|
return priv->hw_addr_len ? priv->hw_addr : NULL;
|
2014-03-31 21:45:54 -05:00
|
|
|
}
|
2008-04-22 19:07:00 +00:00
|
|
|
|
2014-07-14 17:59:45 -05:00
|
|
|
static void
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_update_hw_address (NMDevice *self)
|
2014-03-31 21:45:54 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
int ifindex = nm_device_get_ifindex (self);
|
2014-07-14 17:59:45 -05:00
|
|
|
const guint8 *hwaddr;
|
|
|
|
|
gsize hwaddrlen = 0;
|
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
|
|
|
|
2014-07-14 17:59:45 -05:00
|
|
|
if (ifindex <= 0)
|
|
|
|
|
return;
|
2013-04-24 10:40:58 -04:00
|
|
|
|
2014-07-14 17:59:45 -05:00
|
|
|
hwaddr = nm_platform_link_get_address (ifindex, &hwaddrlen);
|
|
|
|
|
g_assert (hwaddrlen <= sizeof (priv->hw_addr));
|
|
|
|
|
if (hwaddrlen) {
|
2014-08-08 11:08:18 -04:00
|
|
|
if (!priv->hw_addr || !nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) {
|
|
|
|
|
g_free (priv->hw_addr);
|
2014-06-21 12:44:56 -04:00
|
|
|
priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen);
|
2014-03-31 21:45:54 -05:00
|
|
|
|
2014-06-21 12:44:56 -04:00
|
|
|
_LOGD (LOGD_HW | LOGD_DEVICE, "hardware address now %s", priv->hw_addr);
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_HW_ADDRESS);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
} else {
|
2014-07-14 17:59:45 -05:00
|
|
|
/* Invalid or no hardware address */
|
|
|
|
|
if (priv->hw_addr_len != 0) {
|
2014-06-21 12:44:56 -04:00
|
|
|
g_clear_pointer (&priv->hw_addr, g_free);
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_HW | LOGD_DEVICE,
|
|
|
|
|
"previous hardware address is no longer valid");
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_notify (G_OBJECT (self), NM_DEVICE_HW_ADDRESS);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
2014-03-31 21:45:54 -05:00
|
|
|
}
|
2014-07-14 17:59:45 -05:00
|
|
|
priv->hw_addr_len = hwaddrlen;
|
2013-04-24 10:40:58 -04:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
gboolean
|
2014-07-30 10:57:45 -04:00
|
|
|
nm_device_set_hw_addr (NMDevice *self, const char *addr,
|
2014-05-20 15:03:27 -05:00
|
|
|
const char *detail, guint64 hw_log_domain)
|
2013-04-24 10:40:58 -04:00
|
|
|
{
|
2014-06-21 12:44:56 -04:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
gboolean success = FALSE;
|
2014-06-21 12:44:56 -04:00
|
|
|
const char *cur_addr = nm_device_get_hw_address (self);
|
2014-07-30 10:57:45 -04:00
|
|
|
guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX];
|
2013-04-24 10:40:58 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_return_val_if_fail (addr != NULL, FALSE);
|
2013-04-24 10:40:58 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* Do nothing if current MAC is same */
|
2014-07-30 10:57:45 -04:00
|
|
|
if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE | hw_log_domain, "no MAC address change needed");
|
2014-05-20 15:03:27 -05:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
2014-07-30 10:57:45 -04:00
|
|
|
if (!nm_utils_hwaddr_aton (addr, addr_bytes, priv->hw_addr_len)) {
|
|
|
|
|
_LOGW (LOGD_DEVICE | hw_log_domain, "invalid MAC address %s", addr);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
/* Can't change MAC address while device is up */
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_take_down (self, FALSE);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-07-30 10:57:45 -04:00
|
|
|
success = nm_platform_link_set_address (nm_device_get_ip_ifindex (self), addr_bytes, priv->hw_addr_len);
|
2014-05-20 15:03:27 -05:00
|
|
|
if (success) {
|
|
|
|
|
/* MAC address succesfully changed; update the current MAC to match */
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_update_hw_address (self);
|
2014-06-21 12:44:56 -04:00
|
|
|
cur_addr = nm_device_get_hw_address (self);
|
2014-07-30 10:57:45 -04:00
|
|
|
if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_DEVICE | hw_log_domain, "%s MAC address to %s",
|
2014-07-30 10:57:45 -04:00
|
|
|
detail, addr);
|
2014-05-20 15:03:27 -05:00
|
|
|
} else {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE | hw_log_domain,
|
2014-07-30 10:57:45 -04:00
|
|
|
"new MAC address %s not successfully set", addr);
|
2014-05-20 15:03:27 -05:00
|
|
|
success = FALSE;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_DEVICE | hw_log_domain, "failed to %s MAC address to %s",
|
2014-07-30 10:57:45 -04:00
|
|
|
detail, addr);
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_bring_up (self, TRUE, NULL);
|
2013-04-24 10:40:58 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
return success;
|
2013-04-24 10:40:58 -04:00
|
|
|
}
|
|
|
|
|
|
2013-03-13 13:52:55 -04:00
|
|
|
/**
|
|
|
|
|
* nm_device_spec_match_list:
|
2014-07-15 13:36:24 +02:00
|
|
|
* @self: an #NMDevice
|
2013-03-13 13:52:55 -04:00
|
|
|
* @specs: (element-type utf8): a list of device specs
|
|
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* Checks if @self matches any of the specifications in @specs. The
|
2013-03-13 13:52:55 -04:00
|
|
|
* currently-supported spec types are:
|
|
|
|
|
*
|
|
|
|
|
* "mac:00:11:22:33:44:55" - matches a device with the given
|
|
|
|
|
* hardware address
|
|
|
|
|
*
|
|
|
|
|
* "interface-name:foo0" - matches a device with the given
|
|
|
|
|
* interface name
|
|
|
|
|
*
|
|
|
|
|
* "s390-subchannels:00.11.22" - matches a device with the given
|
|
|
|
|
* z/VM / s390 subchannels.
|
|
|
|
|
*
|
2013-03-20 09:48:24 -04:00
|
|
|
* "*" - matches any device
|
|
|
|
|
*
|
2014-07-15 13:36:24 +02:00
|
|
|
* Returns: #TRUE if @self matches one of the specs in @specs
|
2013-03-13 13:52:55 -04:00
|
|
|
*/
|
2011-11-17 23:16:50 -06:00
|
|
|
gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_spec_match_list (NMDevice *self, const GSList *specs)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2013-09-23 09:44:32 -04:00
|
|
|
if (!specs)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
return NM_DEVICE_GET_CLASS (self)->spec_match_list (self, specs);
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
|
2013-02-12 17:59:37 -05:00
|
|
|
static gboolean
|
2014-07-15 13:36:24 +02:00
|
|
|
spec_match_list (NMDevice *self, const GSList *specs)
|
2013-02-12 17:59:37 -05:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2013-03-25 15:17:35 -05:00
|
|
|
gboolean matched = FALSE;
|
2013-02-12 17:59:37 -05:00
|
|
|
|
2013-03-20 09:48:24 -04:00
|
|
|
if (nm_match_spec_string (specs, "*"))
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
2014-06-21 12:44:56 -04:00
|
|
|
if (priv->hw_addr_len)
|
|
|
|
|
matched = nm_match_spec_hwaddr (specs, priv->hw_addr);
|
2013-02-12 17:59:37 -05:00
|
|
|
|
2013-02-12 18:00:48 -05:00
|
|
|
if (!matched)
|
2014-07-15 13:36:24 +02:00
|
|
|
matched = nm_match_spec_interface_name (specs, nm_device_get_iface (self));
|
2013-02-12 18:00:48 -05:00
|
|
|
|
2013-02-12 17:59:37 -05:00
|
|
|
return matched;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/***********************************************************/
|
|
|
|
|
|
|
|
|
|
#define DEFAULT_AUTOCONNECT TRUE
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
nm_device_init (NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
|
|
|
|
|
priv->type = NM_DEVICE_TYPE_UNKNOWN;
|
|
|
|
|
priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED;
|
|
|
|
|
priv->state = NM_DEVICE_STATE_UNMANAGED;
|
|
|
|
|
priv->state_reason = NM_DEVICE_STATE_REASON_NONE;
|
|
|
|
|
priv->dhcp_timeout = 0;
|
|
|
|
|
priv->rfkill_type = RFKILL_TYPE_UNKNOWN;
|
|
|
|
|
priv->autoconnect = DEFAULT_AUTOCONNECT;
|
|
|
|
|
priv->unmanaged_flags = NM_UNMANAGED_INTERNAL;
|
|
|
|
|
priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
|
|
|
|
|
priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Get driver info from SIOCETHTOOL ioctl() for 'iface'
|
|
|
|
|
* Returns driver and firmware versions to 'driver_version and' 'firmware_version'
|
|
|
|
|
*/
|
|
|
|
|
static gboolean
|
2014-02-12 23:54:26 +01:00
|
|
|
device_get_driver_info (NMDevice *self, const char *iface, char **driver_version, char **firmware_version)
|
2014-05-20 15:03:27 -05:00
|
|
|
{
|
|
|
|
|
struct ethtool_drvinfo drvinfo;
|
|
|
|
|
struct ifreq req;
|
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
|
|
fd = socket (PF_INET, SOCK_DGRAM, 0);
|
|
|
|
|
if (fd < 0) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_HW, "couldn't open control socket.");
|
2014-05-20 15:03:27 -05:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get driver and firmware version info */
|
|
|
|
|
memset (&drvinfo, 0, sizeof (drvinfo));
|
|
|
|
|
memset (&req, 0, sizeof (struct ifreq));
|
|
|
|
|
strncpy (req.ifr_name, iface, IFNAMSIZ);
|
|
|
|
|
drvinfo.cmd = ETHTOOL_GDRVINFO;
|
|
|
|
|
req.ifr_data = &drvinfo;
|
|
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
|
if (ioctl (fd, SIOCETHTOOL, &req) < 0) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_HW, "SIOCETHTOOL ioctl() failed: cmd=ETHTOOL_GDRVINFO, iface=%s, errno=%d",
|
|
|
|
|
iface, errno);
|
2014-05-20 15:03:27 -05:00
|
|
|
close (fd);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
if (driver_version)
|
|
|
|
|
*driver_version = g_strdup (drvinfo.version);
|
|
|
|
|
if (firmware_version)
|
|
|
|
|
*firmware_version = g_strdup (drvinfo.fw_version);
|
|
|
|
|
|
|
|
|
|
close (fd);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GObject*
|
|
|
|
|
constructor (GType type,
|
|
|
|
|
guint n_construct_params,
|
|
|
|
|
GObjectConstructParam *construct_params)
|
|
|
|
|
{
|
|
|
|
|
GObject *object;
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevice *self;
|
2014-05-20 15:03:27 -05:00
|
|
|
NMDevicePrivate *priv;
|
|
|
|
|
NMPlatform *platform;
|
|
|
|
|
static guint32 id = 0;
|
|
|
|
|
|
|
|
|
|
object = G_OBJECT_CLASS (nm_device_parent_class)->constructor (type,
|
|
|
|
|
n_construct_params,
|
|
|
|
|
construct_params);
|
|
|
|
|
if (!object)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
self = NM_DEVICE (object);
|
|
|
|
|
priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGD (LOGD_DEVICE, "constructor(): %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), priv->ifindex);
|
2014-02-12 23:54:26 +01:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (!priv->iface) {
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGE (LOGD_DEVICE, "No device interface provided, ignoring");
|
2014-05-20 15:03:27 -05:00
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!priv->udi) {
|
|
|
|
|
/* Use a placeholder UDI until we get a real one */
|
|
|
|
|
priv->udi = g_strdup_printf ("/virtual/device/placeholder/%d", id++);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
|
|
|
|
|
priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
device_get_driver_info (self, priv->iface, &priv->driver_version, &priv->firmware_version);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
/* Watch for external IP config changes */
|
|
|
|
|
platform = nm_platform_get ();
|
2014-07-15 13:36:24 +02:00
|
|
|
g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (device_ip_changed), self);
|
|
|
|
|
g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (device_ip_changed), self);
|
|
|
|
|
g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (device_ip_changed), self);
|
|
|
|
|
g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ip_changed), self);
|
|
|
|
|
g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-07-24 17:14:30 -05:00
|
|
|
if (nm_platform_check_support_user_ipv6ll ()) {
|
|
|
|
|
int ip_ifindex = nm_device_get_ip_ifindex (self);
|
|
|
|
|
|
|
|
|
|
if (ip_ifindex > 0)
|
|
|
|
|
priv->nm_ipv6ll = nm_platform_link_get_user_ipv6ll_enabled (ip_ifindex);
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
return object;
|
|
|
|
|
|
|
|
|
|
error:
|
2014-07-15 13:36:24 +02:00
|
|
|
g_object_unref (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
constructed (GObject *object)
|
|
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevice *self = NM_DEVICE (object);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
nm_device_update_hw_address (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (NM_DEVICE_GET_CLASS (self)->update_permanent_hw_address)
|
|
|
|
|
NM_DEVICE_GET_CLASS (self)->update_permanent_hw_address (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
if (NM_DEVICE_GET_CLASS (self)->update_initial_hw_address)
|
|
|
|
|
NM_DEVICE_GET_CLASS (self)->update_initial_hw_address (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
/* Have to call update_initial_hw_address() before calling get_ignore_carrier() */
|
2014-07-15 13:36:24 +02:00
|
|
|
if (device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
|
|
|
|
|
priv->ignore_carrier = nm_config_get_ignore_carrier (nm_config_get (), self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
2014-07-15 13:36:24 +02:00
|
|
|
check_carrier (self);
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGI (LOGD_HW,
|
|
|
|
|
"carrier is %s%s",
|
|
|
|
|
priv->carrier ? "ON" : "OFF",
|
|
|
|
|
priv->ignore_carrier ? " (but ignored)" : "");
|
2014-05-20 15:03:27 -05:00
|
|
|
} else {
|
|
|
|
|
/* Fake online link when carrier detection is not available. */
|
|
|
|
|
priv->carrier = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (priv->ifindex > 0) {
|
|
|
|
|
priv->is_software = nm_platform_link_is_software (priv->ifindex);
|
|
|
|
|
priv->physical_port_id = nm_platform_link_get_physical_port_id (priv->ifindex);
|
|
|
|
|
priv->mtu = nm_platform_link_get_mtu (priv->ifindex);
|
2014-06-19 11:24:16 +02:00
|
|
|
}
|
|
|
|
|
/* Indicate software device in capabilities. */
|
|
|
|
|
if (priv->is_software)
|
|
|
|
|
priv->capabilities |= NM_DEVICE_CAP_IS_SOFTWARE;
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
priv->con_provider = nm_connection_provider_get ();
|
|
|
|
|
g_assert (priv->con_provider);
|
|
|
|
|
g_signal_connect (priv->con_provider,
|
|
|
|
|
NM_CP_SIGNAL_CONNECTION_ADDED,
|
|
|
|
|
G_CALLBACK (cp_connection_added),
|
2014-07-15 13:36:24 +02:00
|
|
|
self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
g_signal_connect (priv->con_provider,
|
|
|
|
|
NM_CP_SIGNAL_CONNECTION_REMOVED,
|
|
|
|
|
G_CALLBACK (cp_connection_removed),
|
2014-07-15 13:36:24 +02:00
|
|
|
self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
g_signal_connect (priv->con_provider,
|
|
|
|
|
NM_CP_SIGNAL_CONNECTION_UPDATED,
|
|
|
|
|
G_CALLBACK (cp_connection_updated),
|
2014-07-15 13:36:24 +02:00
|
|
|
self);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (nm_device_parent_class)->constructed (object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dispose (GObject *object)
|
|
|
|
|
{
|
|
|
|
|
NMDevice *self = NM_DEVICE (object);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
NMPlatform *platform;
|
|
|
|
|
|
2014-05-20 17:10:42 -05:00
|
|
|
dispatcher_cleanup (self);
|
|
|
|
|
|
core: don't do anything interesting in NMDevice dispose()
The NMDevice dispose() function contained some badly-duplicated logic
about when to deactivate a device on its last ref. This logic should
only run when the device is removed by the manager, since the manager
controls the device's life-cycle, and the manager knows best when to
clean up the device. But since it was tied to the device's refcount,
it could have run later than the manager wanted, or not at all.
It gets better. Dispose duplicated logic that was already done in
nm_device_cleanup(), and then *called* nm_device_cleanup() if the
device was still activated and managed. But the manager already
unmanages the device when removing it, which triggers a call to
nm_device_cleanup(), takes the device down, and resets the IPv6
sysctl properties, which dispose() duplicated too. So by the time
dispose() runs, the device should already be unmanaged if the
manager wants to deconfigure it, and most of the dispose() code
should be a no-op.
Clean all that up and remove duplicated functions. Now, the flow
should be like this:
1) manager decides to remove the device and calls remove_device()
2) if the device should be deconfigured, the manager unmanages
the device
3) the NMDevice state change handler tears down the active connection
via nm_device_cleanup() and resets IPv6 sysctl properties
4) when the device's last reference is finally released, only internal
data members are freed in dispose() because the device should
already have been cleaned up by the manager and be unmanaged
5) if the device should be left running because it has an assumable
connection, then the device is not unmanaged, and no cleanup
happens in the state change handler or in dispose()
2014-05-23 15:41:46 -05:00
|
|
|
_cleanup_generic_pre (self, FALSE);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
g_warn_if_fail (priv->slaves == NULL);
|
|
|
|
|
g_assert (priv->master_ready_id == 0);
|
|
|
|
|
|
2014-07-24 17:14:30 -05:00
|
|
|
/* Let the kernel manage IPv6LL again */
|
|
|
|
|
set_nm_ipv6ll (self, FALSE);
|
|
|
|
|
|
core: don't do anything interesting in NMDevice dispose()
The NMDevice dispose() function contained some badly-duplicated logic
about when to deactivate a device on its last ref. This logic should
only run when the device is removed by the manager, since the manager
controls the device's life-cycle, and the manager knows best when to
clean up the device. But since it was tied to the device's refcount,
it could have run later than the manager wanted, or not at all.
It gets better. Dispose duplicated logic that was already done in
nm_device_cleanup(), and then *called* nm_device_cleanup() if the
device was still activated and managed. But the manager already
unmanages the device when removing it, which triggers a call to
nm_device_cleanup(), takes the device down, and resets the IPv6
sysctl properties, which dispose() duplicated too. So by the time
dispose() runs, the device should already be unmanaged if the
manager wants to deconfigure it, and most of the dispose() code
should be a no-op.
Clean all that up and remove duplicated functions. Now, the flow
should be like this:
1) manager decides to remove the device and calls remove_device()
2) if the device should be deconfigured, the manager unmanages
the device
3) the NMDevice state change handler tears down the active connection
via nm_device_cleanup() and resets IPv6 sysctl properties
4) when the device's last reference is finally released, only internal
data members are freed in dispose() because the device should
already have been cleaned up by the manager and be unmanaged
5) if the device should be left running because it has an assumable
connection, then the device is not unmanaged, and no cleanup
happens in the state change handler or in dispose()
2014-05-23 15:41:46 -05:00
|
|
|
_cleanup_generic_post (self, FALSE);
|
2009-07-15 13:53:49 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_clear_pointer (&priv->ip6_saved_properties, g_hash_table_unref);
|
2009-07-15 13:53:49 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (priv->recheck_assume_id) {
|
|
|
|
|
g_source_remove (priv->recheck_assume_id);
|
|
|
|
|
priv->recheck_assume_id = 0;
|
2009-07-15 13:53:49 -04:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
link_disconnect_action_cancel (self);
|
|
|
|
|
|
|
|
|
|
if (priv->con_provider) {
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_added, self);
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_removed, self);
|
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_updated, self);
|
|
|
|
|
priv->con_provider = NULL;
|
2009-07-15 13:53:49 -04:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_hash_table_unref (priv->available_connections);
|
|
|
|
|
priv->available_connections = NULL;
|
2012-05-14 15:32:54 +02:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
if (priv->carrier_wait_id) {
|
|
|
|
|
g_source_remove (priv->carrier_wait_id);
|
|
|
|
|
priv->carrier_wait_id = 0;
|
|
|
|
|
}
|
2009-09-16 13:18:24 +02:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_clear_object (&priv->queued_act_request);
|
2014-03-05 10:16:39 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
platform = nm_platform_get ();
|
|
|
|
|
g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ip_changed), self);
|
|
|
|
|
g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (link_changed_cb), self);
|
2013-11-04 19:51:28 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
|
2012-08-01 11:16:48 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-05-20 15:03:27 -05:00
|
|
|
finalize (GObject *object)
|
2012-08-01 11:16:48 -06:00
|
|
|
{
|
2014-05-20 15:03:27 -05:00
|
|
|
NMDevice *self = NM_DEVICE (object);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGD (LOGD_DEVICE, "finalize(): %s", G_OBJECT_TYPE_NAME (self));
|
|
|
|
|
|
2014-06-21 12:44:56 -04:00
|
|
|
g_free (priv->hw_addr);
|
2014-05-20 15:03:27 -05:00
|
|
|
g_slist_free_full (priv->pending_actions, g_free);
|
2014-05-22 14:04:01 -05:00
|
|
|
g_clear_pointer (&priv->physical_port_id, g_free);
|
2014-05-20 15:03:27 -05:00
|
|
|
g_free (priv->udi);
|
|
|
|
|
g_free (priv->path);
|
|
|
|
|
g_free (priv->iface);
|
|
|
|
|
g_free (priv->ip_iface);
|
|
|
|
|
g_free (priv->driver);
|
|
|
|
|
g_free (priv->driver_version);
|
|
|
|
|
g_free (priv->firmware_version);
|
|
|
|
|
g_free (priv->type_desc);
|
2014-07-30 10:57:45 -04:00
|
|
|
g_free (priv->dhcp_anycast_address);
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (nm_device_parent_class)->finalize (object);
|
2012-08-01 11:16:48 -06:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static void
|
|
|
|
|
set_property (GObject *object, guint prop_id,
|
|
|
|
|
const GValue *value, GParamSpec *pspec)
|
2013-11-04 19:51:28 -06:00
|
|
|
{
|
2014-07-15 13:36:24 +02:00
|
|
|
NMDevice *self = NM_DEVICE (object);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
2014-05-20 15:03:27 -05:00
|
|
|
NMPlatformLink *platform_device;
|
2014-07-14 17:59:45 -05:00
|
|
|
const char *hw_addr, *p;
|
|
|
|
|
guint count;
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
switch (prop_id) {
|
|
|
|
|
case PROP_PLATFORM_DEVICE:
|
|
|
|
|
platform_device = g_value_get_pointer (value);
|
|
|
|
|
if (platform_device) {
|
|
|
|
|
g_free (priv->udi);
|
|
|
|
|
priv->udi = g_strdup (platform_device->udi);
|
|
|
|
|
g_free (priv->iface);
|
|
|
|
|
priv->iface = g_strdup (platform_device->name);
|
|
|
|
|
priv->ifindex = platform_device->ifindex;
|
|
|
|
|
g_free (priv->driver);
|
|
|
|
|
priv->driver = g_strdup (platform_device->driver);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PROP_UDI:
|
|
|
|
|
if (g_value_get_string (value)) {
|
|
|
|
|
g_free (priv->udi);
|
|
|
|
|
priv->udi = g_value_dup_string (value);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PROP_IFACE:
|
|
|
|
|
if (g_value_get_string (value)) {
|
|
|
|
|
g_free (priv->iface);
|
|
|
|
|
priv->ifindex = 0;
|
|
|
|
|
priv->iface = g_value_dup_string (value);
|
2013-11-04 19:51:28 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* Only look up the ifindex if it appears to be an actual kernel
|
|
|
|
|
* interface name. eg Bluetooth devices won't have one until we know
|
|
|
|
|
* the IP interface.
|
|
|
|
|
*/
|
|
|
|
|
if (priv->iface && !strchr (priv->iface, ':')) {
|
|
|
|
|
priv->ifindex = nm_platform_link_get_ifindex (priv->iface);
|
|
|
|
|
if (priv->ifindex <= 0)
|
2014-02-12 23:54:26 +01:00
|
|
|
_LOGW (LOGD_HW, "failed to look up interface index");
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PROP_DRIVER:
|
|
|
|
|
if (g_value_get_string (value)) {
|
|
|
|
|
g_free (priv->driver);
|
|
|
|
|
priv->driver = g_value_dup_string (value);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PROP_DRIVER_VERSION:
|
|
|
|
|
g_free (priv->driver_version);
|
|
|
|
|
priv->driver_version = g_strdup (g_value_get_string (value));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_FIRMWARE_VERSION:
|
|
|
|
|
g_free (priv->firmware_version);
|
|
|
|
|
priv->firmware_version = g_strdup (g_value_get_string (value));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_MTU:
|
|
|
|
|
priv->mtu = g_value_get_uint (value);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_IP4_ADDRESS:
|
|
|
|
|
priv->ip4_address = g_value_get_uint (value);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_AUTOCONNECT:
|
|
|
|
|
priv->autoconnect = g_value_get_boolean (value);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_FIRMWARE_MISSING:
|
|
|
|
|
priv->firmware_missing = g_value_get_boolean (value);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_DEVICE_TYPE:
|
|
|
|
|
g_return_if_fail (priv->type == NM_DEVICE_TYPE_UNKNOWN);
|
|
|
|
|
priv->type = g_value_get_uint (value);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_TYPE_DESC:
|
|
|
|
|
g_free (priv->type_desc);
|
|
|
|
|
priv->type_desc = g_value_dup_string (value);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_RFKILL_TYPE:
|
|
|
|
|
priv->rfkill_type = g_value_get_uint (value);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_IS_MASTER:
|
|
|
|
|
priv->is_master = g_value_get_boolean (value);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_HW_ADDRESS:
|
2014-07-14 17:59:45 -05:00
|
|
|
/* construct only */
|
|
|
|
|
p = hw_addr = g_value_get_string (value);
|
|
|
|
|
|
|
|
|
|
/* Hardware address length is the number of ':' plus 1 */
|
|
|
|
|
count = 1;
|
|
|
|
|
while (p && *p) {
|
|
|
|
|
if (*p++ == ':')
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
if (count < ETH_ALEN || count > NM_UTILS_HWADDR_LEN_MAX) {
|
2014-06-21 12:44:56 -04:00
|
|
|
if (hw_addr && *hw_addr) {
|
|
|
|
|
_LOGW (LOGD_DEVICE, "ignoring hardware address '%s' with unexpected length %d",
|
|
|
|
|
hw_addr, count);
|
|
|
|
|
}
|
2014-05-20 15:03:27 -05:00
|
|
|
break;
|
|
|
|
|
}
|
2013-11-04 19:51:28 -06:00
|
|
|
|
2014-07-14 17:59:45 -05:00
|
|
|
priv->hw_addr_len = count;
|
2014-06-21 12:44:56 -04:00
|
|
|
g_free (priv->hw_addr);
|
|
|
|
|
if (nm_utils_hwaddr_valid (hw_addr, priv->hw_addr_len))
|
|
|
|
|
priv->hw_addr = g_strdup (hw_addr);
|
|
|
|
|
else {
|
|
|
|
|
_LOGW (LOGD_DEVICE, "could not parse hw-address '%s'", hw_addr);
|
|
|
|
|
priv->hw_addr = NULL;
|
2014-05-20 15:03:27 -05:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
|
break;
|
2013-11-04 19:51:28 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
#define DBUS_TYPE_STATE_REASON_STRUCT (dbus_g_type_get_struct ("GValueArray", G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID))
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
get_property (GObject *object, guint prop_id,
|
|
|
|
|
GValue *value, GParamSpec *pspec)
|
2012-08-01 11:16:48 -06:00
|
|
|
{
|
2014-05-20 15:03:27 -05:00
|
|
|
NMDevice *self = NM_DEVICE (object);
|
|
|
|
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
|
|
|
|
const char *ac_path = NULL;
|
|
|
|
|
GPtrArray *array;
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
NMConnection *connection;
|
2013-11-04 19:51:28 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
switch (prop_id) {
|
|
|
|
|
case PROP_UDI:
|
|
|
|
|
g_value_set_string (value, priv->udi);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_IFACE:
|
|
|
|
|
g_value_set_string (value, priv->iface);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_IP_IFACE:
|
|
|
|
|
if (ip_config_valid (priv->state))
|
|
|
|
|
g_value_set_string (value, nm_device_get_ip_iface (self));
|
|
|
|
|
else
|
|
|
|
|
g_value_set_string (value, NULL);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_IFINDEX:
|
|
|
|
|
g_value_set_int (value, priv->ifindex);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_DRIVER:
|
|
|
|
|
g_value_set_string (value, priv->driver);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_DRIVER_VERSION:
|
|
|
|
|
g_value_set_string (value, priv->driver_version);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_FIRMWARE_VERSION:
|
|
|
|
|
g_value_set_string (value, priv->firmware_version);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_CAPABILITIES:
|
|
|
|
|
g_value_set_uint (value, (priv->capabilities & ~NM_DEVICE_CAP_INTERNAL_MASK));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_IP4_ADDRESS:
|
|
|
|
|
g_value_set_uint (value, priv->ip4_address);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_CARRIER:
|
|
|
|
|
g_value_set_boolean (value, priv->carrier);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_MTU:
|
|
|
|
|
g_value_set_uint (value, priv->mtu);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_IP4_CONFIG:
|
|
|
|
|
if (ip_config_valid (priv->state) && priv->ip4_config)
|
|
|
|
|
g_value_set_boxed (value, nm_ip4_config_get_dbus_path (priv->ip4_config));
|
|
|
|
|
else
|
|
|
|
|
g_value_set_boxed (value, "/");
|
|
|
|
|
break;
|
|
|
|
|
case PROP_DHCP4_CONFIG:
|
2014-07-01 10:58:27 +02:00
|
|
|
if (ip_config_valid (priv->state) && priv->dhcp4_config)
|
2014-05-20 15:03:27 -05:00
|
|
|
g_value_set_boxed (value, nm_dhcp4_config_get_dbus_path (priv->dhcp4_config));
|
|
|
|
|
else
|
|
|
|
|
g_value_set_boxed (value, "/");
|
|
|
|
|
break;
|
|
|
|
|
case PROP_IP6_CONFIG:
|
|
|
|
|
if (ip_config_valid (priv->state) && priv->ip6_config)
|
|
|
|
|
g_value_set_boxed (value, nm_ip6_config_get_dbus_path (priv->ip6_config));
|
|
|
|
|
else
|
|
|
|
|
g_value_set_boxed (value, "/");
|
|
|
|
|
break;
|
|
|
|
|
case PROP_DHCP6_CONFIG:
|
2014-07-01 10:58:27 +02:00
|
|
|
if (ip_config_valid (priv->state) && priv->dhcp6_config)
|
2014-05-20 15:03:27 -05:00
|
|
|
g_value_set_boxed (value, nm_dhcp6_config_get_dbus_path (priv->dhcp6_config));
|
|
|
|
|
else
|
|
|
|
|
g_value_set_boxed (value, "/");
|
|
|
|
|
break;
|
|
|
|
|
case PROP_STATE:
|
|
|
|
|
g_value_set_uint (value, priv->state);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_STATE_REASON:
|
|
|
|
|
g_value_take_boxed (value, dbus_g_type_specialized_construct (DBUS_TYPE_STATE_REASON_STRUCT));
|
|
|
|
|
dbus_g_type_struct_set (value, 0, priv->state, 1, priv->state_reason, G_MAXUINT);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_ACTIVE_CONNECTION:
|
|
|
|
|
if (priv->act_request)
|
|
|
|
|
ac_path = nm_active_connection_get_path (NM_ACTIVE_CONNECTION (priv->act_request));
|
|
|
|
|
g_value_set_boxed (value, ac_path ? ac_path : "/");
|
|
|
|
|
break;
|
|
|
|
|
case PROP_DEVICE_TYPE:
|
|
|
|
|
g_value_set_uint (value, priv->type);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_MANAGED:
|
|
|
|
|
g_value_set_boolean (value, nm_device_get_managed (self));
|
|
|
|
|
break;
|
|
|
|
|
case PROP_AUTOCONNECT:
|
|
|
|
|
g_value_set_boolean (value, priv->autoconnect);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_FIRMWARE_MISSING:
|
|
|
|
|
g_value_set_boolean (value, priv->firmware_missing);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_TYPE_DESC:
|
|
|
|
|
g_value_set_string (value, priv->type_desc);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_RFKILL_TYPE:
|
|
|
|
|
g_value_set_uint (value, priv->rfkill_type);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_AVAILABLE_CONNECTIONS:
|
|
|
|
|
array = g_ptr_array_sized_new (g_hash_table_size (priv->available_connections));
|
|
|
|
|
g_hash_table_iter_init (&iter, priv->available_connections);
|
|
|
|
|
while (g_hash_table_iter_next (&iter, (gpointer) &connection, NULL))
|
|
|
|
|
g_ptr_array_add (array, g_strdup (nm_connection_get_path (connection)));
|
|
|
|
|
g_value_take_boxed (value, array);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_PHYSICAL_PORT_ID:
|
|
|
|
|
g_value_set_string (value, priv->physical_port_id);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_IS_MASTER:
|
|
|
|
|
g_value_set_boolean (value, priv->is_master);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_MASTER:
|
|
|
|
|
g_value_set_object (value, priv->master);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_HW_ADDRESS:
|
2014-06-21 12:44:56 -04:00
|
|
|
g_value_set_string (value, priv->hw_addr);
|
2014-05-20 15:03:27 -05:00
|
|
|
break;
|
|
|
|
|
case PROP_HAS_PENDING_ACTION:
|
|
|
|
|
g_value_set_boolean (value, nm_device_has_pending_action (self));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2012-08-01 11:16:48 -06:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
static void
|
|
|
|
|
nm_device_class_init (NMDeviceClass *klass)
|
2012-08-01 11:16:48 -06:00
|
|
|
{
|
2014-05-20 15:03:27 -05:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_type_class_add_private (object_class, sizeof (NMDevicePrivate));
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* Virtual methods */
|
|
|
|
|
object_class->dispose = dispose;
|
|
|
|
|
object_class->finalize = finalize;
|
|
|
|
|
object_class->set_property = set_property;
|
|
|
|
|
object_class->get_property = get_property;
|
|
|
|
|
object_class->constructor = constructor;
|
|
|
|
|
object_class->constructed = constructed;
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
klass->link_changed = link_changed;
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
klass->is_available = is_available;
|
|
|
|
|
klass->act_stage1_prepare = act_stage1_prepare;
|
|
|
|
|
klass->act_stage2_config = act_stage2_config;
|
|
|
|
|
klass->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
|
|
|
|
|
klass->act_stage3_ip6_config_start = act_stage3_ip6_config_start;
|
|
|
|
|
klass->act_stage4_ip4_config_timeout = act_stage4_ip4_config_timeout;
|
|
|
|
|
klass->act_stage4_ip6_config_timeout = act_stage4_ip6_config_timeout;
|
|
|
|
|
klass->have_any_ready_slaves = have_any_ready_slaves;
|
2013-09-03 15:34:56 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
klass->spec_match_list = spec_match_list;
|
|
|
|
|
klass->can_auto_connect = can_auto_connect;
|
|
|
|
|
klass->check_connection_compatible = check_connection_compatible;
|
|
|
|
|
klass->check_connection_available = check_connection_available;
|
|
|
|
|
klass->is_up = is_up;
|
|
|
|
|
klass->bring_up = bring_up;
|
|
|
|
|
klass->take_down = take_down;
|
|
|
|
|
klass->carrier_changed = carrier_changed;
|
2014-04-10 15:29:45 -05:00
|
|
|
klass->get_ip_iface_identifier = get_ip_iface_identifier;
|
2013-09-03 15:34:56 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* Properties */
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_PLATFORM_DEVICE,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_pointer (NM_DEVICE_PLATFORM_DEVICE, "", "",
|
|
|
|
|
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_UDI,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_string (NM_DEVICE_UDI, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
NULL,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_IFACE,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_string (NM_DEVICE_IFACE, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
NULL,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_IP_IFACE,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_string (NM_DEVICE_IP_IFACE, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
NULL,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_DRIVER,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_string (NM_DEVICE_DRIVER, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
NULL,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2012-08-01 11:16:48 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_DRIVER_VERSION,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_string (NM_DEVICE_DRIVER_VERSION, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
NULL,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2012-06-13 11:32:47 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_FIRMWARE_VERSION,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
NULL,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-05-01 09:28:16 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_CAPABILITIES,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_uint (NM_DEVICE_CAPABILITIES, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
0, G_MAXUINT32, NM_DEVICE_CAP_NONE,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-07-19 12:05:19 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_CARRIER,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boolean (NM_DEVICE_CARRIER, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
FALSE,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2012-06-13 11:32:47 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_MTU,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_uint (NM_DEVICE_MTU, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
0, G_MAXUINT32, 1500,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-05-01 09:28:16 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_IP4_ADDRESS,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_uint (NM_DEVICE_IP4_ADDRESS, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
0, G_MAXUINT32, 0, /* FIXME */
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-05-01 09:28:16 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_IP4_CONFIG,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boxed (NM_DEVICE_IP4_CONFIG, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
DBUS_TYPE_G_OBJECT_PATH,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-05-01 09:28:16 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_DHCP4_CONFIG,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boxed (NM_DEVICE_DHCP4_CONFIG, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
DBUS_TYPE_G_OBJECT_PATH,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-01-21 15:12:24 +01:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_IP6_CONFIG,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boxed (NM_DEVICE_IP6_CONFIG, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
DBUS_TYPE_G_OBJECT_PATH,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-05-01 09:28:16 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_DHCP6_CONFIG,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boxed (NM_DEVICE_DHCP6_CONFIG, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
DBUS_TYPE_G_OBJECT_PATH,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2012-06-13 11:32:47 -05:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_STATE,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_uint (NM_DEVICE_STATE, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
0, G_MAXUINT32, NM_DEVICE_STATE_UNKNOWN,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-08-13 17:45:34 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_STATE_REASON,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boxed (NM_DEVICE_STATE_REASON, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
DBUS_TYPE_STATE_REASON_STRUCT,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-09-08 13:39:03 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_ACTIVE_CONNECTION,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boxed (NM_DEVICE_ACTIVE_CONNECTION, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
DBUS_TYPE_G_OBJECT_PATH,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-09-08 13:39:03 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_DEVICE_TYPE,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
0, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-09-08 13:39:03 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_MANAGED,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boolean (NM_DEVICE_MANAGED, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
FALSE,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-09-08 13:39:03 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_AUTOCONNECT,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
DEFAULT_AUTOCONNECT,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-09-08 13:39:03 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_FIRMWARE_MISSING,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
FALSE,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2014-05-20 15:03:27 -05:00
|
|
|
|
|
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_TYPE_DESC,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_string (NM_DEVICE_TYPE_DESC, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
NULL,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-09-08 13:39:03 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_RFKILL_TYPE,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_uint (NM_DEVICE_RFKILL_TYPE, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
RFKILL_TYPE_WLAN,
|
|
|
|
|
RFKILL_TYPE_MAX,
|
|
|
|
|
RFKILL_TYPE_UNKNOWN,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-09-08 13:39:03 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_IFINDEX,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_int (NM_DEVICE_IFINDEX, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
0, G_MAXINT, 0,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-09-08 13:39:03 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_AVAILABLE_CONNECTIONS,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-08-13 17:45:34 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_PHYSICAL_PORT_ID,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
NULL,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-08-13 17:45:34 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_IS_MASTER,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boolean (NM_DEVICE_IS_MASTER, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
FALSE,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-12-09 12:55:04 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_MASTER,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_object (NM_DEVICE_MASTER, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
NM_TYPE_DEVICE,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-12-16 16:52:36 +01:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_HW_ADDRESS,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_string (NM_DEVICE_HW_ADDRESS, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
NULL,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2013-12-09 12:55:04 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
g_object_class_install_property
|
|
|
|
|
(object_class, PROP_HAS_PENDING_ACTION,
|
2014-06-09 16:17:37 -04:00
|
|
|
g_param_spec_boolean (NM_DEVICE_HAS_PENDING_ACTION, "", "",
|
2014-05-20 15:03:27 -05:00
|
|
|
FALSE,
|
2014-06-09 16:17:37 -04:00
|
|
|
G_PARAM_READABLE |
|
|
|
|
|
G_PARAM_STATIC_STRINGS));
|
2014-04-28 11:18:05 +02:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
/* Signals */
|
|
|
|
|
signals[STATE_CHANGED] =
|
|
|
|
|
g_signal_new ("state-changed",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
|
G_STRUCT_OFFSET (NMDeviceClass, state_changed),
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 3,
|
|
|
|
|
G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
|
2013-08-13 17:45:34 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
signals[AUTOCONNECT_ALLOWED] =
|
|
|
|
|
g_signal_new ("autoconnect-allowed",
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
|
0,
|
|
|
|
|
autoconnect_allowed_accumulator, NULL, NULL,
|
|
|
|
|
G_TYPE_BOOLEAN, 0);
|
2013-08-13 17:45:34 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
signals[AUTH_REQUEST] =
|
|
|
|
|
g_signal_new (NM_DEVICE_AUTH_REQUEST,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
|
/* dbus-glib context, connection, permission, allow_interaction, callback, user_data */
|
|
|
|
|
G_TYPE_NONE, 6, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER, G_TYPE_POINTER);
|
2013-08-13 17:45:34 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
signals[IP4_CONFIG_CHANGED] =
|
|
|
|
|
g_signal_new (NM_DEVICE_IP4_CONFIG_CHANGED,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT);
|
2013-12-09 12:55:04 -06:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
signals[IP6_CONFIG_CHANGED] =
|
|
|
|
|
g_signal_new (NM_DEVICE_IP6_CONFIG_CHANGED,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT);
|
2013-08-13 17:45:34 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
signals[REMOVED] =
|
|
|
|
|
g_signal_new (NM_DEVICE_REMOVED,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 0);
|
2013-08-13 17:45:34 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
signals[RECHECK_AUTO_ACTIVATE] =
|
|
|
|
|
g_signal_new (NM_DEVICE_RECHECK_AUTO_ACTIVATE,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 0);
|
2013-10-11 14:59:26 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
signals[RECHECK_ASSUME] =
|
|
|
|
|
g_signal_new (NM_DEVICE_RECHECK_ASSUME,
|
|
|
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
|
G_TYPE_NONE, 0);
|
2013-10-11 14:59:26 -04:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
|
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
|
&dbus_glib_nm_device_object_info);
|
2013-12-16 15:16:43 +01:00
|
|
|
|
2014-05-20 15:03:27 -05:00
|
|
|
dbus_g_error_domain_register (NM_DEVICE_ERROR, NULL, NM_TYPE_DEVICE_ERROR);
|
2013-12-16 15:16:43 +01:00
|
|
|
}
|
|
|
|
|
|