device: refactor setting unmanaged flag EXTERNAL_DOWN
[NetworkManager.git] / src / devices / nm-device.c
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* NetworkManager -- Network link manager
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Copyright (C) 2005 - 2013 Red Hat, Inc.
19  * Copyright (C) 2006 - 2008 Novell, Inc.
20  */
21
22 #include "nm-default.h"
23
24 #include <netinet/in.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <sys/ioctl.h>
29 #include <signal.h>
30 #include <sys/types.h>
31 #include <sys/wait.h>
32 #include <arpa/inet.h>
33 #include <fcntl.h>
34 #include <netlink/route/addr.h>
35 #include <linux/if_addr.h>
36
37 #include "nm-device.h"
38 #include "nm-device-private.h"
39 #include "NetworkManagerUtils.h"
40 #include "nm-manager.h"
41 #include "nm-platform.h"
42 #include "nm-rdisc.h"
43 #include "nm-lndp-rdisc.h"
44 #include "nm-dhcp-manager.h"
45 #include "nm-activation-request.h"
46 #include "nm-ip4-config.h"
47 #include "nm-ip6-config.h"
48 #include "nm-dnsmasq-manager.h"
49 #include "nm-dhcp4-config.h"
50 #include "nm-dhcp6-config.h"
51 #include "nm-rfkill-manager.h"
52 #include "nm-firewall-manager.h"
53 #include "nm-enum-types.h"
54 #include "nm-settings-connection.h"
55 #include "nm-connection-provider.h"
56 #include "nm-auth-utils.h"
57 #include "nm-dispatcher.h"
58 #include "nm-config.h"
59 #include "nm-dns-manager.h"
60 #include "nm-core-internal.h"
61 #include "nm-default-route-manager.h"
62 #include "nm-route-manager.h"
63 #include "nm-lldp-listener.h"
64 #include "sd-ipv4ll.h"
65 #include "nm-audit-manager.h"
66 #include "nm-arping-manager.h"
67
68 #include "nm-device-logging.h"
69 _LOG_DECLARE_SELF (NMDevice);
70
71 #include "nmdbus-device.h"
72
73 G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_EXPORTED_OBJECT)
74
75 #define NM_DEVICE_GET_PRIVATE(o) ((o)->priv)
76
77 enum {
78         STATE_CHANGED,
79         AUTOCONNECT_ALLOWED,
80         AUTH_REQUEST,
81         IP4_CONFIG_CHANGED,
82         IP6_CONFIG_CHANGED,
83         REMOVED,
84         RECHECK_AUTO_ACTIVATE,
85         RECHECK_ASSUME,
86         LAST_SIGNAL,
87 };
88 static guint signals[LAST_SIGNAL] = { 0 };
89
90 NM_GOBJECT_PROPERTIES_DEFINE (NMDevice,
91         PROP_UDI,
92         PROP_IFACE,
93         PROP_IP_IFACE,
94         PROP_DRIVER,
95         PROP_DRIVER_VERSION,
96         PROP_FIRMWARE_VERSION,
97         PROP_CAPABILITIES,
98         PROP_CARRIER,
99         PROP_MTU,
100         PROP_IP4_ADDRESS,
101         PROP_IP4_CONFIG,
102         PROP_DHCP4_CONFIG,
103         PROP_IP6_CONFIG,
104         PROP_DHCP6_CONFIG,
105         PROP_STATE,
106         PROP_STATE_REASON,
107         PROP_ACTIVE_CONNECTION,
108         PROP_DEVICE_TYPE,
109         PROP_LINK_TYPE,
110         PROP_MANAGED,
111         PROP_AUTOCONNECT,
112         PROP_FIRMWARE_MISSING,
113         PROP_NM_PLUGIN_MISSING,
114         PROP_TYPE_DESC,
115         PROP_RFKILL_TYPE,
116         PROP_IFINDEX,
117         PROP_AVAILABLE_CONNECTIONS,
118         PROP_PHYSICAL_PORT_ID,
119         PROP_IS_MASTER,
120         PROP_MASTER,
121         PROP_HW_ADDRESS,
122         PROP_HAS_PENDING_ACTION,
123         PROP_METERED,
124         PROP_LLDP_NEIGHBORS,
125         PROP_REAL,
126         PROP_SLAVES,
127 );
128
129 #define DEFAULT_AUTOCONNECT TRUE
130
131 /***********************************************************/
132
133 #define PENDING_ACTION_DHCP4 "dhcp4"
134 #define PENDING_ACTION_DHCP6 "dhcp6"
135 #define PENDING_ACTION_AUTOCONF6 "autoconf6"
136
137 typedef void (*ActivationHandleFunc) (NMDevice *self);
138
139 typedef struct {
140         ActivationHandleFunc func;
141         guint id;
142 } ActivationHandleData;
143
144 typedef enum {
145         CLEANUP_TYPE_DECONFIGURE,
146         CLEANUP_TYPE_KEEP,
147         CLEANUP_TYPE_REMOVED,
148 } CleanupType;
149
150 typedef enum {
151         IP_NONE = 0,
152         IP_WAIT,
153         IP_CONF,
154         IP_DONE,
155         IP_FAIL
156 } IpState;
157
158 typedef struct {
159         NMDeviceState state;
160         NMDeviceStateReason reason;
161         guint id;
162 } QueuedState;
163
164 typedef struct {
165         NMDevice *slave;
166         gboolean slave_is_enslaved;
167         gboolean configure;
168         gulong watch_id;
169 } SlaveInfo;
170
171 typedef struct {
172         NMLogDomain log_domain;
173         guint timeout;
174         guint watch;
175         GPid pid;
176         const char *binary;
177         const char *address;
178         guint deadline;
179 } PingInfo;
180
181 typedef struct {
182         NMDevice *device;
183         guint idle_add_id;
184         int ifindex;
185 } DeleteOnDeactivateData;
186
187 typedef void (*ArpingCallback) (NMDevice *, NMIP4Config **, gboolean);
188
189 typedef struct {
190         ArpingCallback callback;
191         NMDevice *device;
192         NMIP4Config **configs;
193 } ArpingData;
194
195 typedef struct _NMDevicePrivate {
196         gboolean in_state_changed;
197
198         guint device_link_changed_id;
199         guint device_ip_link_changed_id;
200
201         NMDeviceState state;
202         NMDeviceStateReason state_reason;
203         QueuedState   queued_state;
204         guint queued_ip4_config_id;
205         guint queued_ip6_config_id;
206         GSList *pending_actions;
207         GSList *dad6_failed_addrs;
208
209         char *        udi;
210         char *        iface;   /* may change, could be renamed by user */
211         int           ifindex;
212         gboolean      real;
213         char *        ip_iface;
214         int           ip_ifindex;
215         NMDeviceType  type;
216         char *        type_desc;
217         char *        type_description;
218         NMLinkType    link_type;
219         NMDeviceCapabilities capabilities;
220         char *        driver;
221         char *        driver_version;
222         char *        firmware_version;
223         RfKillType    rfkill_type;
224         gboolean      firmware_missing;
225         gboolean      nm_plugin_missing;
226         GHashTable *  available_connections;
227         char *        hw_addr;
228         guint         hw_addr_len;
229         char *        perm_hw_addr;
230         char *        initial_hw_addr;
231         char *        physical_port_id;
232         guint         dev_id;
233
234         NMUnmanagedFlags        unmanaged_mask;
235         NMUnmanagedFlags        unmanaged_flags;
236         gboolean                is_nm_owned; /* whether the device is a device owned and created by NM */
237         DeleteOnDeactivateData *delete_on_deactivate_data; /* data for scheduled cleanup when deleting link (g_idle_add) */
238
239         GCancellable *deactivating_cancellable;
240
241         guint32         ip4_address;
242
243         NMActRequest *  queued_act_request;
244         gboolean        queued_act_request_is_waiting_for_carrier;
245         NMActRequest *  act_request;
246         ActivationHandleData act_handle4; /* for layer2 and IPv4. */
247         ActivationHandleData act_handle6;
248         guint           recheck_assume_id;
249         struct {
250                 guint               call_id;
251                 NMDeviceStateReason available_reason;
252                 NMDeviceStateReason unavailable_reason;
253         }               recheck_available;
254         struct {
255                 guint               call_id;
256                 NMDeviceState       post_state;
257                 NMDeviceStateReason post_state_reason;
258         }               dispatcher;
259
260         /* Link stuff */
261         guint           link_connected_id;
262         guint           link_disconnected_id;
263         guint           carrier_defer_id;
264         gboolean        carrier;
265         guint           carrier_wait_id;
266         gboolean        ignore_carrier;
267         guint32         mtu;
268         gboolean        up;   /* IFF_UP */
269
270         /* Generic DHCP stuff */
271         guint32         dhcp_timeout;
272         char *          dhcp_anycast_address;
273
274         /* IP4 configuration info */
275         NMIP4Config *   ip4_config;     /* Combined config from VPN, settings, and device */
276         IpState         ip4_state;
277         NMIP4Config *   con_ip4_config; /* config from the setting */
278         NMIP4Config *   dev_ip4_config; /* Config from DHCP, PPP, LLv4, etc */
279         NMIP4Config *   ext_ip4_config; /* Stuff added outside NM */
280         NMIP4Config *   wwan_ip4_config; /* WWAN configuration */
281         GSList *        vpn4_configs;   /* VPNs which use this device */
282         struct {
283                 gboolean v4_has;
284                 gboolean v4_is_assumed;
285                 NMPlatformIP4Route v4;
286                 gboolean v6_has;
287                 gboolean v6_is_assumed;
288                 NMPlatformIP6Route v6;
289         } default_route;
290
291         gboolean v4_commit_first_time;
292         gboolean v6_commit_first_time;
293
294         /* DHCPv4 tracking */
295         NMDhcpClient *  dhcp4_client;
296         gulong          dhcp4_state_sigid;
297         NMDhcp4Config * dhcp4_config;
298         guint           dhcp4_restart_id;
299
300         PingInfo        gw_ping;
301
302         /* dnsmasq stuff for shared connections */
303         NMDnsMasqManager *dnsmasq_manager;
304         gulong            dnsmasq_state_id;
305
306         /* Firewall */
307         gboolean       fw_ready;
308         NMFirewallManagerCallId fw_call;
309
310         /* IPv4LL stuff */
311         sd_ipv4ll *    ipv4ll;
312         guint          ipv4ll_timeout;
313
314         /* IPv4 DAD stuff */
315         struct {
316                 GSList *          dad_list;
317                 NMArpingManager * announcing;
318         } arping;
319
320         /* IP6 configuration info */
321         NMIP6Config *  ip6_config;
322         IpState        ip6_state;
323         NMIP6Config *  con_ip6_config; /* config from the setting */
324         NMIP6Config *  wwan_ip6_config;
325         NMIP6Config *  ext_ip6_config; /* Stuff added outside NM */
326         NMIP6Config *  ext_ip6_config_captured; /* Configuration captured from platform. */
327         GSList *       vpn6_configs;   /* VPNs which use this device */
328         gboolean       nm_ipv6ll; /* TRUE if NM handles the device's IPv6LL address */
329         guint32        ip6_mtu;
330
331         NMRDisc *      rdisc;
332         gulong         rdisc_changed_id;
333         gulong         rdisc_timeout_id;
334         NMSettingIP6ConfigPrivacy rdisc_use_tempaddr;
335         /* IP6 config from autoconf */
336         NMIP6Config *  ac_ip6_config;
337
338         guint          linklocal6_timeout_id;
339         guint8         linklocal6_dad_counter;
340
341         GHashTable *   ip6_saved_properties;
342
343         NMDhcpClient *  dhcp6_client;
344         NMRDiscDHCPLevel dhcp6_mode;
345         gulong          dhcp6_state_sigid;
346         NMDhcp6Config * dhcp6_config;
347         /* IP6 config from DHCP */
348         NMIP6Config *   dhcp6_ip6_config;
349         /* Event ID of the current IP6 config from DHCP */
350         char *          dhcp6_event_id;
351         guint           dhcp6_restart_id;
352
353         /* allow autoconnect feature */
354         gboolean        autoconnect;
355
356         /* master interface for bridge/bond/team slave */
357         NMDevice *      master;
358         gboolean        is_enslaved;
359         gboolean        master_ready_handled;
360         gulong          master_ready_id;
361
362         /* slave management */
363         gboolean        is_master;
364         GSList *        slaves;    /* list of SlaveInfo */
365
366         NMMetered       metered;
367
368         NMConnectionProvider *con_provider;
369         NMLldpListener *lldp_listener;
370
371         guint check_delete_unrealized_id;
372 } NMDevicePrivate;
373
374 static gboolean nm_device_set_ip4_config (NMDevice *self,
375                                           NMIP4Config *config,
376                                           guint32 default_route_metric,
377                                           gboolean commit,
378                                           gboolean routes_full_sync,
379                                           NMDeviceStateReason *reason);
380 static gboolean ip4_config_merge_and_apply (NMDevice *self,
381                                             NMIP4Config *config,
382                                             gboolean commit,
383                                             NMDeviceStateReason *out_reason);
384
385 static gboolean nm_device_set_ip6_config (NMDevice *self,
386                                           NMIP6Config *config,
387                                           gboolean commit,
388                                           gboolean routes_full_sync,
389                                           NMDeviceStateReason *reason);
390
391 static void nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure);
392 static void nm_device_slave_notify_enslave (NMDevice *self, gboolean success);
393 static void nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason);
394
395 static gboolean addrconf6_start_with_link_ready (NMDevice *self);
396 static NMActStageReturn linklocal6_start (NMDevice *self);
397
398 static void _carrier_wait_check_queued_act_request (NMDevice *self);
399
400 static const char *_activation_func_to_string (ActivationHandleFunc func);
401 static void activation_source_handle_cb (NMDevice *self, int family);
402
403 static void _set_state_full (NMDevice *self,
404                              NMDeviceState state,
405                              NMDeviceStateReason reason,
406                              gboolean quitting);
407
408 static gboolean queued_ip4_config_change (gpointer user_data);
409 static gboolean queued_ip6_config_change (gpointer user_data);
410 static void ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data);
411 static gboolean ip_config_valid (NMDeviceState state);
412 static NMActStageReturn dhcp4_start (NMDevice *self, NMConnection *connection, NMDeviceStateReason *reason);
413 static gboolean dhcp6_start (NMDevice *self, gboolean wait_for_ll, NMDeviceStateReason *reason);
414 static void nm_device_start_ip_check (NMDevice *self);
415 static void realize_start_setup (NMDevice *self, const NMPlatformLink *plink);
416
417 /***********************************************************/
418
419 #define QUEUED_PREFIX "queued state change to "
420
421 static const char *state_table[] = {
422         [NM_DEVICE_STATE_UNKNOWN]      = QUEUED_PREFIX "unknown",
423         [NM_DEVICE_STATE_UNMANAGED]    = QUEUED_PREFIX "unmanaged",
424         [NM_DEVICE_STATE_UNAVAILABLE]  = QUEUED_PREFIX "unavailable",
425         [NM_DEVICE_STATE_DISCONNECTED] = QUEUED_PREFIX "disconnected",
426         [NM_DEVICE_STATE_PREPARE]      = QUEUED_PREFIX "prepare",
427         [NM_DEVICE_STATE_CONFIG]       = QUEUED_PREFIX "config",
428         [NM_DEVICE_STATE_NEED_AUTH]    = QUEUED_PREFIX "need-auth",
429         [NM_DEVICE_STATE_IP_CONFIG]    = QUEUED_PREFIX "ip-config",
430         [NM_DEVICE_STATE_IP_CHECK]     = QUEUED_PREFIX "ip-check",
431         [NM_DEVICE_STATE_SECONDARIES]  = QUEUED_PREFIX "secondaries",
432         [NM_DEVICE_STATE_ACTIVATED]    = QUEUED_PREFIX "activated",
433         [NM_DEVICE_STATE_DEACTIVATING] = QUEUED_PREFIX "deactivating",
434         [NM_DEVICE_STATE_FAILED]       = QUEUED_PREFIX "failed",
435 };
436
437 static const char *
438 queued_state_to_string (NMDeviceState state)
439 {
440         if ((gsize) state < G_N_ELEMENTS (state_table))
441                 return state_table[state];
442         return state_table[NM_DEVICE_STATE_UNKNOWN];
443 }
444
445 static const char *
446 state_to_string (NMDeviceState state)
447 {
448         return queued_state_to_string (state) + strlen (QUEUED_PREFIX);
449 }
450
451 NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_reason_to_string, NMDeviceStateReason,
452         NM_UTILS_LOOKUP_DEFAULT (NULL),
453         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_UNKNOWN,                        "unknown"),
454         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_NONE,                           "none"),
455         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_NOW_MANAGED,                    "managed"),
456         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_NOW_UNMANAGED,                  "unmanaged"),
457         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_CONFIG_FAILED,                  "config-failed"),
458         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE,          "ip-config-unavailable"),
459         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED,              "ip-config-expired"),
460         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_NO_SECRETS,                     "no-secrets"),
461         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT,          "supplicant-disconnect"),
462         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED,       "supplicant-config-failed"),
463         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED,              "supplicant-failed"),
464         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT,             "supplicant-timeout"),
465         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PPP_START_FAILED,               "ppp-start-failed"),
466         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PPP_DISCONNECT,                 "ppp-disconnect"),
467         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PPP_FAILED,                     "ppp-failed"),
468         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_DHCP_START_FAILED,              "dhcp-start-failed"),
469         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_DHCP_ERROR,                     "dhcp-error"),
470         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_DHCP_FAILED,                    "dhcp-failed"),
471         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SHARED_START_FAILED,            "sharing-start-failed"),
472         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SHARED_FAILED,                  "sharing-failed"),
473         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED,            "autoip-start-failed"),
474         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_AUTOIP_ERROR,                   "autoip-error"),
475         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_AUTOIP_FAILED,                  "autoip-failed"),
476         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_BUSY,                     "modem-busy"),
477         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE,             "modem-no-dialtone"),
478         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER,               "modem-no-carrier"),
479         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT,             "modem-dial-timeout"),
480         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED,              "modem-dial-failed"),
481         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED,              "modem-init-failed"),
482         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_APN_FAILED,                 "gsm-apn-failed"),
483         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING, "gsm-registration-idle"),
484         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED,        "gsm-registration-denied"),
485         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT,       "gsm-registration-timeout"),
486         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED,        "gsm-registration-failed"),
487         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED,           "gsm-pin-check-failed"),
488         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_FIRMWARE_MISSING,               "firmware-missing"),
489         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_REMOVED,                        "removed"),
490         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SLEEPING,                       "sleeping"),
491         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_CONNECTION_REMOVED,             "connection-removed"),
492         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_USER_REQUESTED,                 "user-requested"),
493         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_CARRIER,                        "carrier-changed"),
494         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED,             "connection-assumed"),
495         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,           "supplicant-available"),
496         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND,                "modem-not-found"),
497         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_BT_FAILED,                      "bluetooth-failed"),
498         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED,           "gsm-sim-not-inserted"),
499         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED,           "gsm-sim-pin-required"),
500         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED,           "gsm-sim-puk-required"),
501         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_SIM_WRONG,                  "gsm-sim-wrong"),
502         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_INFINIBAND_MODE,                "infiniband-mode"),
503         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED,              "dependency-failed"),
504         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_BR2684_FAILED,                  "br2684-bridge-failed"),
505         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE,      "modem-manager-unavailable"),
506         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SSID_NOT_FOUND,                 "ssid-not-found"),
507         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED,    "secondary-connection-failed"),
508         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED,                "dcb-fcoe-failed"),
509         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED,           "teamd-control-failed"),
510         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_FAILED,                   "modem-failed"),
511         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_AVAILABLE,                "modem-available"),
512         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT,              "sim-pin-incorrect"),
513         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_NEW_ACTIVATION,                 "new-activation"),
514         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PARENT_CHANGED,                 "parent-changed"),
515         NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED,         "parent-managed-changed"),
516 );
517
518 #define reason_to_string(reason) \
519         NM_UTILS_LOOKUP_STR (_reason_to_string, reason)
520
521 /***********************************************************/
522
523 gboolean
524 nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value)
525 {
526         return nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property), value);
527 }
528
529 static guint32
530 nm_device_ipv6_sysctl_get_int32 (NMDevice *self, const char *property, gint32 fallback)
531 {
532         return nm_platform_sysctl_get_int32 (NM_PLATFORM_GET, nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property), fallback);
533 }
534
535 gboolean
536 nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps)
537 {
538         return NM_FLAGS_ANY (NM_DEVICE_GET_PRIVATE (self)->capabilities, caps);
539 }
540
541 /***********************************************************/
542
543 const char *
544 nm_device_get_udi (NMDevice *self)
545 {
546         g_return_val_if_fail (self != NULL, NULL);
547
548         return NM_DEVICE_GET_PRIVATE (self)->udi;
549 }
550
551 const char *
552 nm_device_get_iface (NMDevice *self)
553 {
554         g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
555
556         return NM_DEVICE_GET_PRIVATE (self)->iface;
557 }
558
559 int
560 nm_device_get_ifindex (NMDevice *self)
561 {
562         g_return_val_if_fail (NM_IS_DEVICE (self), 0);
563
564         return NM_DEVICE_GET_PRIVATE (self)->ifindex;
565 }
566
567 /**
568  * nm_device_is_software:
569  * @self: the #NMDevice
570  *
571  * Indicates if the device is a software-based virtual device without
572  * backing hardware, which can be added and removed programmatically.
573  *
574  * Returns: %TRUE if the device is a software-based device
575  */
576 gboolean
577 nm_device_is_software (NMDevice *self)
578 {
579         return NM_FLAGS_HAS (NM_DEVICE_GET_PRIVATE (self)->capabilities, NM_DEVICE_CAP_IS_SOFTWARE);
580 }
581
582 /**
583  * nm_device_is_real:
584  * @self: the #NMDevice
585  *
586  * Returns: %TRUE if the device exists, %FALSE if the device is a placeholder
587  */
588 gboolean
589 nm_device_is_real (NMDevice *self)
590 {
591         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
592
593         return NM_DEVICE_GET_PRIVATE (self)->real;
594 }
595
596 const char *
597 nm_device_get_ip_iface (NMDevice *self)
598 {
599         NMDevicePrivate *priv;
600
601         g_return_val_if_fail (self != NULL, NULL);
602
603         priv = NM_DEVICE_GET_PRIVATE (self);
604         /* If it's not set, default to iface */
605         return priv->ip_iface ? priv->ip_iface : priv->iface;
606 }
607
608 int
609 nm_device_get_ip_ifindex (NMDevice *self)
610 {
611         NMDevicePrivate *priv;
612
613         g_return_val_if_fail (self != NULL, 0);
614
615         priv = NM_DEVICE_GET_PRIVATE (self);
616         /* If it's not set, default to ifindex */
617         return priv->ip_iface ? priv->ip_ifindex : priv->ifindex;
618 }
619
620 void
621 nm_device_set_ip_iface (NMDevice *self, const char *iface)
622 {
623         NMDevicePrivate *priv;
624         char *old_ip_iface;
625
626         g_return_if_fail (NM_IS_DEVICE (self));
627
628         priv = NM_DEVICE_GET_PRIVATE (self);
629         if (!g_strcmp0 (iface, priv->ip_iface))
630                 return;
631
632         old_ip_iface = priv->ip_iface;
633         priv->ip_ifindex = 0;
634
635         priv->ip_iface = g_strdup (iface);
636         if (priv->ip_iface) {
637                 priv->ip_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, priv->ip_iface);
638                 if (priv->ip_ifindex > 0) {
639                         if (nm_platform_check_support_user_ipv6ll (NM_PLATFORM_GET))
640                                 nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, priv->ip_ifindex, TRUE);
641
642                         if (!nm_platform_link_is_up (NM_PLATFORM_GET, priv->ip_ifindex))
643                                 nm_platform_link_set_up (NM_PLATFORM_GET, priv->ip_ifindex, NULL);
644                 } else {
645                         /* Device IP interface must always be a kernel network interface */
646                         _LOGW (LOGD_HW, "failed to look up interface index");
647                 }
648         }
649
650         /* We don't care about any saved values from the old iface */
651         g_hash_table_remove_all (priv->ip6_saved_properties);
652
653         /* Emit change notification */
654         if (g_strcmp0 (old_ip_iface, priv->ip_iface))
655                 _notify (self, PROP_IP_IFACE);
656         g_free (old_ip_iface);
657 }
658
659 static gboolean
660 get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid)
661 {
662         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
663         NMLinkType link_type;
664         const guint8 *hwaddr = NULL;
665         size_t hwaddr_len = 0;
666         int ifindex;
667         gboolean success;
668
669         /* If we get here, we *must* have a kernel netdev, which implies an ifindex */
670         ifindex = nm_device_get_ip_ifindex (self);
671         g_assert (ifindex);
672
673         link_type = nm_platform_link_get_type (NM_PLATFORM_GET, ifindex);
674         g_return_val_if_fail (link_type > NM_LINK_TYPE_UNKNOWN, 0);
675
676         hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddr_len);
677         if (!hwaddr_len)
678                 return FALSE;
679
680         success = nm_utils_get_ipv6_interface_identifier (link_type,
681                                                           hwaddr,
682                                                           hwaddr_len,
683                                                           priv->dev_id,
684                                                           out_iid);
685         if (!success) {
686                 _LOGW (LOGD_HW, "failed to generate interface identifier "
687                        "for link type %u hwaddr_len %zu", link_type, hwaddr_len);
688         }
689         return success;
690 }
691
692 static gboolean
693 nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid)
694 {
695         return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid);
696 }
697
698 const char *
699 nm_device_get_driver (NMDevice *self)
700 {
701         g_return_val_if_fail (self != NULL, NULL);
702
703         return NM_DEVICE_GET_PRIVATE (self)->driver;
704 }
705
706 const char *
707 nm_device_get_driver_version (NMDevice *self)
708 {
709         g_return_val_if_fail (self != NULL, NULL);
710
711         return NM_DEVICE_GET_PRIVATE (self)->driver_version;
712 }
713
714 NMDeviceType
715 nm_device_get_device_type (NMDevice *self)
716 {
717         g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_TYPE_UNKNOWN);
718
719         return NM_DEVICE_GET_PRIVATE (self)->type;
720 }
721
722 NMLinkType
723 nm_device_get_link_type (NMDevice *self)
724 {
725         g_return_val_if_fail (NM_IS_DEVICE (self), NM_LINK_TYPE_UNKNOWN);
726
727         return NM_DEVICE_GET_PRIVATE (self)->link_type;
728 }
729
730 /**
731  * nm_device_get_metered:
732  * @setting: the #NMDevice
733  *
734  * Returns: the #NMDevice:metered property of the device.
735  *
736  * Since: 1.2
737  **/
738 NMMetered
739 nm_device_get_metered (NMDevice *self)
740 {
741         g_return_val_if_fail (NM_IS_DEVICE (self), NM_METERED_UNKNOWN);
742
743         return NM_DEVICE_GET_PRIVATE (self)->metered;
744 }
745
746 /**
747  * nm_device_get_priority():
748  * @self: the #NMDevice
749  *
750  * Returns: the device's routing priority.  Lower numbers means a "better"
751  *  device, eg higher priority.
752  */
753 int
754 nm_device_get_priority (NMDevice *self)
755 {
756         g_return_val_if_fail (NM_IS_DEVICE (self), 1000);
757
758         /* Device 'priority' is used for the default route-metric and is based on
759          * the device type. The settings ipv4.route-metric and ipv6.route-metric
760          * can overwrite this default.
761          *
762          * Currently for both IPv4 and IPv6 we use the same default values.
763          *
764          * The route-metric is used for the metric of the routes of device.
765          * This also applies to the default route. Therefore it affects also
766          * which device is the "best".
767          *
768          * For comparison, note that iproute2 by default adds IPv4 routes with
769          * metric 0, and IPv6 routes with metric 1024. The latter is the IPv6
770          * "user default" in the kernel (NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6).
771          * In kernel, the full uint32_t range is available for route
772          * metrics (except for IPv6, where 0 means 1024).
773          */
774
775         switch (nm_device_get_device_type (self)) {
776         /* 50 is reserved for VPN (NM_VPN_ROUTE_METRIC_DEFAULT) */
777         case NM_DEVICE_TYPE_ETHERNET:
778         case NM_DEVICE_TYPE_VETH:
779                 return 100;
780         case NM_DEVICE_TYPE_INFINIBAND:
781                 return 150;
782         case NM_DEVICE_TYPE_ADSL:
783                 return 200;
784         case NM_DEVICE_TYPE_WIMAX:
785                 return 250;
786         case NM_DEVICE_TYPE_BOND:
787                 return 300;
788         case NM_DEVICE_TYPE_TEAM:
789                 return 350;
790         case NM_DEVICE_TYPE_VLAN:
791                 return 400;
792         case NM_DEVICE_TYPE_MACVLAN:
793                 return 410;
794         case NM_DEVICE_TYPE_BRIDGE:
795                 return 425;
796         case NM_DEVICE_TYPE_TUN:
797                 return 450;
798         case NM_DEVICE_TYPE_VXLAN:
799                 return 500;
800         case NM_DEVICE_TYPE_WIFI:
801                 return 600;
802         case NM_DEVICE_TYPE_OLPC_MESH:
803                 return 650;
804         case NM_DEVICE_TYPE_IP_TUNNEL:
805                 return 675;
806         case NM_DEVICE_TYPE_MODEM:
807                 return 700;
808         case NM_DEVICE_TYPE_BT:
809                 return 750;
810         case NM_DEVICE_TYPE_GENERIC:
811                 return 950;
812         case NM_DEVICE_TYPE_UNKNOWN:
813                 return 10000;
814         case NM_DEVICE_TYPE_UNUSED1:
815         case NM_DEVICE_TYPE_UNUSED2:
816                 /* omit default: to get compiler warning about missing switch cases */
817                 break;
818         }
819         return 11000;
820 }
821
822 static guint32
823 _get_ipx_route_metric (NMDevice *self,
824                        gboolean is_v4)
825 {
826         char *value;
827         gint64 route_metric;
828         NMSettingIPConfig *s_ip;
829         NMConnection *connection;
830
831         g_return_val_if_fail (NM_IS_DEVICE (self), G_MAXUINT32);
832
833         connection = nm_device_get_applied_connection (self);
834         if (connection) {
835                 s_ip = is_v4
836                        ? nm_connection_get_setting_ip4_config (connection)
837                        : nm_connection_get_setting_ip6_config (connection);
838
839                 /* Slave interfaces don't have IP settings, but we may get here when
840                  * external changes are made or when noticing IP changes when starting
841                  * the slave connection.
842                  */
843                 if (s_ip) {
844                         route_metric = nm_setting_ip_config_get_route_metric (s_ip);
845                         if (route_metric >= 0)
846                                 goto out;
847                 }
848         }
849
850         /* use the current NMConfigData, which makes this configuration reloadable.
851          * Note that that means that the route-metric might change between SIGHUP.
852          * You must cache the returned value if that is a problem. */
853         value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
854                                                        is_v4 ? "ipv4.route-metric" : "ipv6.route-metric", self);
855         if (value) {
856                 route_metric = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, -1);
857                 g_free (value);
858
859                 if (route_metric >= 0)
860                         goto out;
861         }
862         route_metric = nm_device_get_priority (self);
863 out:
864         if (!is_v4)
865                 route_metric = nm_utils_ip6_route_metric_normalize (route_metric);
866         return route_metric;
867 }
868
869 guint32
870 nm_device_get_ip4_route_metric (NMDevice *self)
871 {
872         return _get_ipx_route_metric (self, TRUE);
873 }
874
875 guint32
876 nm_device_get_ip6_route_metric (NMDevice *self)
877 {
878         return _get_ipx_route_metric (self, FALSE);
879 }
880
881 const NMPlatformIP4Route *
882 nm_device_get_ip4_default_route (NMDevice *self, gboolean *out_is_assumed)
883 {
884         NMDevicePrivate *priv;
885
886         g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
887
888         priv = NM_DEVICE_GET_PRIVATE (self);
889
890         if (out_is_assumed)
891                 *out_is_assumed = priv->default_route.v4_is_assumed;
892
893         return priv->default_route.v4_has ? &priv->default_route.v4 : NULL;
894 }
895
896 const NMPlatformIP6Route *
897 nm_device_get_ip6_default_route (NMDevice *self, gboolean *out_is_assumed)
898 {
899         NMDevicePrivate *priv;
900
901         g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
902
903         priv = NM_DEVICE_GET_PRIVATE (self);
904
905         if (out_is_assumed)
906                 *out_is_assumed = priv->default_route.v6_is_assumed;
907
908         return priv->default_route.v6_has ? &priv->default_route.v6 : NULL;
909 }
910
911 const char *
912 nm_device_get_type_desc (NMDevice *self)
913 {
914         g_return_val_if_fail (self != NULL, NULL);
915
916         return NM_DEVICE_GET_PRIVATE (self)->type_desc;
917 }
918
919 const char *
920 nm_device_get_type_description (NMDevice *self)
921 {
922         g_return_val_if_fail (self != NULL, NULL);
923
924         /* Beware: this function should return the same
925          * value as nm_device_get_type_description() in libnm. */
926
927         return NM_DEVICE_GET_CLASS (self)->get_type_description (self);
928 }
929
930 static const char *
931 get_type_description (NMDevice *self)
932 {
933         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
934
935         if (!priv->type_description) {
936                 const char *typename;
937
938                 typename = G_OBJECT_TYPE_NAME (self);
939                 if (g_str_has_prefix (typename, "NMDevice"))
940                         typename += 8;
941                 priv->type_description = g_ascii_strdown (typename, -1);
942         }
943
944         return priv->type_description;
945 }
946
947 gboolean
948 nm_device_has_carrier (NMDevice *self)
949 {
950         return NM_DEVICE_GET_PRIVATE (self)->carrier;
951 }
952
953 NMActRequest *
954 nm_device_get_act_request (NMDevice *self)
955 {
956         g_return_val_if_fail (self != NULL, NULL);
957
958         return NM_DEVICE_GET_PRIVATE (self)->act_request;
959 }
960
961 NMSettingsConnection *
962 nm_device_get_settings_connection (NMDevice *self)
963 {
964         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
965
966         return priv->act_request ? nm_act_request_get_settings_connection (priv->act_request) : NULL;
967 }
968
969 NMConnection *
970 nm_device_get_applied_connection (NMDevice *self)
971 {
972         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
973
974         return priv->act_request ? nm_act_request_get_applied_connection (priv->act_request) : NULL;
975 }
976
977 gboolean
978 nm_device_has_unmodified_applied_connection (NMDevice *self, NMSettingCompareFlags compare_flags)
979 {
980         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
981
982         if (!priv->act_request)
983                 return FALSE;
984
985         return nm_active_connection_has_unmodified_applied_connection ((NMActiveConnection *) priv->act_request, compare_flags);
986 }
987
988 NMSetting *
989 nm_device_get_applied_setting (NMDevice *device, GType setting_type)
990 {
991         NMActRequest *req;
992         NMSetting *setting = NULL;
993
994         g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
995
996         req = nm_device_get_act_request (device);
997         if (req) {
998                 NMConnection *connection;
999
1000                 connection = nm_act_request_get_applied_connection (req);
1001                 if (connection)
1002                         setting = nm_connection_get_setting (connection, setting_type);
1003         }
1004
1005         return setting;
1006 }
1007
1008 RfKillType
1009 nm_device_get_rfkill_type (NMDevice *self)
1010 {
1011         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
1012
1013         return NM_DEVICE_GET_PRIVATE (self)->rfkill_type;
1014 }
1015
1016 static const char *
1017 nm_device_get_physical_port_id (NMDevice *self)
1018 {
1019         return NM_DEVICE_GET_PRIVATE (self)->physical_port_id;
1020 }
1021
1022 /***********************************************************/
1023
1024 static gboolean
1025 nm_device_uses_generated_assumed_connection (NMDevice *self)
1026 {
1027         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1028         NMSettingsConnection *connection;
1029
1030         if (   priv->act_request
1031             && nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (priv->act_request))) {
1032                 connection = nm_act_request_get_settings_connection (priv->act_request);
1033                 if (   connection
1034                     && nm_settings_connection_get_nm_generated_assumed (connection))
1035                         return TRUE;
1036         }
1037         return FALSE;
1038 }
1039
1040 gboolean
1041 nm_device_uses_assumed_connection (NMDevice *self)
1042 {
1043         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1044
1045         if (   priv->act_request
1046             && nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (priv->act_request)))
1047                 return TRUE;
1048         return FALSE;
1049 }
1050
1051 static SlaveInfo *
1052 find_slave_info (NMDevice *self, NMDevice *slave)
1053 {
1054         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1055         SlaveInfo *info;
1056         GSList *iter;
1057
1058         for (iter = priv->slaves; iter; iter = g_slist_next (iter)) {
1059                 info = iter->data;
1060                 if (info->slave == slave)
1061                         return info;
1062         }
1063         return NULL;
1064 }
1065
1066 /**
1067  * nm_device_master_enslave_slave:
1068  * @self: the master device
1069  * @slave: the slave device to enslave
1070  * @connection: (allow-none): the slave device's connection
1071  *
1072  * If @self is capable of enslaving other devices (ie it's a bridge, bond, team,
1073  * etc) then this function enslaves @slave.
1074  *
1075  * Returns: %TRUE on success, %FALSE on failure or if this device cannot enslave
1076  *  other devices.
1077  */
1078 static gboolean
1079 nm_device_master_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *connection)
1080 {
1081         SlaveInfo *info;
1082         gboolean success = FALSE;
1083         gboolean configure;
1084
1085         g_return_val_if_fail (self != NULL, FALSE);
1086         g_return_val_if_fail (slave != NULL, FALSE);
1087         g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE);
1088
1089         info = find_slave_info (self, slave);
1090         if (!info)
1091                 return FALSE;
1092
1093         if (info->slave_is_enslaved)
1094                 success = TRUE;
1095         else {
1096                 configure = (info->configure && connection != NULL);
1097                 if (configure)
1098                         g_return_val_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE);
1099
1100                 success = NM_DEVICE_GET_CLASS (self)->enslave_slave (self, slave, connection, configure);
1101                 info->slave_is_enslaved = success;
1102         }
1103
1104         nm_device_slave_notify_enslave (info->slave, success);
1105
1106         /* Ensure the device's hardware address is up-to-date; it often changes
1107          * when slaves change.
1108          */
1109         nm_device_update_hw_address (self);
1110
1111         /* Restart IP configuration if we're waiting for slaves.  Do this
1112          * after updating the hardware address as IP config may need the
1113          * new address.
1114          */
1115         if (success) {
1116                 if (NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT)
1117                         nm_device_activate_stage3_ip4_start (self);
1118
1119                 if (NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT)
1120                         nm_device_activate_stage3_ip6_start (self);
1121         }
1122
1123         return success;
1124 }
1125
1126 /**
1127  * nm_device_master_release_one_slave:
1128  * @self: the master device
1129  * @slave: the slave device to release
1130  * @configure: whether @self needs to actually release @slave
1131  * @reason: the state change reason for the @slave
1132  *
1133  * If @self is capable of enslaving other devices (ie it's a bridge, bond, team,
1134  * etc) then this function releases the previously enslaved @slave and/or
1135  * updates the state of @self and @slave to reflect its release.
1136  */
1137 static void
1138 nm_device_master_release_one_slave (NMDevice *self, NMDevice *slave, gboolean configure, NMDeviceStateReason reason)
1139 {
1140         NMDevicePrivate *priv;
1141         NMDevicePrivate *slave_priv;
1142         SlaveInfo *info;
1143         gs_unref_object NMDevice *self_free = NULL;
1144
1145         g_return_if_fail (NM_DEVICE (self));
1146         g_return_if_fail (NM_DEVICE (slave));
1147         g_return_if_fail (NM_DEVICE_GET_CLASS (self)->release_slave != NULL);
1148
1149         info = find_slave_info (self, slave);
1150
1151         _LOGt (LOGD_CORE, "master: release one slave %p/%s%s", slave, nm_device_get_iface (slave),
1152                !info ? " (not registered)" : "");
1153
1154         if (!info)
1155                 g_return_if_reached ();
1156
1157         priv = NM_DEVICE_GET_PRIVATE (self);
1158         slave_priv = NM_DEVICE_GET_PRIVATE (slave);
1159
1160         g_return_if_fail (self == slave_priv->master);
1161         nm_assert (slave == info->slave);
1162
1163         /* first, let subclasses handle the release ... */
1164         if (info->slave_is_enslaved)
1165                 NM_DEVICE_GET_CLASS (self)->release_slave (self, slave, configure);
1166
1167         /* raise notifications about the release, including clearing is_enslaved. */
1168         nm_device_slave_notify_release (slave, reason);
1169
1170         /* keep both alive until the end of the function.
1171          * Transfers ownership from slave_priv->master.  */
1172         self_free = self;
1173
1174         priv->slaves = g_slist_remove (priv->slaves, info);
1175         slave_priv->master = NULL;
1176
1177         g_signal_handler_disconnect (slave, info->watch_id);
1178         g_object_unref (slave);
1179         g_slice_free (SlaveInfo, info);
1180
1181         /* Ensure the device's hardware address is up-to-date; it often changes
1182          * when slaves change.
1183          */
1184         nm_device_update_hw_address (self);
1185         nm_device_set_unmanaged_by_flags (slave, NM_UNMANAGED_IS_SLAVE, NM_UNMAN_FLAG_OP_FORGET, NM_DEVICE_STATE_REASON_REMOVED);
1186 }
1187
1188 /**
1189  * can_unmanaged_external_down:
1190  * @self: the device
1191  *
1192  * Check whether the device should stay NM_UNMANAGED_EXTERNAL_DOWN unless
1193  * IFF_UP-ed externally.
1194  */
1195 static gboolean
1196 can_unmanaged_external_down (NMDevice *self)
1197 {
1198         return    !NM_DEVICE_GET_PRIVATE (self)->is_nm_owned
1199                && nm_device_is_software (self);
1200 }
1201
1202 static NMUnmanFlagOp
1203 is_unmanaged_external_down (NMDevice *self, gboolean consider_can)
1204 {
1205         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1206
1207         if (   consider_can
1208             && !NM_DEVICE_GET_CLASS (self)->can_unmanaged_external_down (self))
1209                 return NM_UNMAN_FLAG_OP_FORGET;
1210
1211         /* Manage externally-created software interfaces only when they are IFF_UP */
1212         if (   priv->ifindex <= 0
1213             || !priv->up)
1214                 return NM_UNMAN_FLAG_OP_SET_UNMANAGED;
1215
1216         return NM_UNMAN_FLAG_OP_SET_MANAGED;
1217 }
1218
1219 static void
1220 update_dynamic_ip_setup (NMDevice *self)
1221 {
1222         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1223         GError *error;
1224         gconstpointer addr;
1225         size_t addr_length;
1226
1227         g_hash_table_remove_all (priv->ip6_saved_properties);
1228
1229         if (priv->dhcp4_client) {
1230                 if (!nm_device_dhcp4_renew (self, FALSE)) {
1231                         nm_device_state_changed (self,
1232                                                  NM_DEVICE_STATE_FAILED,
1233                                                  NM_DEVICE_STATE_REASON_DHCP_FAILED);
1234                         return;
1235                 }
1236         }
1237         if (priv->dhcp6_client) {
1238                 if (!nm_device_dhcp6_renew (self, FALSE)) {
1239                         nm_device_state_changed (self,
1240                                                  NM_DEVICE_STATE_FAILED,
1241                                                  NM_DEVICE_STATE_REASON_DHCP_FAILED);
1242                         return;
1243                 }
1244         }
1245         if (priv->rdisc) {
1246                 /* FIXME: todo */
1247         }
1248         if (priv->dnsmasq_manager) {
1249                 /* FIXME: todo */
1250         }
1251
1252         if (priv->lldp_listener && nm_lldp_listener_is_running (priv->lldp_listener)) {
1253                 nm_lldp_listener_stop (priv->lldp_listener);
1254                 addr = nm_platform_link_get_address (NM_PLATFORM_GET, priv->ifindex, &addr_length);
1255
1256                 if (!nm_lldp_listener_start (priv->lldp_listener, nm_device_get_ifindex (self), &error)) {
1257                         _LOGD (LOGD_DEVICE, "LLDP listener %p could not be restarted: %s",
1258                                priv->lldp_listener, error->message);
1259                         g_clear_error (&error);
1260                 }
1261         }
1262 }
1263
1264 static void
1265 carrier_changed (NMDevice *self, gboolean carrier)
1266 {
1267         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1268
1269         if (priv->state <= NM_DEVICE_STATE_UNMANAGED)
1270                 return;
1271
1272         nm_device_recheck_available_connections (self);
1273
1274         /* ignore-carrier devices ignore all carrier-down events */
1275         if (priv->ignore_carrier && !carrier)
1276                 return;
1277
1278         if (priv->is_master) {
1279                 /* Bridge/bond/team carrier does not affect its own activation,
1280                  * but when carrier comes on, if there are slaves waiting,
1281                  * it will restart them.
1282                  */
1283                 if (!carrier)
1284                         return;
1285
1286                 if (nm_device_activate_ip4_state_in_wait (self))
1287                         nm_device_activate_stage3_ip4_start (self);
1288                 if (nm_device_activate_ip6_state_in_wait (self))
1289                         nm_device_activate_stage3_ip6_start (self);
1290
1291                 return;
1292         } else if (nm_device_get_enslaved (self) && !carrier) {
1293                 /* Slaves don't deactivate when they lose carrier; for
1294                  * bonds/teams in particular that would be actively
1295                  * counterproductive.
1296                  */
1297                 return;
1298         }
1299
1300         if (carrier) {
1301                 if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) {
1302                         nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED,
1303                                                NM_DEVICE_STATE_REASON_CARRIER);
1304                 } else if (priv->state == NM_DEVICE_STATE_DISCONNECTED) {
1305                         /* If the device is already in DISCONNECTED state without a carrier
1306                          * (probably because it is tagged for carrier ignore) ensure that
1307                          * when the carrier appears, auto connections are rechecked for
1308                          * the device.
1309                          */
1310                         nm_device_emit_recheck_auto_activate (self);
1311                 } else if (priv->state == NM_DEVICE_STATE_ACTIVATED) {
1312                         /* If the device is active without a carrier (probably because it is
1313                          * tagged for carrier ignore) ensure that when the carrier appears we
1314                          * renew DHCP leases and such.
1315                          */
1316                         update_dynamic_ip_setup (self);
1317                 }
1318         } else {
1319                 if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) {
1320                         if (nm_device_queued_state_peek (self) >= NM_DEVICE_STATE_DISCONNECTED)
1321                                 nm_device_queued_state_clear (self);
1322                 } else {
1323                         nm_device_queue_state (self, NM_DEVICE_STATE_UNAVAILABLE,
1324                                                NM_DEVICE_STATE_REASON_CARRIER);
1325                 }
1326         }
1327 }
1328
1329 #define LINK_DISCONNECT_DELAY 4
1330
1331 static gboolean
1332 link_disconnect_action_cb (gpointer user_data)
1333 {
1334         NMDevice *self = NM_DEVICE (user_data);
1335         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1336
1337         _LOGD (LOGD_DEVICE, "link disconnected (calling deferred action) (id=%u)", priv->carrier_defer_id);
1338
1339         priv->carrier_defer_id = 0;
1340
1341         _LOGI (LOGD_DEVICE, "link disconnected (calling deferred action)");
1342
1343         NM_DEVICE_GET_CLASS (self)->carrier_changed (self, FALSE);
1344
1345         return FALSE;
1346 }
1347
1348 static void
1349 link_disconnect_action_cancel (NMDevice *self)
1350 {
1351         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1352
1353         if (priv->carrier_defer_id) {
1354                 g_source_remove (priv->carrier_defer_id);
1355                 _LOGD (LOGD_DEVICE, "link disconnected (canceling deferred action) (id=%u)", priv->carrier_defer_id);
1356                 priv->carrier_defer_id = 0;
1357         }
1358 }
1359
1360 void
1361 nm_device_set_carrier (NMDevice *self, gboolean carrier)
1362 {
1363         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1364         NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
1365         NMDeviceState state = nm_device_get_state (self);
1366
1367         if (priv->carrier == carrier)
1368                 return;
1369
1370         priv->carrier = carrier;
1371         _notify (self, PROP_CARRIER);
1372
1373         if (priv->carrier) {
1374                 _LOGI (LOGD_DEVICE, "link connected");
1375                 link_disconnect_action_cancel (self);
1376                 klass->carrier_changed (self, TRUE);
1377
1378                 if (nm_clear_g_source (&priv->carrier_wait_id)) {
1379                         nm_device_remove_pending_action (self, "carrier wait", TRUE);
1380                         _carrier_wait_check_queued_act_request (self);
1381                 }
1382         } else if (state <= NM_DEVICE_STATE_DISCONNECTED) {
1383                 _LOGI (LOGD_DEVICE, "link disconnected");
1384                 klass->carrier_changed (self, FALSE);
1385         } else {
1386                 _LOGI (LOGD_DEVICE, "link disconnected (deferring action for %d seconds)", LINK_DISCONNECT_DELAY);
1387                 priv->carrier_defer_id = g_timeout_add_seconds (LINK_DISCONNECT_DELAY,
1388                                                                 link_disconnect_action_cb, self);
1389                 _LOGD (LOGD_DEVICE, "link disconnected (deferring action for %d seconds) (id=%u)",
1390                        LINK_DISCONNECT_DELAY, priv->carrier_defer_id);
1391         }
1392 }
1393
1394 static void
1395 device_recheck_slave_status (NMDevice *self, const NMPlatformLink *plink)
1396 {
1397         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1398
1399         g_return_if_fail (plink);
1400
1401         if (plink->master <= 0)
1402                 return;
1403
1404         if (priv->master) {
1405                 if (   plink->master > 0
1406                     && plink->master == nm_device_get_ifindex (priv->master)) {
1407                         /* call add-slave again. We expect @self already to be added to
1408                          * the master, but this also triggers a recheck-assume. */
1409                         nm_device_master_add_slave (priv->master, self, FALSE);
1410                         return;
1411                 }
1412
1413                 nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
1414         }
1415         if (plink->master > 0) {
1416                 NMDevice *master;
1417
1418                 master = nm_manager_get_device_by_ifindex (nm_manager_get (), plink->master);
1419                 if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave)
1420                         nm_device_master_add_slave (master, self, FALSE);
1421                 else if (master) {
1422                         _LOGI (LOGD_DEVICE, "enslaved to non-master-type device %s; ignoring",
1423                                nm_device_get_iface (master));
1424                 } else {
1425                         _LOGW (LOGD_DEVICE, "enslaved to unknown device %d %s",
1426                                plink->master,
1427                                nm_platform_link_get_name (NM_PLATFORM_GET, plink->master));
1428                 }
1429         }
1430 }
1431
1432 static gboolean
1433 device_link_changed (NMDevice *self)
1434 {
1435         NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
1436         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1437         NMUtilsIPv6IfaceId token_iid;
1438         gboolean ip_ifname_changed = FALSE;
1439         const char *udi;
1440         NMPlatformLink info;
1441         const NMPlatformLink *pllink;
1442         int ifindex;
1443
1444         priv->device_link_changed_id = 0;
1445
1446         ifindex = nm_device_get_ifindex (self);
1447         pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex);
1448         if (!pllink)
1449                 return G_SOURCE_REMOVE;
1450
1451         info = *pllink;
1452
1453         udi = nm_platform_link_get_udi (NM_PLATFORM_GET, info.ifindex);
1454         if (udi && g_strcmp0 (udi, priv->udi)) {
1455                 /* Update UDI to what udev gives us */
1456                 g_free (priv->udi);
1457                 priv->udi = g_strdup (udi);
1458                 _notify (self, PROP_UDI);
1459         }
1460
1461         if (g_strcmp0 (info.driver, priv->driver)) {
1462                 /* Update driver to what udev gives us */
1463                 g_free (priv->driver);
1464                 priv->driver = g_strdup (info.driver);
1465                 _notify (self, PROP_DRIVER);
1466         }
1467
1468         /* Update MTU if it has changed. */
1469         if (priv->mtu != info.mtu) {
1470                 priv->mtu = info.mtu;
1471                 _notify (self, PROP_MTU);
1472         }
1473
1474         if (info.driver && g_strcmp0 (priv->driver, info.driver) != 0) {
1475                 g_free (priv->driver);
1476                 priv->driver = g_strdup (info.driver);
1477                 _notify (self, PROP_DRIVER);
1478         }
1479
1480         if (info.name[0] && strcmp (priv->iface, info.name) != 0) {
1481                 _LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'",
1482                        priv->ifindex, priv->iface, info.name);
1483                 g_free (priv->iface);
1484                 priv->iface = g_strdup (info.name);
1485
1486                 /* If the device has no explicit ip_iface, then changing iface changes ip_iface too. */
1487                 ip_ifname_changed = !priv->ip_iface;
1488
1489                 _notify (self, PROP_IFACE);
1490                 if (ip_ifname_changed)
1491                         _notify (self, PROP_IP_IFACE);
1492
1493                 /* Re-match available connections against the new interface name */
1494                 nm_device_recheck_available_connections (self);
1495
1496                 /* Let any connections that use the new interface name have a chance
1497                  * to auto-activate on the device.
1498                  */
1499                 nm_device_emit_recheck_auto_activate (self);
1500         }
1501
1502         if (priv->rdisc && nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &token_iid)) {
1503                 _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
1504                 if (nm_rdisc_set_iid (priv->rdisc, token_iid))
1505                         nm_rdisc_start (priv->rdisc);
1506         }
1507
1508         if (klass->link_changed)
1509                 klass->link_changed (self, &info);
1510
1511         /* Update DHCP, etc, if needed */
1512         if (ip_ifname_changed)
1513                 update_dynamic_ip_setup (self);
1514
1515         priv->up = NM_FLAGS_HAS (info.n_ifi_flags, IFF_UP);
1516
1517         if (   info.initialized
1518             && nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
1519                 NMDeviceStateReason reason;
1520
1521                 nm_device_set_unmanaged_by_user_udev (self);
1522
1523                 /* If the device is a external-down candidated but no longer has external
1524                  * down set, we must clear the platform-unmanaged flag with reason
1525                  * "assumed". */
1526                 if (    nm_device_get_unmanaged_mask (self, NM_UNMANAGED_EXTERNAL_DOWN)
1527                     && !nm_device_get_unmanaged_flags (self, NM_UNMANAGED_EXTERNAL_DOWN)) {
1528                         /* Ensure the assume check is queued before any queued state changes
1529                          * from the transition to UNAVAILABLE.
1530                          */
1531                         nm_device_queue_recheck_assume (self);
1532                         reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED;
1533                 } else
1534                         reason = NM_DEVICE_STATE_REASON_NOW_MANAGED;
1535
1536                 nm_device_set_unmanaged_by_flags (self, NM_UNMANAGED_PLATFORM_INIT, FALSE, reason);
1537         }
1538
1539         if (nm_device_get_unmanaged_mask (self, NM_UNMANAGED_EXTERNAL_DOWN)) {
1540                 NMUnmanFlagOp ext_flags;
1541
1542                 ext_flags = is_unmanaged_external_down (self, FALSE);
1543                 if (ext_flags != NM_UNMAN_FLAG_OP_SET_UNMANAGED) {
1544                         /* Ensure the assume check is queued before any queued state changes
1545                          * from the transition to UNAVAILABLE.
1546                          */
1547                         nm_device_queue_recheck_assume (self);
1548                 }
1549
1550                 nm_device_set_unmanaged_by_flags (self,
1551                                                   NM_UNMANAGED_EXTERNAL_DOWN,
1552                                                   ext_flags,
1553                                                   NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
1554         }
1555
1556         device_recheck_slave_status (self, &info);
1557         return G_SOURCE_REMOVE;
1558 }
1559
1560 static gboolean
1561 device_ip_link_changed (NMDevice *self)
1562 {
1563         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1564         const NMPlatformLink *pllink;
1565
1566         priv->device_ip_link_changed_id = 0;
1567
1568         if (!priv->ip_ifindex)
1569                 return G_SOURCE_REMOVE;
1570
1571         pllink = nm_platform_link_get (NM_PLATFORM_GET, priv->ip_ifindex);
1572         if (!pllink)
1573                 return G_SOURCE_REMOVE;
1574
1575         if (pllink->name[0] && g_strcmp0 (priv->ip_iface, pllink->name)) {
1576                 _LOGI (LOGD_DEVICE, "interface index %d renamed ip_iface (%d) from '%s' to '%s'",
1577                        priv->ifindex, nm_device_get_ip_ifindex (self),
1578                        priv->ip_iface, pllink->name);
1579                 g_free (priv->ip_iface);
1580                 priv->ip_iface = g_strdup (pllink->name);
1581
1582                 _notify (self, PROP_IP_IFACE);
1583                 update_dynamic_ip_setup (self);
1584         }
1585         return G_SOURCE_REMOVE;
1586 }
1587
1588 static void
1589 link_changed_cb (NMPlatform *platform,
1590                  NMPObjectType obj_type,
1591                  int ifindex,
1592                  NMPlatformLink *info,
1593                  NMPlatformSignalChangeType change_type,
1594                  NMDevice *self)
1595 {
1596         NMDevicePrivate *priv;
1597
1598         if (change_type != NM_PLATFORM_SIGNAL_CHANGED)
1599                 return;
1600
1601         priv = NM_DEVICE_GET_PRIVATE (self);
1602
1603         if (ifindex == nm_device_get_ifindex (self)) {
1604                 if (!priv->device_link_changed_id) {
1605                         priv->device_link_changed_id = g_idle_add ((GSourceFunc) device_link_changed, self);
1606                         _LOGD (LOGD_DEVICE, "queued link change for ifindex %d", ifindex);
1607                 }
1608         } else if (ifindex == nm_device_get_ip_ifindex (self)) {
1609                 if (!priv->device_ip_link_changed_id) {
1610                         priv->device_ip_link_changed_id = g_idle_add ((GSourceFunc) device_ip_link_changed, self);
1611                         _LOGD (LOGD_DEVICE, "queued link change for ip-ifindex %d", ifindex);
1612                 }
1613         }
1614 }
1615
1616 static void
1617 link_changed (NMDevice *self, NMPlatformLink *info)
1618 {
1619         /* Update carrier from link event if applicable. */
1620         if (   nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)
1621             && !nm_device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER))
1622                 nm_device_set_carrier (self, info->connected);
1623 }
1624
1625 static gboolean
1626 link_type_compatible (NMDevice *self,
1627                       NMLinkType link_type,
1628                       gboolean *out_compatible,
1629                       GError **error)
1630 {
1631         NMDeviceClass *klass;
1632         NMLinkType device_type;
1633         guint i = 0;
1634
1635         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
1636
1637         klass = NM_DEVICE_GET_CLASS (self);
1638
1639         if (!klass->link_types) {
1640                 NM_SET_OUT (out_compatible, FALSE);
1641                 g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
1642                                      "Device does not support platform links");
1643                 return FALSE;
1644         }
1645
1646         device_type = self->priv->link_type;
1647         if (device_type > NM_LINK_TYPE_UNKNOWN && device_type != link_type) {
1648                 g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
1649                              "Needed link type 0x%x does not match the platform link type 0x%X",
1650                              device_type, link_type);
1651                 return FALSE;
1652         }
1653
1654         for (i = 0; klass->link_types[i] > NM_LINK_TYPE_UNKNOWN; i++) {
1655                 if (klass->link_types[i] == link_type)
1656                         return TRUE;
1657                 if (klass->link_types[i] == NM_LINK_TYPE_ANY)
1658                         return TRUE;
1659         }
1660
1661         NM_SET_OUT (out_compatible, FALSE);
1662         g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
1663                      "Device does not support platform link type 0x%X",
1664                      link_type);
1665         return FALSE;
1666 }
1667
1668 /**
1669  * nm_device_realize_start():
1670  * @self: the #NMDevice
1671  * @plink: an existing platform link or %NULL
1672  * @out_compatible: %TRUE on return if @self is compatible with @plink
1673  * @error: location to store error, or %NULL
1674  *
1675  * Initializes and sets up the device using existing backing resources. Before
1676  * the device is ready for use nm_device_realize_finish() must be called.
1677  * @out_compatible will only be set if @plink is not %NULL, and
1678  *
1679  * Important: if nm_device_realize_start() returns %TRUE, the caller MUST
1680  * also call nm_device_realize_finish() to balance g_object_freeze_notify().
1681  *
1682  * Returns: %TRUE on success, %FALSE on error
1683  */
1684 gboolean
1685 nm_device_realize_start (NMDevice *self,
1686                          const NMPlatformLink *plink,
1687                          gboolean *out_compatible,
1688                          GError **error)
1689 {
1690         NM_SET_OUT (out_compatible, TRUE);
1691
1692         if (plink) {
1693                 if (g_strcmp0 (nm_device_get_iface (self), plink->name) != 0) {
1694                         NM_SET_OUT (out_compatible, FALSE);
1695                         g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
1696                                              "Device interface name does not match platform link");
1697                         return FALSE;
1698                 }
1699
1700                 if (!link_type_compatible (self, plink->type, out_compatible, error))
1701                         return FALSE;
1702         }
1703
1704         realize_start_setup (self, plink);
1705
1706         return TRUE;
1707 }
1708
1709 /**
1710  * nm_device_create_and_realize():
1711  * @self: the #NMDevice
1712  * @connection: the #NMConnection being activated
1713  * @parent: the parent #NMDevice if any
1714  * @error: location to store error, or %NULL
1715  *
1716  * Creates any backing resources needed to realize the device to proceed
1717  * with activating @connection.
1718  *
1719  * Returns: %TRUE on success, %FALSE on error
1720  */
1721 gboolean
1722 nm_device_create_and_realize (NMDevice *self,
1723                               NMConnection *connection,
1724                               NMDevice *parent,
1725                               GError **error)
1726 {
1727         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1728         NMPlatformLink plink_copy;
1729         const NMPlatformLink *plink = NULL;
1730
1731         /* Must be set before device is realized */
1732         priv->is_nm_owned = !nm_platform_link_get_by_ifname (NM_PLATFORM_GET, priv->iface);
1733
1734         _LOGD (LOGD_DEVICE, "create (is %snm-owned)", priv->is_nm_owned ? "" : "not ");
1735
1736         /* Create any resources the device needs */
1737         if (NM_DEVICE_GET_CLASS (self)->create_and_realize) {
1738                 if (!NM_DEVICE_GET_CLASS (self)->create_and_realize (self, connection, parent, &plink, error))
1739                         return FALSE;
1740                 plink_copy = *plink;
1741                 plink = &plink_copy;
1742         }
1743
1744         realize_start_setup (self, plink);
1745         nm_device_realize_finish (self, plink);
1746
1747         if (nm_device_get_managed (self, FALSE)) {
1748                 nm_device_state_changed (self,
1749                                          NM_DEVICE_STATE_UNAVAILABLE,
1750                                          NM_DEVICE_STATE_REASON_NOW_MANAGED);
1751         }
1752         return TRUE;
1753 }
1754
1755 static void
1756 update_device_from_platform_link (NMDevice *self, const NMPlatformLink *plink)
1757 {
1758         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1759         const char *udi;
1760
1761         g_return_if_fail (plink != NULL);
1762
1763         udi = nm_platform_link_get_udi (NM_PLATFORM_GET, plink->ifindex);
1764         if (udi && !g_strcmp0 (udi, priv->udi)) {
1765                 g_free (priv->udi);
1766                 priv->udi = g_strdup (udi);
1767                 _notify (self, PROP_UDI);
1768         }
1769
1770         if (!g_strcmp0 (plink->name, priv->iface)) {
1771                 g_free (priv->iface);
1772                 priv->iface = g_strdup (plink->name);
1773                 _notify (self, PROP_IFACE);
1774         }
1775
1776         priv->ifindex = plink->ifindex;
1777         _notify (self, PROP_IFINDEX);
1778
1779         priv->up = NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP);
1780         if (plink->driver && g_strcmp0 (plink->driver, priv->driver) != 0) {
1781                 g_free (priv->driver);
1782                 priv->driver = g_strdup (plink->driver);
1783                 _notify (self, PROP_DRIVER);
1784         }
1785 }
1786
1787 static void
1788 config_changed_update_ignore_carrier (NMConfig *config,
1789                                       NMConfigData *config_data,
1790                                       NMConfigChangeFlags changes,
1791                                       NMConfigData *old_data,
1792                                       NMDevice *self)
1793 {
1794         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1795
1796         if (   priv->state <= NM_DEVICE_STATE_DISCONNECTED
1797             || priv->state > NM_DEVICE_STATE_ACTIVATED)
1798                 priv->ignore_carrier = nm_config_data_get_ignore_carrier (config_data, self);
1799 }
1800
1801 static void
1802 check_carrier (NMDevice *self)
1803 {
1804         int ifindex = nm_device_get_ip_ifindex (self);
1805
1806         if (!nm_device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER))
1807                 nm_device_set_carrier (self, nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
1808 }
1809
1810 static void
1811 realize_start_notify (NMDevice *self, const NMPlatformLink *plink)
1812 {
1813         /* Stub implementation for realize_start_notify(). It does nothing,
1814          * but allows derived classes to uniformly invoke the parent
1815          * implementation. */
1816 }
1817
1818 /**
1819  * realize_start_setup():
1820  * @self: the #NMDevice
1821  * @plink: the #NMPlatformLink if backed by a kernel netdevice
1822  *
1823  * Update the device from backing resource properties (like hardware
1824  * addresses, carrier states, driver/firmware info, etc).  This function
1825  * should only change properties for this device, and should not perform
1826  * any tasks that affect other interfaces (like master/slave or parent/child
1827  * stuff).
1828  */
1829 static void
1830 realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
1831 {
1832         NMDevicePrivate *priv;
1833         NMDeviceClass *klass;
1834         static guint32 id = 0;
1835
1836         g_return_if_fail (NM_IS_DEVICE (self));
1837
1838         priv = NM_DEVICE_GET_PRIVATE (self);
1839
1840         /* The device should not be realized */
1841         g_return_if_fail (!priv->real);
1842         g_return_if_fail (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT));
1843         g_return_if_fail (priv->ip_ifindex <= 0);
1844         g_return_if_fail (priv->ip_iface == NULL);
1845
1846         _LOGD (LOGD_DEVICE, "start setup of %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), plink ? plink->ifindex : 0);
1847
1848         klass = NM_DEVICE_GET_CLASS (self);
1849
1850         /* Balanced by a thaw in nm_device_realize_finish() */
1851         g_object_freeze_notify (G_OBJECT (self));
1852
1853         if (plink) {
1854                 g_return_if_fail (link_type_compatible (self, plink->type, NULL, NULL));
1855                 update_device_from_platform_link (self, plink);
1856         }
1857
1858         if (priv->ifindex > 0) {
1859                 priv->physical_port_id = nm_platform_link_get_physical_port_id (NM_PLATFORM_GET, priv->ifindex);
1860                 _notify (self, PROP_PHYSICAL_PORT_ID);
1861
1862                 priv->dev_id = nm_platform_link_get_dev_id (NM_PLATFORM_GET, priv->ifindex);
1863
1864                 if (nm_platform_link_is_software (NM_PLATFORM_GET, priv->ifindex))
1865                         priv->capabilities |= NM_DEVICE_CAP_IS_SOFTWARE;
1866
1867                 priv->mtu = nm_platform_link_get_mtu (NM_PLATFORM_GET, priv->ifindex);
1868                 _notify (self, PROP_MTU);
1869
1870                 nm_platform_link_get_driver_info (NM_PLATFORM_GET,
1871                                                   priv->ifindex,
1872                                                   NULL,
1873                                                   &priv->driver_version,
1874                                                   &priv->firmware_version);
1875                 if (priv->driver_version)
1876                         _notify (self, PROP_DRIVER_VERSION);
1877                 if (priv->firmware_version)
1878                         _notify (self, PROP_FIRMWARE_VERSION);
1879
1880                 if (nm_platform_check_support_user_ipv6ll (NM_PLATFORM_GET))
1881                         priv->nm_ipv6ll = nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, priv->ifindex);
1882         }
1883
1884         if (klass->get_generic_capabilities)
1885                 priv->capabilities |= klass->get_generic_capabilities (self);
1886
1887         if (!priv->udi) {
1888                 /* Use a placeholder UDI until we get a real one */
1889                 priv->udi = g_strdup_printf ("/virtual/device/placeholder/%d", id++);
1890                 _notify (self, PROP_UDI);
1891         }
1892
1893         /* trigger initial ip config change to initialize ip-config */
1894         priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
1895         priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
1896
1897         nm_device_update_hw_address (self);
1898         nm_device_update_initial_hw_address (self);
1899
1900         /* Note: initial hardware address must be read before calling get_ignore_carrier() */
1901         if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
1902                 NMConfig *config = nm_config_get ();
1903
1904                 priv->ignore_carrier = nm_config_data_get_ignore_carrier (nm_config_get_data (config), self);
1905                 g_signal_connect (G_OBJECT (config),
1906                                   NM_CONFIG_SIGNAL_CONFIG_CHANGED,
1907                                   G_CALLBACK (config_changed_update_ignore_carrier),
1908                                   self);
1909
1910                 check_carrier (self);
1911                 _LOGD (LOGD_HW,
1912                        "carrier is %s%s",
1913                        priv->carrier ? "ON" : "OFF",
1914                        priv->ignore_carrier ? " (but ignored)" : "");
1915         } else {
1916                 /* Fake online link when carrier detection is not available. */
1917                 priv->carrier = TRUE;
1918         }
1919
1920         _notify (self, PROP_CAPABILITIES);
1921
1922         klass->realize_start_notify (self, plink);
1923
1924         /* Do not manage externally created software devices until they are IFF_UP
1925          * or have IP addressing */
1926         nm_device_set_unmanaged_flags (self,
1927                                        NM_UNMANAGED_EXTERNAL_DOWN,
1928                                        is_unmanaged_external_down (self, TRUE));
1929
1930         /* Unmanaged the loopback device with an explicit NM_UNMANAGED_LOOPBACK flag.
1931          * Later we might want to manage 'lo' too. Currently that doesn't work because
1932          * NetworkManager might down the interface or remove the 127.0.0.1 address. */
1933         nm_device_set_unmanaged_flags (self, NM_UNMANAGED_LOOPBACK, priv->ifindex == 1);
1934
1935         nm_device_set_unmanaged_by_user_udev (self);
1936
1937         nm_device_set_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT,
1938                                        plink && !plink->initialized);
1939 }
1940
1941 /**
1942  * nm_device_realize_finish():
1943  * @self: the #NMDevice
1944  * @plink: the #NMPlatformLink if backed by a kernel netdevice
1945  *
1946  * Update the device's master/slave or parent/child relationships from
1947  * backing resource properties.  After this function finishes, the device
1948  * is ready for network connectivity.
1949  */
1950 void
1951 nm_device_realize_finish (NMDevice *self, const NMPlatformLink *plink)
1952 {
1953         NMDevicePrivate *priv;
1954
1955         g_return_if_fail (NM_IS_DEVICE (self));
1956         g_return_if_fail (!plink || link_type_compatible (self, plink->type, NULL, NULL));
1957
1958         priv = NM_DEVICE_GET_PRIVATE (self);
1959
1960         g_return_if_fail (!priv->real);
1961
1962         if (plink)
1963                 device_recheck_slave_status (self, plink);
1964
1965         priv->real = TRUE;
1966         _notify (self, PROP_REAL);
1967
1968         nm_device_recheck_available_connections (self);
1969
1970         /* Balanced by a freeze in realize_start_setup(). */
1971         g_object_thaw_notify (G_OBJECT (self));
1972 }
1973
1974 static void
1975 unrealize_notify (NMDevice *self)
1976 {
1977         /* Stub implementation for unrealize_notify(). It does nothing,
1978          * but allows derived classes to uniformly invoke the parent
1979          * implementation. */
1980 }
1981
1982 static gboolean
1983 available_connections_check_delete_unrealized_on_idle (gpointer user_data)
1984 {
1985         NMDevice *self = user_data;
1986         NMDevicePrivate *priv;
1987
1988         g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE);
1989
1990         priv = NM_DEVICE_GET_PRIVATE (self);
1991
1992         priv->check_delete_unrealized_id = 0;
1993
1994         if (   g_hash_table_size (priv->available_connections) == 0
1995             && !nm_device_is_real (self))
1996                 g_signal_emit (self, signals[REMOVED], 0);
1997
1998         return G_SOURCE_REMOVE;
1999 }
2000
2001 static void
2002 available_connections_check_delete_unrealized (NMDevice *self)
2003 {
2004         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2005
2006         /* always rescheadule the remove signal. */
2007         nm_clear_g_source (&priv->check_delete_unrealized_id);
2008
2009         if (   g_hash_table_size (priv->available_connections) == 0
2010             && !nm_device_is_real (self))
2011                 priv->check_delete_unrealized_id = g_idle_add (available_connections_check_delete_unrealized_on_idle, self);
2012 }
2013
2014 /**
2015  * nm_device_unrealize():
2016  * @self: the #NMDevice
2017  * @remove_resources: if %TRUE, remove backing resources
2018  * @error: location to store error, or %NULL
2019  *
2020  * Clears any properties that depend on backing resources (kernel devices,
2021  * etc) and removes those resources if @remove_resources is %TRUE.
2022  *
2023  * Returns: %TRUE on success, %FALSE on error
2024  */
2025 gboolean
2026 nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
2027 {
2028         NMDevicePrivate *priv;
2029         int ifindex;
2030
2031         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
2032
2033         if (!nm_device_is_software (self) || !nm_device_is_real (self)) {
2034                 g_set_error_literal (error,
2035                                      NM_DEVICE_ERROR,
2036                                      NM_DEVICE_ERROR_NOT_SOFTWARE,
2037                                      "This device is not a software device or is not realized");
2038                 return FALSE;
2039         }
2040
2041         priv = NM_DEVICE_GET_PRIVATE (self);
2042
2043         g_return_val_if_fail (priv->iface != NULL, FALSE);
2044         g_return_val_if_fail (priv->real, FALSE);
2045
2046         g_object_freeze_notify (G_OBJECT (self));
2047
2048         ifindex = nm_device_get_ifindex (self);
2049
2050         _LOGD (LOGD_DEVICE, "unrealize (ifindex %d)", ifindex > 0 ? ifindex : 0);
2051
2052         if (remove_resources) {
2053                 if (ifindex > 0)
2054                         nm_platform_link_delete (NM_PLATFORM_GET, ifindex);
2055         }
2056
2057         NM_DEVICE_GET_CLASS (self)->unrealize_notify (self);
2058
2059         if (priv->ifindex > 0) {
2060                 priv->ifindex = 0;
2061                 _notify (self, PROP_IFINDEX);
2062         }
2063         priv->ip_ifindex = 0;
2064         if (priv->ip_iface) {
2065                 g_clear_pointer (&priv->ip_iface, g_free);
2066                 _notify (self, PROP_IP_IFACE);
2067         }
2068         if (priv->driver_version) {
2069                 g_clear_pointer (&priv->driver_version, g_free);
2070                 _notify (self, PROP_DRIVER_VERSION);
2071         }
2072         if (priv->firmware_version) {
2073                 g_clear_pointer (&priv->firmware_version, g_free);
2074                 _notify (self, PROP_FIRMWARE_VERSION);
2075         }
2076         if (priv->udi) {
2077                 g_clear_pointer (&priv->udi, g_free);
2078                 _notify (self, PROP_UDI);
2079         }
2080         if (priv->hw_addr) {
2081                 g_clear_pointer (&priv->hw_addr, g_free);
2082                 _notify (self, PROP_HW_ADDRESS);
2083         }
2084         if (priv->physical_port_id) {
2085                 g_clear_pointer (&priv->physical_port_id, g_free);
2086                 _notify (self, PROP_PHYSICAL_PORT_ID);
2087         }
2088
2089         g_clear_pointer (&priv->perm_hw_addr, g_free);
2090         g_clear_pointer (&priv->initial_hw_addr, g_free);
2091
2092         priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED;
2093         if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
2094                 priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
2095         _notify (self, PROP_CAPABILITIES);
2096
2097         priv->real = FALSE;
2098         _notify (self, PROP_REAL);
2099
2100         nm_device_set_autoconnect (self, DEFAULT_AUTOCONNECT);
2101
2102         g_object_thaw_notify (G_OBJECT (self));
2103
2104         nm_device_set_unmanaged_flags (self,
2105                                        NM_UNMANAGED_PLATFORM_INIT,
2106                                        TRUE);
2107
2108         nm_device_set_unmanaged_flags (self,
2109                                        NM_UNMANAGED_PARENT |
2110                                        NM_UNMANAGED_LOOPBACK |
2111                                        NM_UNMANAGED_USER_UDEV |
2112                                        NM_UNMANAGED_EXTERNAL_DOWN |
2113                                        NM_UNMANAGED_IS_SLAVE,
2114                                        NM_UNMAN_FLAG_OP_FORGET);
2115
2116         nm_device_state_changed (self,
2117                                  NM_DEVICE_STATE_UNMANAGED,
2118                                  remove_resources ?
2119                                      NM_DEVICE_STATE_REASON_USER_REQUESTED : NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
2120
2121         /* Garbage-collect unneeded unrealized devices. */
2122         nm_device_recheck_available_connections (self);
2123
2124         return TRUE;
2125 }
2126
2127 /**
2128  * nm_device_notify_new_device_added():
2129  * @self: the #NMDevice
2130  * @device: the newly added device
2131  *
2132  * Called by the manager to notify the device that a new device has
2133  * been found and added.
2134  */
2135 void
2136 nm_device_notify_new_device_added (NMDevice *self, NMDevice *device)
2137 {
2138         NMDeviceClass *klass;
2139
2140         g_return_if_fail (NM_IS_DEVICE (self));
2141         g_return_if_fail (NM_IS_DEVICE (device));
2142
2143         klass = NM_DEVICE_GET_CLASS (self);
2144         if (klass->notify_new_device_added)
2145                 klass->notify_new_device_added (self, device);
2146 }
2147
2148 /**
2149  * nm_device_notify_component_added():
2150  * @self: the #NMDevice
2151  * @component: the component being added by a plugin
2152  *
2153  * Called by the manager to notify the device that a new component has
2154  * been found.  The device implementation should return %TRUE if it
2155  * wishes to claim the component, or %FALSE if it cannot.
2156  *
2157  * Returns: %TRUE to claim the component, %FALSE if the component cannot be
2158  * claimed.
2159  */
2160 gboolean
2161 nm_device_notify_component_added (NMDevice *self, GObject *component)
2162 {
2163         NMDeviceClass *klass;
2164
2165         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
2166         g_return_val_if_fail (G_IS_OBJECT (component), FALSE);
2167
2168         klass = NM_DEVICE_GET_CLASS (self);
2169         if (klass->component_added)
2170                 return klass->component_added (self, component);
2171         return FALSE;
2172 }
2173
2174 /**
2175  * nm_device_owns_iface():
2176  * @self: the #NMDevice
2177  * @iface: an interface name
2178  *
2179  * Called by the manager to ask if the device or any of its components owns
2180  * @iface.  For example, a WWAN implementation would return %TRUE for an
2181  * ethernet interface name that was owned by the WWAN device's modem component,
2182  * because that ethernet interface is controlled by the WWAN device and cannot
2183  * be used independently of the WWAN device.
2184  *
2185  * Returns: %TRUE if @self or it's components owns the interface name,
2186  * %FALSE if not
2187  */
2188 gboolean
2189 nm_device_owns_iface (NMDevice *self, const char *iface)
2190 {
2191         if (NM_DEVICE_GET_CLASS (self)->owns_iface)
2192                 return NM_DEVICE_GET_CLASS (self)->owns_iface (self, iface);
2193         return FALSE;
2194 }
2195
2196 NMConnection *
2197 nm_device_new_default_connection (NMDevice *self)
2198 {
2199         if (NM_DEVICE_GET_CLASS (self)->new_default_connection)
2200                 return NM_DEVICE_GET_CLASS (self)->new_default_connection (self);
2201         return NULL;
2202 }
2203
2204 static void
2205 slave_state_changed (NMDevice *slave,
2206                      NMDeviceState slave_new_state,
2207                      NMDeviceState slave_old_state,
2208                      NMDeviceStateReason reason,
2209                      NMDevice *self)
2210 {
2211         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2212         gboolean release = FALSE;
2213
2214         _LOGD (LOGD_DEVICE, "slave %s state change %d (%s) -> %d (%s)",
2215                nm_device_get_iface (slave),
2216                slave_old_state,
2217                state_to_string (slave_old_state),
2218                slave_new_state,
2219                state_to_string (slave_new_state));
2220
2221         /* Don't try to enslave slaves until the master is ready */
2222         if (priv->state < NM_DEVICE_STATE_CONFIG)
2223                 return;
2224
2225         if (slave_new_state == NM_DEVICE_STATE_IP_CONFIG)
2226                 nm_device_master_enslave_slave (self, slave, nm_device_get_applied_connection (slave));
2227         else if (slave_new_state > NM_DEVICE_STATE_ACTIVATED)
2228                 release = TRUE;
2229         else if (   slave_new_state <= NM_DEVICE_STATE_DISCONNECTED
2230                  && slave_old_state > NM_DEVICE_STATE_DISCONNECTED) {
2231                 /* Catch failures due to unavailable or unmanaged */
2232                 release = TRUE;
2233         }
2234
2235         if (release) {
2236                 nm_device_master_release_one_slave (self, slave, TRUE, reason);
2237                 /* Bridge/bond/team interfaces are left up until manually deactivated */
2238                 if (priv->slaves == NULL && priv->state == NM_DEVICE_STATE_ACTIVATED)
2239                         _LOGD (LOGD_DEVICE, "last slave removed; remaining activated");
2240         }
2241 }
2242
2243 /**
2244  * nm_device_master_add_slave:
2245  * @self: the master device
2246  * @slave: the slave device to enslave
2247  * @configure: pass %TRUE if the slave should be configured by the master, or
2248  * %FALSE if it is already configured outside NetworkManager
2249  *
2250  * If @self is capable of enslaving other devices (ie it's a bridge, bond, team,
2251  * etc) then this function adds @slave to the slave list for later enslavement.
2252  */
2253 static void
2254 nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure)
2255 {
2256         NMDevicePrivate *priv;
2257         NMDevicePrivate *slave_priv;
2258         SlaveInfo *info;
2259
2260         g_return_if_fail (NM_IS_DEVICE (self));
2261         g_return_if_fail (NM_IS_DEVICE (slave));
2262         g_return_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL);
2263
2264         priv = NM_DEVICE_GET_PRIVATE (self);
2265         slave_priv = NM_DEVICE_GET_PRIVATE (slave);
2266
2267         info = find_slave_info (self, slave);
2268
2269         _LOGt (LOGD_CORE, "master: add one slave %p/%s%s", slave, nm_device_get_iface (slave),
2270                info ? " (already registered)" : "");
2271
2272         if (configure)
2273                 g_return_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED);
2274
2275         if (!info) {
2276                 g_return_if_fail (!slave_priv->master);
2277                 g_return_if_fail (!slave_priv->is_enslaved);
2278
2279                 info = g_slice_new0 (SlaveInfo);
2280                 info->slave = g_object_ref (slave);
2281                 info->configure = configure;
2282                 info->watch_id = g_signal_connect (slave,
2283                                                    NM_DEVICE_STATE_CHANGED,
2284                                                    G_CALLBACK (slave_state_changed), self);
2285                 priv->slaves = g_slist_append (priv->slaves, info);
2286                 slave_priv->master = g_object_ref (self);
2287
2288                 /* no need to emit
2289                  *
2290                  *   _notify (slave, PROP_MASTER);
2291                  *
2292                  * because slave_priv->is_enslaved is not true, thus the value
2293                  * didn't change yet. */
2294
2295                 g_warn_if_fail (!NM_FLAGS_HAS (slave_priv->unmanaged_mask, NM_UNMANAGED_IS_SLAVE));
2296                 nm_device_set_unmanaged_by_flags (slave, NM_UNMANAGED_IS_SLAVE, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
2297         } else
2298                 g_return_if_fail (slave_priv->master == self);
2299
2300         nm_device_queue_recheck_assume (self);
2301         nm_device_queue_recheck_assume (slave);
2302 }
2303
2304
2305 /**
2306  * nm_device_master_get_slaves:
2307  * @self: the master device
2308  *
2309  * Returns: any slaves of which @self is the master.  Caller owns returned list.
2310  */
2311 static GSList *
2312 nm_device_master_get_slaves (NMDevice *self)
2313 {
2314         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2315         GSList *slaves = NULL, *iter;
2316
2317         for (iter = priv->slaves; iter; iter = g_slist_next (iter))
2318                 slaves = g_slist_prepend (slaves, ((SlaveInfo *) iter->data)->slave);
2319
2320         return slaves;
2321 }
2322
2323 /**
2324  * nm_device_master_get_slave_by_ifindex:
2325  * @self: the master device
2326  * @ifindex: the slave's interface index
2327  *
2328  * Returns: the slave with the given @ifindex of which @self is the master,
2329  *   or %NULL if no device with @ifindex is a slave of @self.
2330  */
2331 NMDevice *
2332 nm_device_master_get_slave_by_ifindex (NMDevice *self, int ifindex)
2333 {
2334         GSList *iter;
2335
2336         for (iter = NM_DEVICE_GET_PRIVATE (self)->slaves; iter; iter = g_slist_next (iter)) {
2337                 SlaveInfo *info = iter->data;
2338
2339                 if (nm_device_get_ip_ifindex (info->slave) == ifindex)
2340                         return info->slave;
2341         }
2342         return NULL;
2343 }
2344
2345 /**
2346  * nm_device_master_check_slave_physical_port:
2347  * @self: the master device
2348  * @slave: a slave device
2349  * @log_domain: domain to log a warning in
2350  *
2351  * Checks if @self already has a slave with the same #NMDevice:physical-port-id
2352  * as @slave, and logs a warning if so.
2353  */
2354 void
2355 nm_device_master_check_slave_physical_port (NMDevice *self, NMDevice *slave,
2356                                             NMLogDomain log_domain)
2357 {
2358         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2359         const char *slave_physical_port_id, *existing_physical_port_id;
2360         SlaveInfo *info;
2361         GSList *iter;
2362
2363         slave_physical_port_id = nm_device_get_physical_port_id (slave);
2364         if (!slave_physical_port_id)
2365                 return;
2366
2367         for (iter = priv->slaves; iter; iter = iter->next) {
2368                 info = iter->data;
2369                 if (info->slave == slave)
2370                         continue;
2371
2372                 existing_physical_port_id = nm_device_get_physical_port_id (info->slave);
2373                 if (!g_strcmp0 (slave_physical_port_id, existing_physical_port_id)) {
2374                         _LOGW (log_domain, "slave %s shares a physical port with existing slave %s",
2375                                nm_device_get_ip_iface (slave),
2376                                nm_device_get_ip_iface (info->slave));
2377                         /* Since this function will get called for every slave, we only have
2378                          * to warn about the first match we find; if there are other matches
2379                          * later in the list, we will have already warned about them matching
2380                          * @existing earlier.
2381                          */
2382                         return;
2383                 }
2384         }
2385 }
2386
2387 /* release all slaves */
2388 static void
2389 nm_device_master_release_slaves (NMDevice *self)
2390 {
2391         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2392         NMDeviceStateReason reason;
2393         gboolean configure = TRUE;
2394
2395         /* Don't release the slaves if this connection doesn't belong to NM. */
2396         if (nm_device_uses_generated_assumed_connection (self))
2397                 return;
2398
2399         reason = priv->state_reason;
2400         if (priv->state == NM_DEVICE_STATE_FAILED)
2401                 reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED;
2402
2403         if (!nm_platform_link_get (NM_PLATFORM_GET, priv->ifindex))
2404                 configure = FALSE;
2405
2406         while (priv->slaves) {
2407                 SlaveInfo *info = priv->slaves->data;
2408
2409                 nm_device_master_release_one_slave (self, info->slave, configure, reason);
2410         }
2411 }
2412
2413 /**
2414  * nm_device_is_master:
2415  * @self: the device
2416  *
2417  * Returns: %TRUE if the device can have slaves
2418  */
2419 gboolean
2420 nm_device_is_master (NMDevice *self)
2421 {
2422         return NM_DEVICE_GET_PRIVATE (self)->is_master;
2423 }
2424
2425 /**
2426  * nm_device_get_master:
2427  * @self: the device
2428  *
2429  * If @self has been enslaved by another device, this returns that
2430  * device. Otherwise it returns %NULL. (In particular, note that if
2431  * @self is in the process of activating as a slave, but has not yet
2432  * been enslaved by its master, this will return %NULL.)
2433  *
2434  * Returns: (transfer none): @self's master, or %NULL
2435  */
2436 NMDevice *
2437 nm_device_get_master (NMDevice *self)
2438 {
2439         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2440
2441         if (priv->is_enslaved) {
2442                 g_return_val_if_fail (priv->master, NULL);
2443                 return priv->master;
2444         }
2445         return NULL;
2446 }
2447
2448 /**
2449  * nm_device_slave_notify_enslave:
2450  * @self: the slave device
2451  * @success: whether the enslaving operation succeeded
2452  *
2453  * Notifies a slave that either it has been enslaved, or else its master tried
2454  * to enslave it and failed.
2455  */
2456 static void
2457 nm_device_slave_notify_enslave (NMDevice *self, gboolean success)
2458 {
2459         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2460         NMConnection *connection = nm_device_get_applied_connection (self);
2461         gboolean activating = (priv->state == NM_DEVICE_STATE_IP_CONFIG);
2462
2463         g_return_if_fail (priv->master);
2464
2465         if (!priv->is_enslaved) {
2466                 if (success) {
2467                         if (activating) {
2468                                 _LOGI (LOGD_DEVICE, "Activation: connection '%s' enslaved, continuing activation",
2469                                        nm_connection_get_id (connection));
2470                         } else
2471                                 _LOGI (LOGD_DEVICE, "enslaved to %s", nm_device_get_iface (priv->master));
2472
2473                         priv->is_enslaved = TRUE;
2474                         _notify (self, PROP_MASTER);
2475                         _notify (priv->master, PROP_SLAVES);
2476                 } else if (activating) {
2477                         _LOGW (LOGD_DEVICE, "Activation: connection '%s' could not be enslaved",
2478                                nm_connection_get_id (connection));
2479                 }
2480         }
2481
2482         if (activating) {
2483                 priv->ip4_state = IP_DONE;
2484                 priv->ip6_state = IP_DONE;
2485                 if (success)
2486                         nm_device_queue_state (self, NM_DEVICE_STATE_SECONDARIES, NM_DEVICE_STATE_REASON_NONE);
2487                 else
2488                         nm_device_queue_state (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN);
2489         } else
2490                 nm_device_queue_recheck_assume (self);
2491 }
2492
2493 /**
2494  * nm_device_slave_notify_release:
2495  * @self: the slave device
2496  * @reason: the reason associated with the state change
2497  *
2498  * Notifies a slave that it has been released, and why.
2499  */
2500 static void
2501 nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason)
2502 {
2503         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2504         NMConnection *connection = nm_device_get_applied_connection (self);
2505         NMDeviceState new_state;
2506         const char *master_status;
2507
2508         g_return_if_fail (priv->master);
2509
2510         if (   priv->state > NM_DEVICE_STATE_DISCONNECTED
2511             && priv->state <= NM_DEVICE_STATE_ACTIVATED) {
2512                 if (reason == NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED) {
2513                         new_state = NM_DEVICE_STATE_FAILED;
2514                         master_status = "failed";
2515                 } else if (reason == NM_DEVICE_STATE_REASON_USER_REQUESTED) {
2516                         new_state = NM_DEVICE_STATE_DEACTIVATING;
2517                         master_status = "deactivated by user request";
2518                 } else {
2519                         new_state = NM_DEVICE_STATE_DISCONNECTED;
2520                         master_status = "deactivated";
2521                 }
2522
2523                 _LOGD (LOGD_DEVICE, "Activation: connection '%s' master %s",
2524                        nm_connection_get_id (connection),
2525                        master_status);
2526
2527                 nm_device_queue_state (self, new_state, reason);
2528         } else
2529                 _LOGI (LOGD_DEVICE, "released from master device %s", nm_device_get_iface (priv->master));
2530
2531         if (priv->is_enslaved) {
2532                 priv->is_enslaved = FALSE;
2533                 _notify (self, PROP_MASTER);
2534                 _notify (priv->master, PROP_SLAVES);
2535         }
2536 }
2537
2538 /**
2539  * nm_device_get_enslaved:
2540  * @self: the #NMDevice
2541  *
2542  * Returns: %TRUE if the device is enslaved to a master device (eg bridge or
2543  * bond or team), %FALSE if not
2544  */
2545 gboolean
2546 nm_device_get_enslaved (NMDevice *self)
2547 {
2548         return NM_DEVICE_GET_PRIVATE (self)->is_enslaved;
2549 }
2550
2551 /**
2552  * nm_device_removed:
2553  * @self: the #NMDevice
2554  *
2555  * Called by the manager when the device was removed. Releases the device from
2556  * the master in case it's enslaved.
2557  */
2558 void
2559 nm_device_removed (NMDevice *self)
2560 {
2561         NMDevicePrivate *priv;
2562
2563         g_return_if_fail (NM_IS_DEVICE (self));
2564
2565         priv = NM_DEVICE_GET_PRIVATE (self);
2566         if (priv->master) {
2567                 /* this is called when something externally messes with the slave or during shut-down.
2568                  * Release the slave from master, but don't touch the device. */
2569                 nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
2570         }
2571 }
2572
2573 static gboolean
2574 is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags)
2575 {
2576         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2577
2578         if (priv->carrier || priv->ignore_carrier)
2579                 return TRUE;
2580
2581         if (NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER))
2582                 return TRUE;
2583
2584         return FALSE;
2585 }
2586
2587 /**
2588  * nm_device_is_available:
2589  * @self: the #NMDevice
2590  * @flags: additional flags to influence the check. Flags have the
2591  *   meaning to increase the availability of a device.
2592  *
2593  * Checks if @self would currently be capable of activating a
2594  * connection. In particular, it checks that the device is ready (eg,
2595  * is not missing firmware), that it has carrier (if necessary), and
2596  * that any necessary external software (eg, ModemManager,
2597  * wpa_supplicant) is available.
2598  *
2599  * @self can only be in a state higher than
2600  * %NM_DEVICE_STATE_UNAVAILABLE when nm_device_is_available() returns
2601  * %TRUE. (But note that it can still be %NM_DEVICE_STATE_UNMANAGED
2602  * when it is available.)
2603  *
2604  * Returns: %TRUE or %FALSE
2605  */
2606 gboolean
2607 nm_device_is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags)
2608 {
2609         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2610
2611         if (priv->firmware_missing)
2612                 return FALSE;
2613
2614         return NM_DEVICE_GET_CLASS (self)->is_available (self, flags);
2615 }
2616
2617 gboolean
2618 nm_device_get_enabled (NMDevice *self)
2619 {
2620         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
2621
2622         if (NM_DEVICE_GET_CLASS (self)->get_enabled)
2623                 return NM_DEVICE_GET_CLASS (self)->get_enabled (self);
2624         return TRUE;
2625 }
2626
2627 void
2628 nm_device_set_enabled (NMDevice *self, gboolean enabled)
2629 {
2630         g_return_if_fail (NM_IS_DEVICE (self));
2631
2632         if (NM_DEVICE_GET_CLASS (self)->set_enabled)
2633                 NM_DEVICE_GET_CLASS (self)->set_enabled (self, enabled);
2634 }
2635
2636 /**
2637  * nm_device_get_autoconnect:
2638  * @self: the #NMDevice
2639  *
2640  * Returns: %TRUE if the device allows autoconnect connections, or %FALSE if the
2641  * device is explicitly blocking all autoconnect connections.  Does not take
2642  * into account transient conditions like companion devices that may wish to
2643  * block the device.
2644  */
2645 gboolean
2646 nm_device_get_autoconnect (NMDevice *self)
2647 {
2648         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
2649
2650         return NM_DEVICE_GET_PRIVATE (self)->autoconnect;
2651 }
2652
2653 void
2654 nm_device_set_autoconnect (NMDevice *self, gboolean autoconnect)
2655 {
2656         NMDevicePrivate *priv;
2657
2658         g_return_if_fail (NM_IS_DEVICE (self));
2659
2660         autoconnect = !!autoconnect;
2661
2662         priv = NM_DEVICE_GET_PRIVATE (self);
2663         if (priv->autoconnect != autoconnect) {
2664                 priv->autoconnect = autoconnect;
2665                 _notify (self, PROP_AUTOCONNECT);
2666         }
2667 }
2668
2669 static gboolean
2670 autoconnect_allowed_accumulator (GSignalInvocationHint *ihint,
2671                                  GValue *return_accu,
2672                                  const GValue *handler_return, gpointer data)
2673 {
2674         if (!g_value_get_boolean (handler_return))
2675                 g_value_set_boolean (return_accu, FALSE);
2676         return TRUE;
2677 }
2678
2679 /**
2680  * nm_device_autoconnect_allowed:
2681  * @self: the #NMDevice
2682  *
2683  * Returns: %TRUE if the device can be auto-connected immediately, taking
2684  * transient conditions into account (like companion devices that may wish to
2685  * block autoconnect for a time).
2686  */
2687 gboolean
2688 nm_device_autoconnect_allowed (NMDevice *self)
2689 {
2690         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2691         GValue instance = G_VALUE_INIT;
2692         GValue retval = G_VALUE_INIT;
2693
2694         if (!priv->autoconnect)
2695                 return FALSE;
2696
2697         /* Unrealized devices can always autoconnect. */
2698         if (nm_device_is_real (self) && priv->state < NM_DEVICE_STATE_DISCONNECTED)
2699                 return FALSE;
2700
2701         /* The 'autoconnect-allowed' signal is emitted on a device to allow
2702          * other listeners to block autoconnect on the device if they wish.
2703          * This is mainly used by the OLPC Mesh devices to block autoconnect
2704          * on their companion WiFi device as they share radio resources and
2705          * cannot be connected at the same time.
2706          */
2707
2708         g_value_init (&instance, G_TYPE_OBJECT);
2709         g_value_set_object (&instance, self);
2710
2711         g_value_init (&retval, G_TYPE_BOOLEAN);
2712         g_value_set_boolean (&retval, TRUE);
2713
2714         /* Use g_signal_emitv() rather than g_signal_emit() to avoid the return
2715          * value being changed if no handlers are connected */
2716         g_signal_emitv (&instance, signals[AUTOCONNECT_ALLOWED], 0, &retval);
2717         g_value_unset (&instance);
2718
2719         return g_value_get_boolean (&retval);
2720 }
2721
2722 static gboolean
2723 can_auto_connect (NMDevice *self,
2724                   NMConnection *connection,
2725                   char **specific_object)
2726 {
2727         NMSettingConnection *s_con;
2728
2729         s_con = nm_connection_get_setting_connection (connection);
2730         if (!nm_setting_connection_get_autoconnect (s_con))
2731                 return FALSE;
2732
2733         return nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, NULL);
2734 }
2735
2736 /**
2737  * nm_device_can_auto_connect:
2738  * @self: an #NMDevice
2739  * @connection: a #NMConnection
2740  * @specific_object: (out) (transfer full): on output, the path of an
2741  *   object associated with the returned connection, to be passed to
2742  *   nm_manager_activate_connection(), or %NULL.
2743  *
2744  * Checks if @connection can be auto-activated on @self right now.
2745  * This requires, at a minimum, that the connection be compatible with
2746  * @self, and that it have the #NMSettingConnection:autoconnect property
2747  * set, and that the device allow auto connections. Some devices impose
2748  * additional requirements. (Eg, a Wi-Fi connection can only be activated
2749  * if its SSID was seen in the last scan.)
2750  *
2751  * Returns: %TRUE, if the @connection can be auto-activated.
2752  **/
2753 gboolean
2754 nm_device_can_auto_connect (NMDevice *self,
2755                             NMConnection *connection,
2756                             char **specific_object)
2757 {
2758         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
2759         g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
2760         g_return_val_if_fail (specific_object && !*specific_object, FALSE);
2761
2762         if (nm_device_autoconnect_allowed (self))
2763                 return NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object);
2764         return FALSE;
2765 }
2766
2767 static gboolean
2768 device_has_config (NMDevice *self)
2769 {
2770         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2771
2772         /* Check for IP configuration. */
2773         if (priv->ip4_config && nm_ip4_config_get_num_addresses (priv->ip4_config))
2774                 return TRUE;
2775         if (priv->ip6_config && nm_ip6_config_get_num_addresses (priv->ip6_config))
2776                 return TRUE;
2777
2778         /* The existence of a software device is good enough. */
2779         if (nm_device_is_software (self) && nm_device_is_real (self))
2780                 return TRUE;
2781
2782         /* Slaves are also configured by definition */
2783         if (nm_platform_link_get_master (NM_PLATFORM_GET, priv->ifindex) > 0)
2784                 return TRUE;
2785
2786         return FALSE;
2787 }
2788
2789 /**
2790  * nm_device_master_update_slave_connection:
2791  * @self: the master #NMDevice
2792  * @slave: the slave #NMDevice
2793  * @connection: the #NMConnection to update with the slave settings
2794  * @GError: (out): error description
2795  *
2796  * Reads the slave configuration for @slave and updates @connection with those
2797  * properties. This invokes a virtual function on the master device @self.
2798  *
2799  * Returns: %TRUE if the configuration was read and @connection updated,
2800  * %FALSE on failure.
2801  */
2802 gboolean
2803 nm_device_master_update_slave_connection (NMDevice *self,
2804                                           NMDevice *slave,
2805                                           NMConnection *connection,
2806                                           GError **error)
2807 {
2808         NMDeviceClass *klass;
2809         gboolean success;
2810
2811         g_return_val_if_fail (self, FALSE);
2812         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
2813         g_return_val_if_fail (slave, FALSE);
2814         g_return_val_if_fail (connection, FALSE);
2815         g_return_val_if_fail (!error || !*error, FALSE);
2816         g_return_val_if_fail (nm_connection_get_setting_connection (connection), FALSE);
2817
2818         g_return_val_if_fail (nm_device_get_iface (self), FALSE);
2819
2820         klass = NM_DEVICE_GET_CLASS (self);
2821         if (klass->master_update_slave_connection) {
2822                 success = klass->master_update_slave_connection (self, slave, connection, error);
2823
2824                 g_return_val_if_fail (!error || (success && !*error) || *error, success);
2825                 return success;
2826         }
2827
2828         g_set_error (error,
2829                      NM_DEVICE_ERROR,
2830                      NM_DEVICE_ERROR_FAILED,
2831                      "master device '%s' cannot update a slave connection for slave device '%s' (master type not supported?)",
2832                      nm_device_get_iface (self), nm_device_get_iface (slave));
2833         return FALSE;
2834 }
2835
2836 NMConnection *
2837 nm_device_generate_connection (NMDevice *self, NMDevice *master)
2838 {
2839         NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
2840         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2841         const char *ifname = nm_device_get_iface (self);
2842         NMConnection *connection;
2843         NMSetting *s_con;
2844         NMSetting *s_ip4;
2845         NMSetting *s_ip6;
2846         gs_free char *uuid = NULL;
2847         const char *ip4_method, *ip6_method;
2848         GError *error = NULL;
2849
2850         /* If update_connection() is not implemented, just fail. */
2851         if (!klass->update_connection)
2852                 return NULL;
2853
2854         /* Return NULL if device is unconfigured. */
2855         if (!device_has_config (self)) {
2856                 _LOGD (LOGD_DEVICE, "device has no existing configuration");
2857                 return NULL;
2858         }
2859
2860         connection = nm_simple_connection_new ();
2861         s_con = nm_setting_connection_new ();
2862         uuid = nm_utils_uuid_generate ();
2863
2864         g_object_set (s_con,
2865                       NM_SETTING_CONNECTION_UUID, uuid,
2866                       NM_SETTING_CONNECTION_ID, ifname,
2867                       NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
2868                       NM_SETTING_CONNECTION_INTERFACE_NAME, ifname,
2869                       NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL),
2870                       NULL);
2871         if (klass->connection_type)
2872                 g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, klass->connection_type, NULL);
2873         nm_connection_add_setting (connection, s_con);
2874
2875         /* If the device is a slave, update various slave settings */
2876         if (master) {
2877                 if (!nm_device_master_update_slave_connection (master,
2878                                                                self,
2879                                                                connection,
2880                                                                &error))
2881                 {
2882                         _LOGE (LOGD_DEVICE, "master device '%s' failed to update slave connection: %s",
2883                                nm_device_get_iface (master), error->message);
2884                         g_error_free (error);
2885                         g_object_unref (connection);
2886                         return NULL;
2887                 }
2888         } else {
2889                 /* Only regular and master devices get IP configuration; slaves do not */
2890                 s_ip4 = nm_ip4_config_create_setting (priv->ip4_config);
2891                 nm_connection_add_setting (connection, s_ip4);
2892
2893                 s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
2894                 nm_connection_add_setting (connection, s_ip6);
2895         }
2896
2897         klass->update_connection (self, connection);
2898
2899         /* Check the connection in case of update_connection() bug. */
2900         if (!nm_connection_verify (connection, &error)) {
2901                 _LOGE (LOGD_DEVICE, "Generated connection does not verify: %s", error->message);
2902                 g_clear_error (&error);
2903                 g_object_unref (connection);
2904                 return NULL;
2905         }
2906
2907         /* Ignore the connection if it has no IP configuration,
2908          * no slave configuration, and is not a master interface.
2909          */
2910         ip4_method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
2911         ip6_method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
2912         if (   g_strcmp0 (ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0
2913             && g_strcmp0 (ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0
2914             && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con))
2915             && !priv->slaves) {
2916                 _LOGD (LOGD_DEVICE, "ignoring generated connection (no IP and not in master-slave relationship)");
2917                 g_object_unref (connection);
2918                 connection = NULL;
2919         }
2920
2921         /* Ignore any IPv6LL-only, not master connections without slaves,
2922          * unless they are in the assume-ipv6ll-only list.
2923          */
2924         if (   connection
2925             && g_strcmp0 (ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0
2926             && g_strcmp0 (ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0
2927             && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con))
2928             && !priv->slaves
2929             && !nm_config_data_get_assume_ipv6ll_only (NM_CONFIG_GET_DATA, self)) {
2930                 _LOGD (LOGD_DEVICE, "ignoring generated connection (IPv6LL-only and not in master-slave relationship)");
2931                 g_object_unref (connection);
2932                 connection = NULL;
2933         }
2934
2935         return connection;
2936 }
2937
2938 gboolean
2939 nm_device_complete_connection (NMDevice *self,
2940                                NMConnection *connection,
2941                                const char *specific_object,
2942                                const GSList *existing_connections,
2943                                GError **error)
2944 {
2945         gboolean success = FALSE;
2946
2947         g_return_val_if_fail (self != NULL, FALSE);
2948         g_return_val_if_fail (connection != NULL, FALSE);
2949
2950         if (!NM_DEVICE_GET_CLASS (self)->complete_connection) {
2951                 g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION,
2952                              "Device class %s had no complete_connection method",
2953                              G_OBJECT_TYPE_NAME (self));
2954                 return FALSE;
2955         }
2956
2957         success = NM_DEVICE_GET_CLASS (self)->complete_connection (self,
2958                                                                    connection,
2959                                                                    specific_object,
2960                                                                    existing_connections,
2961                                                                    error);
2962         if (success)
2963                 success = nm_connection_verify (connection, error);
2964
2965         return success;
2966 }
2967
2968 static gboolean
2969 check_connection_compatible (NMDevice *self, NMConnection *connection)
2970 {
2971         const char *device_iface = nm_device_get_iface (self);
2972         gs_free char *conn_iface = nm_manager_get_connection_iface (nm_manager_get (),
2973                                                                     connection,
2974                                                                     NULL, NULL);
2975
2976         /* We always need a interface name for virtual devices, but for
2977          * physical ones a connection without interface name is fine for
2978          * any device. */
2979         if (!conn_iface)
2980                 return !nm_connection_is_virtual (connection);
2981
2982         if (strcmp (conn_iface, device_iface) != 0)
2983                 return FALSE;
2984
2985         return TRUE;
2986 }
2987
2988 /**
2989  * nm_device_check_connection_compatible:
2990  * @self: an #NMDevice
2991  * @connection: an #NMConnection
2992  *
2993  * Checks if @connection could potentially be activated on @self.
2994  * This means only that @self has the proper capabilities, and that
2995  * @connection is not locked to some other device. It does not
2996  * necessarily mean that @connection could be activated on @self
2997  * right now. (Eg, it might refer to a Wi-Fi network that is not
2998  * currently available.)
2999  *
3000  * Returns: #TRUE if @connection could potentially be activated on
3001  *   @self.
3002  */
3003 gboolean
3004 nm_device_check_connection_compatible (NMDevice *self, NMConnection *connection)
3005 {
3006         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
3007         g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
3008
3009         return NM_DEVICE_GET_CLASS (self)->check_connection_compatible (self, connection);
3010 }
3011
3012 gboolean
3013 nm_device_check_slave_connection_compatible (NMDevice *self, NMConnection *slave)
3014 {
3015         NMDevicePrivate *priv;
3016         NMSettingConnection *s_con;
3017         const char *connection_type, *slave_type;
3018
3019         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
3020         g_return_val_if_fail (NM_IS_CONNECTION (slave), FALSE);
3021
3022         priv = NM_DEVICE_GET_PRIVATE (self);
3023
3024         if (!priv->is_master)
3025                 return FALSE;
3026
3027         /* All masters should have connection type set */
3028         connection_type = NM_DEVICE_GET_CLASS (self)->connection_type;
3029         g_return_val_if_fail (connection_type, FALSE);
3030
3031         s_con = nm_connection_get_setting_connection (slave);
3032         g_assert (s_con);
3033         slave_type = nm_setting_connection_get_slave_type (s_con);
3034         if (!slave_type)
3035                 return FALSE;
3036
3037         return strcmp (connection_type, slave_type) == 0;
3038 }
3039
3040 /**
3041  * nm_device_can_assume_connections:
3042  * @self: #NMDevice instance
3043  *
3044  * This is a convenience function to determine whether connection assumption
3045  * is available for this device.
3046  *
3047  * Returns: %TRUE if the device is capable of assuming connections, %FALSE if not
3048  */
3049 static gboolean
3050 nm_device_can_assume_connections (NMDevice *self)
3051 {
3052         return   !!NM_DEVICE_GET_CLASS (self)->update_connection
3053               && !NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
3054 }
3055
3056 /**
3057  * nm_device_can_assume_active_connection:
3058  * @self: #NMDevice instance
3059  *
3060  * This is a convenience function to determine whether the device's active
3061  * connection can be assumed if NetworkManager restarts.  This method returns
3062  * %TRUE if and only if the device can assume connections, and the device has
3063  * an active connection, and that active connection can be assumed.
3064  *
3065  * Returns: %TRUE if the device's active connection can be assumed, or %FALSE
3066  * if there is no active connection or the active connection cannot be
3067  * assumed.
3068  */
3069 gboolean
3070 nm_device_can_assume_active_connection (NMDevice *self)
3071 {
3072         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3073         NMConnection *connection;
3074         const char *method;
3075         const char *assumable_ip6_methods[] = {
3076                 NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
3077                 NM_SETTING_IP6_CONFIG_METHOD_AUTO,
3078                 NM_SETTING_IP6_CONFIG_METHOD_DHCP,
3079                 NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
3080                 NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
3081                 NULL
3082         };
3083         const char *assumable_ip4_methods[] = {
3084                 NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
3085                 NM_SETTING_IP6_CONFIG_METHOD_AUTO,
3086                 NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
3087                 NULL
3088         };
3089
3090         if (!nm_device_can_assume_connections (self))
3091                 return FALSE;
3092
3093         connection = nm_device_get_applied_connection (self);
3094         if (!connection)
3095                 return FALSE;
3096
3097         /* Can't assume connections that aren't yet configured
3098          * FIXME: what about bridges/bonds waiting for slaves?
3099          */
3100         if (priv->state < NM_DEVICE_STATE_IP_CONFIG)
3101                 return FALSE;
3102         if (priv->ip4_state != IP_DONE && priv->ip6_state != IP_DONE)
3103                 return FALSE;
3104
3105         method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
3106         if (!_nm_utils_string_in_list (method, assumable_ip6_methods))
3107                 return FALSE;
3108
3109         method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
3110         if (!_nm_utils_string_in_list (method, assumable_ip4_methods))
3111                 return FALSE;
3112
3113         return TRUE;
3114 }
3115
3116 static gboolean
3117 nm_device_emit_recheck_assume (gpointer user_data)
3118 {
3119         NMDevice *self = user_data;
3120         NMDevicePrivate *priv;
3121
3122         g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE);
3123
3124         priv = NM_DEVICE_GET_PRIVATE (self);
3125
3126         priv->recheck_assume_id = 0;
3127         if (!nm_device_get_act_request (self)) {
3128                 _LOGD (LOGD_DEVICE, "emit RECHECK_ASSUME signal");
3129                 g_signal_emit (self, signals[RECHECK_ASSUME], 0);
3130         }
3131         return G_SOURCE_REMOVE;
3132 }
3133
3134 void
3135 nm_device_queue_recheck_assume (NMDevice *self)
3136 {
3137         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3138
3139         if (   !priv->recheck_assume_id
3140             && nm_device_can_assume_connections (self))
3141                 priv->recheck_assume_id = g_idle_add (nm_device_emit_recheck_assume, self);
3142 }
3143
3144 static gboolean
3145 recheck_available (gpointer user_data)
3146 {
3147         NMDevice *self = NM_DEVICE (user_data);
3148         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3149         gboolean now_available = nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
3150         NMDeviceState state = nm_device_get_state (self);
3151         NMDeviceState new_state = NM_DEVICE_STATE_UNKNOWN;
3152
3153         priv->recheck_available.call_id = 0;
3154
3155         if (state == NM_DEVICE_STATE_UNAVAILABLE && now_available) {
3156                 new_state = NM_DEVICE_STATE_DISCONNECTED;
3157                 nm_device_queue_state (self, new_state, priv->recheck_available.available_reason);
3158         } else if (state >= NM_DEVICE_STATE_DISCONNECTED && !now_available) {
3159                 new_state = NM_DEVICE_STATE_UNAVAILABLE;
3160                 nm_device_queue_state (self, new_state, priv->recheck_available.unavailable_reason);
3161         }
3162
3163         if (new_state > NM_DEVICE_STATE_UNKNOWN) {
3164                 _LOGD (LOGD_DEVICE, "is %savailable, %s %s",
3165                            now_available ? "" : "not ",
3166                            new_state == NM_DEVICE_STATE_UNAVAILABLE ? "no change required for" : "will transition to",
3167                            state_to_string (new_state == NM_DEVICE_STATE_UNAVAILABLE ? state : new_state));
3168
3169                 priv->recheck_available.available_reason = NM_DEVICE_STATE_REASON_NONE;
3170                 priv->recheck_available.unavailable_reason = NM_DEVICE_STATE_REASON_NONE;
3171         }
3172
3173         return G_SOURCE_REMOVE;
3174 }
3175
3176 void
3177 nm_device_queue_recheck_available (NMDevice *self,
3178                                    NMDeviceStateReason available_reason,
3179                                    NMDeviceStateReason unavailable_reason)
3180 {
3181         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3182
3183         priv->recheck_available.available_reason = available_reason;
3184         priv->recheck_available.unavailable_reason = unavailable_reason;
3185         if (!priv->recheck_available.call_id)
3186                 priv->recheck_available.call_id = g_idle_add (recheck_available, self);
3187 }
3188
3189 void
3190 nm_device_emit_recheck_auto_activate (NMDevice *self)
3191 {
3192         g_signal_emit (self, signals[RECHECK_AUTO_ACTIVATE], 0);
3193 }
3194
3195 static void
3196 dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer user_data)
3197 {
3198         NMDevice *self = NM_DEVICE (user_data);
3199
3200         switch (status) {
3201         case NM_DNSMASQ_STATUS_DEAD:
3202                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
3203                 break;
3204         default:
3205                 break;
3206         }
3207 }
3208
3209 /*****************************************************************************/
3210
3211 static gboolean
3212 activation_source_handle_cb4 (gpointer user_data)
3213 {
3214         activation_source_handle_cb (user_data, AF_INET);
3215         return G_SOURCE_REMOVE;
3216 }
3217
3218 static gboolean
3219 activation_source_handle_cb6 (gpointer user_data)
3220 {
3221         activation_source_handle_cb (user_data, AF_INET6);
3222         return G_SOURCE_REMOVE;
3223 }
3224
3225 static ActivationHandleData *
3226 activation_source_get_by_family (NMDevice *self,
3227                                  int family,
3228                                  GSourceFunc *out_idle_func)
3229 {
3230         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3231
3232         if (family == AF_INET6) {
3233                 NM_SET_OUT (out_idle_func, activation_source_handle_cb6);
3234                 return &priv->act_handle6;
3235         } else {
3236                 NM_SET_OUT (out_idle_func, activation_source_handle_cb4);
3237                 g_return_val_if_fail (family == AF_INET, &priv->act_handle4);
3238                 return &priv->act_handle4;
3239         }
3240 }
3241
3242 static void
3243 activation_source_clear (NMDevice *self, int family)
3244 {
3245         ActivationHandleData *act_data;
3246
3247         act_data = activation_source_get_by_family (self, family, NULL);
3248
3249         if (act_data->id) {
3250                 _LOGD (LOGD_DEVICE, "activation-stage: clear %s,%d (id %u)",
3251                        _activation_func_to_string (act_data->func), family, act_data->id);
3252                 nm_clear_g_source (&act_data->id);
3253                 act_data->func = NULL;
3254         }
3255 }
3256
3257 static void
3258 activation_source_handle_cb (NMDevice *self, int family)
3259 {
3260         ActivationHandleData *act_data, a;
3261
3262         g_return_if_fail (NM_IS_DEVICE (self));
3263
3264         act_data = activation_source_get_by_family (self, family, NULL);
3265
3266         g_return_if_fail (act_data->id);
3267         g_return_if_fail (act_data->func);
3268
3269         a = *act_data;
3270
3271         act_data->func = NULL;
3272         act_data->id = 0;
3273
3274         _LOGD (LOGD_DEVICE, "activation-stage: invoke %s,%d (id %u)",
3275                _activation_func_to_string (a.func), family, a.id);
3276
3277         a.func (self);
3278
3279         _LOGD (LOGD_DEVICE, "activation-stage: complete %s,%d (id %u)",
3280                _activation_func_to_string (a.func), family, a.id);
3281 }
3282
3283 static void
3284 activation_source_schedule (NMDevice *self, ActivationHandleFunc func, int family)
3285 {
3286         ActivationHandleData *act_data;
3287         GSourceFunc source_func;
3288         guint new_id = 0;
3289
3290         act_data = activation_source_get_by_family (self, family, &source_func);
3291
3292         if (act_data->id && act_data->func != func) {
3293                 /* Don't bother rescheduling the same function that's about to
3294                  * run anyway.  Fixes issues with crappy wireless drivers sending
3295                  * streams of associate events before NM has had a chance to process
3296                  * the first one.
3297                  */
3298                 _LOGD (LOGD_DEVICE, "activation-stage: already scheduled %s,%d (id %u)",
3299                        _activation_func_to_string (func), family, act_data->id);
3300                 return;
3301         }
3302
3303         new_id = g_idle_add (source_func, self);
3304
3305         if (act_data->id) {
3306                 _LOGW (LOGD_DEVICE, "activation-stage: schedule %s,%d which replaces %s,%d (id %u -> %u)",
3307                        _activation_func_to_string (func), family,
3308                        _activation_func_to_string (act_data->func), family,
3309                        act_data->id, new_id);
3310                 nm_clear_g_source (&act_data->id);
3311         } else {
3312                 _LOGD (LOGD_DEVICE, "activation-stage: schedule %s,%d (id %u)",
3313                        _activation_func_to_string (func), family, new_id);
3314         }
3315
3316         act_data->func = func;
3317         act_data->id = new_id;
3318 }
3319
3320 /*****************************************************************************/
3321
3322 static gboolean
3323 get_ip_config_may_fail (NMDevice *self, int family)
3324 {
3325         NMConnection *connection;
3326         NMSettingIPConfig *s_ip = NULL;
3327
3328         g_return_val_if_fail (self != NULL, TRUE);
3329
3330         connection = nm_device_get_applied_connection (self);
3331         g_assert (connection);
3332
3333         /* Fail the connection if the failed IP method is required to complete */
3334         switch (family) {
3335         case AF_INET:
3336                 s_ip = nm_connection_get_setting_ip4_config (connection);
3337                 break;
3338         case AF_INET6:
3339                 s_ip = nm_connection_get_setting_ip6_config (connection);
3340                 break;
3341         default:
3342                 g_assert_not_reached ();
3343         }
3344
3345         return nm_setting_ip_config_get_may_fail (s_ip);
3346 }
3347
3348 static void
3349 master_ready (NMDevice *self,
3350               NMActiveConnection *active)
3351 {
3352         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3353         NMActiveConnection *master_connection;
3354         NMDevice *master;
3355
3356         g_return_if_fail (priv->state == NM_DEVICE_STATE_PREPARE);
3357         g_return_if_fail (!priv->master_ready_handled);
3358
3359         /* Notify a master device that it has a new slave */
3360         g_return_if_fail (nm_active_connection_get_master_ready (active));
3361         master_connection = nm_active_connection_get_master (active);
3362
3363         priv->master_ready_handled = TRUE;
3364         nm_clear_g_signal_handler (active, &priv->master_ready_id);
3365
3366         master = nm_active_connection_get_device (master_connection);
3367
3368         _LOGD (LOGD_DEVICE, "master connection ready; master device %s",
3369                nm_device_get_iface (master));
3370
3371         if (priv->master && priv->master != master)
3372                 nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
3373
3374         /* If the master didn't change, add-slave only rechecks whether to assume a connection. */
3375         nm_device_master_add_slave (master,
3376                                     self,
3377                                     nm_active_connection_get_assumed (active) ? FALSE : TRUE);
3378 }
3379
3380 static void
3381 master_ready_cb (NMActiveConnection *active,
3382                  GParamSpec *pspec,
3383                  NMDevice *self)
3384 {
3385         master_ready (self, active);
3386         nm_device_activate_schedule_stage2_device_config (self);
3387 }
3388
3389 static void
3390 lldp_neighbors_changed (NMLldpListener *lldp_listener, GParamSpec *pspec,
3391                         gpointer user_data)
3392 {
3393         NMDevice *self = NM_DEVICE (user_data);
3394
3395         _notify (self, PROP_LLDP_NEIGHBORS);
3396 }
3397
3398 static gboolean
3399 lldp_rx_enabled (NMDevice *self)
3400 {
3401         NMConnection *connection;
3402         NMSettingConnection *s_con;
3403         NMSettingConnectionLldp lldp = NM_SETTING_CONNECTION_LLDP_DEFAULT;
3404
3405         connection = nm_device_get_applied_connection (self);
3406         g_return_val_if_fail (connection, FALSE);
3407
3408         s_con = nm_connection_get_setting_connection (connection);
3409         g_return_val_if_fail (s_con, FALSE);
3410
3411         lldp = nm_setting_connection_get_lldp (s_con);
3412         if (lldp == NM_SETTING_CONNECTION_LLDP_DEFAULT) {
3413                 gs_free char *value = NULL;
3414
3415                 value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
3416                                                                "connection.lldp",
3417                                                                self);
3418                 lldp = _nm_utils_ascii_str_to_int64 (value, 10,
3419                                                      NM_SETTING_CONNECTION_LLDP_DEFAULT,
3420                                                      NM_SETTING_CONNECTION_LLDP_ENABLE_RX,
3421                                                      NM_SETTING_CONNECTION_LLDP_DEFAULT);
3422                 if (lldp == NM_SETTING_CONNECTION_LLDP_DEFAULT)
3423                         lldp = NM_SETTING_CONNECTION_LLDP_DISABLE;
3424         }
3425         return lldp == NM_SETTING_CONNECTION_LLDP_ENABLE_RX;
3426 }
3427
3428 static NMActStageReturn
3429 act_stage1_prepare (NMDevice *self, NMDeviceStateReason *reason)
3430 {
3431         return NM_ACT_STAGE_RETURN_SUCCESS;
3432 }
3433
3434 /*
3435  * activate_stage1_device_prepare
3436  *
3437  * Prepare for device activation
3438  *
3439  */
3440 static void
3441 activate_stage1_device_prepare (NMDevice *self)
3442 {
3443         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3444         NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
3445         NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
3446         NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
3447
3448         priv->ip4_state = priv->ip6_state = IP_NONE;
3449
3450         /* Notify the new ActiveConnection along with the state change */
3451         _notify (self, PROP_ACTIVE_CONNECTION);
3452
3453         nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE);
3454
3455         /* Assumed connections were already set up outside NetworkManager */
3456         if (!nm_active_connection_get_assumed (active)) {
3457                 ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, &reason);
3458                 if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
3459                         return;
3460                 } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
3461                         nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
3462                         return;
3463                 }
3464                 g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
3465         }
3466
3467         nm_device_activate_schedule_stage2_device_config (self);
3468 }
3469
3470
3471 /*
3472  * nm_device_activate_schedule_stage1_device_prepare
3473  *
3474  * Prepare a device for activation
3475  *
3476  */
3477 void
3478 nm_device_activate_schedule_stage1_device_prepare (NMDevice *self)
3479 {
3480         NMDevicePrivate *priv;
3481
3482         g_return_if_fail (NM_IS_DEVICE (self));
3483
3484         priv = NM_DEVICE_GET_PRIVATE (self);
3485         g_return_if_fail (priv->act_request);
3486
3487         activation_source_schedule (self, activate_stage1_device_prepare, AF_INET);
3488 }
3489
3490 static NMActStageReturn
3491 act_stage2_config (NMDevice *self, NMDeviceStateReason *reason)
3492 {
3493         /* Nothing to do */
3494         return NM_ACT_STAGE_RETURN_SUCCESS;
3495 }
3496
3497 /*
3498  * activate_stage2_device_config
3499  *
3500  * Determine device parameters and set those on the device, ie
3501  * for wireless devices, set SSID, keys, etc.
3502  *
3503  */
3504 static void
3505 activate_stage2_device_config (NMDevice *self)
3506 {
3507         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3508         NMActStageReturn ret;
3509         NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
3510         gboolean no_firmware = FALSE;
3511         NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
3512         GSList *iter;
3513
3514         nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE);
3515
3516         /* Assumed connections were already set up outside NetworkManager */
3517         if (!nm_active_connection_get_assumed (active)) {
3518                 if (!nm_device_bring_up (self, FALSE, &no_firmware)) {
3519                         if (no_firmware)
3520                                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_FIRMWARE_MISSING);
3521                         else
3522                                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
3523                         return;
3524                 }
3525
3526                 ret = NM_DEVICE_GET_CLASS (self)->act_stage2_config (self, &reason);
3527                 if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
3528                         return;
3529                 else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
3530                         nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
3531                         return;
3532                 }
3533                 g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
3534         }
3535
3536         /* If we have slaves that aren't yet enslaved, do that now */
3537         for (iter = priv->slaves; iter; iter = g_slist_next (iter)) {
3538                 SlaveInfo *info = iter->data;
3539                 NMDeviceState slave_state = nm_device_get_state (info->slave);
3540
3541                 if (slave_state == NM_DEVICE_STATE_IP_CONFIG)
3542                         nm_device_master_enslave_slave (self, info->slave, nm_device_get_applied_connection (info->slave));
3543                 else if (   nm_device_uses_generated_assumed_connection (self)
3544                          && slave_state <= NM_DEVICE_STATE_DISCONNECTED)
3545                         nm_device_queue_recheck_assume (info->slave);
3546         }
3547
3548         if (lldp_rx_enabled (self)) {
3549                 gs_free_error GError *error = NULL;
3550                 gconstpointer addr;
3551                 size_t addr_length;
3552
3553                 if (priv->lldp_listener)
3554                         nm_lldp_listener_stop (priv->lldp_listener);
3555                 else {
3556                         priv->lldp_listener = nm_lldp_listener_new ();
3557                         g_signal_connect (priv->lldp_listener,
3558                                           "notify::" NM_LLDP_LISTENER_NEIGHBORS,
3559                                           G_CALLBACK (lldp_neighbors_changed),
3560                                           self);
3561                 }
3562
3563                 addr = nm_platform_link_get_address (NM_PLATFORM_GET, priv->ifindex, &addr_length);
3564
3565                 if (nm_lldp_listener_start (priv->lldp_listener, nm_device_get_ifindex (self), &error))
3566                         _LOGD (LOGD_DEVICE, "LLDP listener %p started", priv->lldp_listener);
3567                 else {
3568                         _LOGD (LOGD_DEVICE, "LLDP listener %p could not be started: %s",
3569                                priv->lldp_listener, error->message);
3570                 }
3571         }
3572
3573         nm_device_activate_schedule_stage3_ip_config_start (self);
3574 }
3575
3576
3577 /*
3578  * nm_device_activate_schedule_stage2_device_config
3579  *
3580  * Schedule setup of the hardware device
3581  *
3582  */
3583 void
3584 nm_device_activate_schedule_stage2_device_config (NMDevice *self)
3585 {
3586         NMDevicePrivate *priv;
3587
3588         g_return_if_fail (NM_IS_DEVICE (self));
3589
3590         priv = NM_DEVICE_GET_PRIVATE (self);
3591         g_return_if_fail (priv->act_request);
3592
3593         if (!priv->master_ready_handled) {
3594                 NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
3595
3596                 if (!nm_active_connection_get_master (active)) {
3597                         g_warn_if_fail (!priv->master_ready_id);
3598                         priv->master_ready_handled = TRUE;
3599                 } else {
3600                         /* If the master connection is ready for slaves, attach ourselves */
3601                         if (nm_active_connection_get_master_ready (active))
3602                                 master_ready (self, active);
3603                         else {
3604                                 _LOGD (LOGD_DEVICE, "waiting for master connection to become ready");
3605
3606                                 if (priv->master_ready_id == 0) {
3607                                         priv->master_ready_id = g_signal_connect (active,
3608                                                                                   "notify::" NM_ACTIVE_CONNECTION_INT_MASTER_READY,
3609                                                                                   (GCallback) master_ready_cb,
3610                                                                                   self);
3611                                 }
3612                                 /* Postpone */
3613                                 return;
3614                         }
3615                 }
3616         }
3617
3618         activation_source_schedule (self, activate_stage2_device_config, AF_INET);
3619 }
3620
3621 /*
3622  * check_ip_failed
3623  *
3624  * Progress the device to appropriate state if both IPv4 and IPv6 failed
3625  */
3626 static void
3627 check_ip_failed (NMDevice *self, gboolean may_fail)
3628 {
3629         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3630         NMDeviceState state;
3631
3632         if (   priv->ip4_state != IP_FAIL
3633             || priv->ip6_state != IP_FAIL)
3634                 return;
3635
3636         if (nm_device_uses_assumed_connection (self)) {
3637                 /* We have assumed configuration, but couldn't
3638                  * redo it. No problem, move to check state. */
3639                 priv->ip4_state = priv->ip6_state = IP_DONE;
3640                 state = NM_DEVICE_STATE_IP_CHECK;
3641         } else if (   may_fail
3642                    && get_ip_config_may_fail (self, AF_INET)
3643                    && get_ip_config_may_fail (self, AF_INET6)) {
3644                 /* Couldn't start either IPv6 and IPv4 autoconfiguration,
3645                  * but both are allowed to fail. */
3646                 state = NM_DEVICE_STATE_SECONDARIES;
3647         } else {
3648                 /* Autoconfiguration attempted without success. */
3649                 state = NM_DEVICE_STATE_FAILED;
3650         }
3651
3652         nm_device_state_changed (self,
3653                                  state,
3654                                  NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
3655 }
3656
3657 /*
3658  * check_ip_done
3659  *
3660  * Progress the device to ip connectivity check state if IPv4 or IPv6 succeeded
3661  */
3662 static void
3663 check_ip_done (NMDevice *self)
3664 {
3665         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3666
3667         if (nm_device_get_state (self) != NM_DEVICE_STATE_IP_CONFIG)
3668                 return;
3669
3670         if (priv->ip4_state != IP_DONE && !get_ip_config_may_fail (self, AF_INET))
3671                 return;
3672
3673         if (priv->ip6_state != IP_DONE && !get_ip_config_may_fail (self, AF_INET6))
3674                 return;
3675
3676         nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
3677 }
3678
3679 /*********************************************/
3680 /* IPv4 DAD stuff */
3681
3682 static guint
3683 get_ipv4_dad_timeout (NMDevice *self)
3684 {
3685         NMConnection *connection;
3686         NMSettingIPConfig *s_ip4 = NULL;
3687         gs_free char *value = NULL;
3688         gint ret = 0;
3689
3690         connection = nm_device_get_applied_connection (self);
3691         if (connection)
3692                 s_ip4 = nm_connection_get_setting_ip4_config (connection);
3693
3694         if (s_ip4) {
3695                 ret = nm_setting_ip_config_get_dad_timeout (s_ip4);
3696
3697                 if (ret < 0) {
3698                         value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
3699                                                                        "ipv4.dad-timeout", self);
3700                         ret = _nm_utils_ascii_str_to_int64 (value, 10, -1,
3701                                                             NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX,
3702                                                             -1);
3703                         ret = ret < 0 ? 0 : ret;
3704                 }
3705         }
3706
3707         return ret;
3708 }
3709
3710 static void
3711 arping_data_destroy (gpointer ptr, GClosure *closure)
3712 {
3713         ArpingData *data = ptr;
3714         int i;
3715
3716         if (data) {
3717                 for (i = 0; data->configs && data->configs[i]; i++)
3718                         g_object_unref (data->configs[i]);
3719                 g_free (data->configs);
3720                 g_slice_free (ArpingData, data);
3721         }
3722 }
3723
3724 static void
3725 ipv4_manual_method_apply (NMDevice *self, NMIP4Config **configs, gboolean success)
3726 {
3727         NMIP4Config *empty;
3728
3729         if (success) {
3730                 empty = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
3731                 nm_device_activate_schedule_ip4_config_result (self, empty);
3732                 g_object_unref (empty);
3733         } else {
3734                 nm_device_queue_state (self, NM_DEVICE_STATE_FAILED,
3735                                        NM_DEVICE_STATE_REASON_CONFIG_FAILED);
3736         }
3737 }
3738
3739 static void
3740 arping_manager_probe_terminated (NMArpingManager *arping_manager, ArpingData *data)
3741 {
3742         NMDevice *self;
3743         NMDevicePrivate *priv;
3744         const NMPlatformIP4Address *address;
3745         gboolean result, success = TRUE;
3746         int i, j;
3747
3748         g_assert (data);
3749         self = data->device;
3750         priv = NM_DEVICE_GET_PRIVATE (self);
3751
3752         for (i = 0; data->configs && data->configs[i]; i++) {
3753                 for (j = 0; j < nm_ip4_config_get_num_addresses (data->configs[i]); j++) {
3754                         address = nm_ip4_config_get_address (data->configs[i], j);
3755                         result = nm_arping_manager_check_address (arping_manager, address->address);
3756                         success &= result;
3757
3758                         _NMLOG (result ? LOGL_DEBUG : LOGL_WARN,
3759                                 LOGD_DEVICE,
3760                                 "IPv4 DAD result: address %s is %s",
3761                                 nm_utils_inet4_ntop (address->address, NULL),
3762                                 result ? "unique" : "duplicate");
3763                 }
3764         }
3765
3766         data->callback (self, data->configs, success);
3767
3768         priv->arping.dad_list = g_slist_remove (priv->arping.dad_list, arping_manager);
3769         nm_arping_manager_destroy (arping_manager);
3770 }
3771
3772 /**
3773  * ipv4_dad_start:
3774  * @self: device instance
3775  * @configs: NULL-terminated array of IPv4 configurations
3776  * @cb: callback function
3777  *
3778  * Start IPv4 DAD on device @self, check addresses in @configs and call @cb
3779  * when the procedure ends. @cb will be called in any case, even if DAD can't
3780  * be started. @configs will be unreferenced after @cb has been called.
3781  */
3782 static void
3783 ipv4_dad_start (NMDevice *self, NMIP4Config **configs, ArpingCallback cb)
3784 {
3785         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3786         NMArpingManager *arping_manager;
3787         const NMPlatformIP4Address *address;
3788         ArpingData *data;
3789         guint timeout;
3790         gboolean ret, addr_found;
3791         const guint8 *hw_addr;
3792         size_t hw_addr_len = 0;
3793         GError *error = NULL;
3794         guint i, j;
3795
3796         g_return_if_fail (NM_IS_DEVICE (self));
3797         g_return_if_fail (configs);
3798         g_return_if_fail (cb);
3799
3800         for (i = 0, addr_found = FALSE; configs[i]; i++) {
3801                 if (nm_ip4_config_get_num_addresses (configs[i]) > 0) {
3802                         addr_found = TRUE;
3803                         break;
3804                 }
3805         }
3806
3807         timeout = get_ipv4_dad_timeout (self);
3808         hw_addr = nm_platform_link_get_address (NM_PLATFORM_GET,
3809                                                 nm_device_get_ip_ifindex (self),
3810                                                 &hw_addr_len);
3811
3812         if (   !timeout
3813             || !hw_addr
3814             || !hw_addr_len
3815             || !addr_found
3816             || nm_device_uses_assumed_connection (self)) {
3817
3818                 /* DAD not needed, signal success */
3819                 cb (self, configs, TRUE);
3820
3821                 for (i = 0; configs[i]; i++)
3822                         g_object_unref (configs[i]);
3823                 g_free (configs);
3824
3825                 return;
3826         }
3827
3828         /* don't take additional references of @arping_manager that outlive @self.
3829          * Otherwise, the callback can be invoked on a dangling pointer as we don't
3830          * disconnect the handler. */
3831         arping_manager = nm_arping_manager_new (nm_device_get_ip_ifindex (self));
3832         priv->arping.dad_list = g_slist_append (priv->arping.dad_list, arping_manager);
3833
3834         data = g_slice_new0 (ArpingData);
3835         data->configs = configs;
3836         data->callback = cb;
3837         data->device = self;
3838
3839         for (i = 0; configs[i]; i++) {
3840                 for (j = 0; j < nm_ip4_config_get_num_addresses (configs[i]); j++) {
3841                         address = nm_ip4_config_get_address (configs[i], j);
3842                         nm_arping_manager_add_address (arping_manager, address->address);
3843                 }
3844         }
3845
3846         g_signal_connect_data (arping_manager, NM_ARPING_MANAGER_PROBE_TERMINATED,
3847                                G_CALLBACK (arping_manager_probe_terminated), data,
3848                                arping_data_destroy, 0);
3849
3850         ret = nm_arping_manager_start_probe (arping_manager, timeout, &error);
3851
3852         if (!ret) {
3853                 _LOGW (LOGD_DEVICE, "arping probe failed: %s", error->message);
3854
3855                 /* DAD could not be started, signal success */
3856                 cb (self, configs, TRUE);
3857
3858                 priv->arping.dad_list = g_slist_remove (priv->arping.dad_list, arping_manager);
3859                 nm_arping_manager_destroy (arping_manager);
3860         }
3861 }
3862
3863 /*********************************************/
3864 /* IPv4LL stuff */
3865
3866 static void
3867 ipv4ll_cleanup (NMDevice *self)
3868 {
3869         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3870
3871         if (priv->ipv4ll) {
3872                 sd_ipv4ll_set_callback (priv->ipv4ll, NULL, NULL);
3873                 sd_ipv4ll_stop (priv->ipv4ll);
3874                 priv->ipv4ll = sd_ipv4ll_unref (priv->ipv4ll);
3875         }
3876
3877         nm_clear_g_source (&priv->ipv4ll_timeout);
3878 }
3879
3880 static NMIP4Config *
3881 ipv4ll_get_ip4_config (NMDevice *self, guint32 lla)
3882 {
3883         NMIP4Config *config = NULL;
3884         NMPlatformIP4Address address;
3885         NMPlatformIP4Route route;
3886
3887         config = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
3888         g_assert (config);
3889
3890         memset (&address, 0, sizeof (address));
3891         nm_platform_ip4_address_set_addr (&address, lla, 16);
3892         address.source = NM_IP_CONFIG_SOURCE_IP4LL;
3893         nm_ip4_config_add_address (config, &address);
3894
3895         /* Add a multicast route for link-local connections: destination= 224.0.0.0, netmask=240.0.0.0 */
3896         memset (&route, 0, sizeof (route));
3897         route.network = htonl (0xE0000000L);
3898         route.plen = 4;
3899         route.source = NM_IP_CONFIG_SOURCE_IP4LL;
3900         route.metric = nm_device_get_ip4_route_metric (self);
3901         nm_ip4_config_add_route (config, &route);
3902
3903         return config;
3904 }
3905
3906 #define IPV4LL_NETWORK (htonl (0xA9FE0000L))
3907 #define IPV4LL_NETMASK (htonl (0xFFFF0000L))
3908
3909 static void
3910 nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data)
3911 {
3912         NMDevice *self = data;
3913         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3914         NMConnection *connection = NULL;
3915         const char *method;
3916         struct in_addr address;
3917         NMIP4Config *config;
3918         int r;
3919
3920         if (priv->act_request == NULL)
3921                 return;
3922
3923         connection = nm_act_request_get_applied_connection (priv->act_request);
3924         g_assert (connection);
3925
3926         /* Ignore if the connection isn't an AutoIP connection */
3927         method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
3928         if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) != 0)
3929                 return;
3930
3931         switch (event) {
3932         case SD_IPV4LL_EVENT_BIND:
3933                 r = sd_ipv4ll_get_address (ll, &address);
3934                 if (r < 0) {
3935                         _LOGE (LOGD_AUTOIP4, "invalid IPv4 link-local address received, error %d.", r);
3936                         priv->ip4_state = IP_FAIL;
3937                         check_ip_failed (self, FALSE);
3938                         return;
3939                 }
3940
3941                 if ((address.s_addr & IPV4LL_NETMASK) != IPV4LL_NETWORK) {
3942                         _LOGE (LOGD_AUTOIP4, "invalid address %08x received (not link-local).", address.s_addr);
3943                         priv->ip4_state = IP_FAIL;
3944                         check_ip_failed (self, FALSE);
3945                         return;
3946                 }
3947
3948                 config = ipv4ll_get_ip4_config (self, address.s_addr);
3949                 if (config == NULL) {
3950                         _LOGE (LOGD_AUTOIP4, "failed to get IPv4LL config");
3951                         priv->ip4_state = IP_FAIL;
3952                         check_ip_failed (self, FALSE);
3953                         return;
3954                 }
3955
3956                 if (priv->ip4_state == IP_CONF) {
3957                         nm_clear_g_source (&priv->ipv4ll_timeout);
3958                         nm_device_activate_schedule_ip4_config_result (self, config);
3959                 } else if (priv->ip4_state == IP_DONE) {
3960                         if (!ip4_config_merge_and_apply (self, config, TRUE, NULL)) {
3961                                 _LOGE (LOGD_AUTOIP4, "failed to update IP4 config for autoip change.");
3962                                 priv->ip4_state = IP_FAIL;
3963                                 check_ip_failed (self, FALSE);
3964                         }
3965                 } else
3966                         g_assert_not_reached ();
3967
3968                 g_object_unref (config);
3969                 break;
3970         default:
3971                 _LOGW (LOGD_AUTOIP4, "IPv4LL address no longer valid after event %d.", event);
3972                 priv->ip4_state = IP_FAIL;
3973                 check_ip_failed (self, FALSE);
3974         }
3975 }
3976
3977 static gboolean
3978 ipv4ll_timeout_cb (gpointer user_data)
3979 {
3980         NMDevice *self = NM_DEVICE (user_data);
3981         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3982
3983         if (priv->ipv4ll_timeout) {
3984                 _LOGI (LOGD_AUTOIP4, "IPv4LL configuration timed out.");
3985                 priv->ipv4ll_timeout = 0;
3986                 ipv4ll_cleanup (self);
3987
3988                 if (priv->ip4_state == IP_CONF)
3989                         nm_device_activate_schedule_ip4_config_timeout (self);
3990         }
3991
3992         return FALSE;
3993 }
3994
3995 static NMActStageReturn
3996 ipv4ll_start (NMDevice *self, NMDeviceStateReason *reason)
3997 {
3998         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3999         const struct ether_addr *addr;
4000         int ifindex, r;
4001         size_t addr_len;
4002
4003         ipv4ll_cleanup (self);
4004
4005         r = sd_ipv4ll_new (&priv->ipv4ll);
4006         if (r < 0) {
4007                 _LOGE (LOGD_AUTOIP4, "IPv4LL: new() failed with error %d", r);
4008                 goto fail;
4009         }
4010
4011         r = sd_ipv4ll_attach_event (priv->ipv4ll, NULL, 0);
4012         if (r < 0) {
4013                 _LOGE (LOGD_AUTOIP4, "IPv4LL: attach_event() failed with error %d", r);
4014                 goto fail;
4015         }
4016
4017         ifindex = nm_device_get_ip_ifindex (self);
4018         addr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &addr_len);
4019         if (!addr || addr_len != ETH_ALEN) {
4020                 _LOGE (LOGD_AUTOIP4, "IPv4LL: can't retrieve hardware address");
4021                 goto fail;
4022         }
4023
4024         r = sd_ipv4ll_set_mac (priv->ipv4ll, addr);
4025         if (r < 0) {
4026                 _LOGE (LOGD_AUTOIP4, "IPv4LL: set_mac() failed with error %d", r);
4027                 goto fail;
4028         }
4029
4030         r = sd_ipv4ll_set_index (priv->ipv4ll, ifindex);
4031         if (r < 0) {
4032                 _LOGE (LOGD_AUTOIP4, "IPv4LL: set_index() failed with error %d", r);
4033                 goto fail;
4034         }
4035
4036         r = sd_ipv4ll_set_callback (priv->ipv4ll, nm_device_handle_ipv4ll_event, self);
4037         if (r < 0) {
4038                 _LOGE (LOGD_AUTOIP4, "IPv4LL: set_callback() failed with error %d", r);
4039                 goto fail;
4040         }
4041
4042         r = sd_ipv4ll_start (priv->ipv4ll);
4043         if (r < 0) {
4044                 _LOGE (LOGD_AUTOIP4, "IPv4LL: start() failed with error %d", r);
4045                 goto fail;
4046         }
4047
4048         _LOGI (LOGD_DEVICE | LOGD_AUTOIP4, "IPv4LL: started");
4049
4050         /* Start a timeout to bound the address attempt */
4051         priv->ipv4ll_timeout = g_timeout_add_seconds (20, ipv4ll_timeout_cb, self);
4052
4053         return NM_ACT_STAGE_RETURN_POSTPONE;
4054 fail:
4055         *reason = NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED;
4056         return NM_ACT_STAGE_RETURN_FAILURE;
4057 }
4058
4059 /*********************************************/
4060
4061 static gboolean
4062 _device_get_default_route_from_platform (NMDevice *self, int addr_family, NMPlatformIPRoute *out_route)
4063 {
4064         gboolean success = FALSE;
4065         int ifindex = nm_device_get_ip_ifindex (self);
4066         GArray *routes;
4067
4068         if (addr_family == AF_INET)
4069                 routes = nm_platform_ip4_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT);
4070         else
4071                 routes = nm_platform_ip6_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT);
4072
4073         if (routes) {
4074                 guint route_metric = G_MAXUINT32, m;
4075                 const NMPlatformIPRoute *route = NULL, *r;
4076                 guint i;
4077
4078                 /* if there are several default routes, find the one with the best metric */
4079                 for (i = 0; i < routes->len; i++) {
4080                         if (addr_family == AF_INET) {
4081                                 r = (const NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP4Route, i);
4082                                 m = r->metric;
4083                         } else {
4084                                 r = (const NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP6Route, i);
4085                                 m = nm_utils_ip6_route_metric_normalize (r->metric);
4086                         }
4087                         if (!route || m < route_metric) {
4088                                 route = r;
4089                                 route_metric = m;
4090                         }
4091                 }
4092
4093                 if (route) {
4094                         if (addr_family == AF_INET)
4095                                 *((NMPlatformIP4Route *) out_route) = *((NMPlatformIP4Route *) route);
4096                         else
4097                                 *((NMPlatformIP6Route *) out_route) = *((NMPlatformIP6Route *) route);
4098                         success = TRUE;
4099                 }
4100                 g_array_free (routes, TRUE);
4101         }
4102         return success;
4103 }
4104
4105 /*********************************************/
4106
4107 static void
4108 ensure_con_ip4_config (NMDevice *self)
4109 {
4110         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4111         int ip_ifindex = nm_device_get_ip_ifindex (self);
4112         NMConnection *connection;
4113
4114         if (priv->con_ip4_config)
4115                 return;
4116
4117         connection = nm_device_get_applied_connection (self);
4118         if (!connection)
4119                 return;
4120
4121         priv->con_ip4_config = nm_ip4_config_new (ip_ifindex);
4122         nm_ip4_config_merge_setting (priv->con_ip4_config,
4123                                      nm_connection_get_setting_ip4_config (connection),
4124                                      nm_device_get_ip4_route_metric (self));
4125
4126         if (nm_device_uses_assumed_connection (self)) {
4127                 /* For assumed connections ignore all addresses and routes. */
4128                 nm_ip4_config_reset_addresses (priv->con_ip4_config);
4129                 nm_ip4_config_reset_routes (priv->con_ip4_config);
4130         }
4131 }
4132
4133 static void
4134 ensure_con_ip6_config (NMDevice *self)
4135 {
4136         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4137         int ip_ifindex = nm_device_get_ip_ifindex (self);
4138         NMConnection *connection;
4139
4140         if (priv->con_ip6_config)
4141                 return;
4142
4143         connection = nm_device_get_applied_connection (self);
4144         if (!connection)
4145                 return;
4146
4147         priv->con_ip6_config = nm_ip6_config_new (ip_ifindex);
4148         nm_ip6_config_merge_setting (priv->con_ip6_config,
4149                                      nm_connection_get_setting_ip6_config (connection),
4150                                      nm_device_get_ip6_route_metric (self));
4151
4152         if (nm_device_uses_assumed_connection (self)) {
4153                 /* For assumed connections ignore all addresses and routes. */
4154                 nm_ip6_config_reset_addresses (priv->con_ip6_config);
4155                 nm_ip6_config_reset_routes (priv->con_ip6_config);
4156         }
4157 }
4158
4159 /*********************************************/
4160 /* DHCPv4 stuff */
4161
4162 static void
4163 dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release)
4164 {
4165         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4166
4167         nm_clear_g_source (&priv->dhcp4_restart_id);
4168
4169         if (priv->dhcp4_client) {
4170                 /* Stop any ongoing DHCP transaction on this device */
4171                 nm_clear_g_signal_handler (priv->dhcp4_client, &priv->dhcp4_state_sigid);
4172
4173                 nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
4174
4175                 if (   cleanup_type == CLEANUP_TYPE_DECONFIGURE
4176                     || cleanup_type == CLEANUP_TYPE_REMOVED)
4177                         nm_dhcp_client_stop (priv->dhcp4_client, release);
4178
4179                 g_clear_object (&priv->dhcp4_client);
4180         }
4181
4182         if (priv->dhcp4_config) {
4183                 nm_exported_object_clear_and_unexport (&priv->dhcp4_config);
4184                 _notify (self, PROP_DHCP4_CONFIG);
4185         }
4186 }
4187
4188 static void
4189 _ip4_config_merge_default (gpointer value, gpointer user_data)
4190 {
4191         NMIP4Config *src = (NMIP4Config *) value;
4192         NMIP4Config *dst = (NMIP4Config *) user_data;
4193
4194         nm_ip4_config_merge (dst, src, NM_IP_CONFIG_MERGE_DEFAULT);
4195 }
4196
4197 static gboolean
4198 ip4_config_merge_and_apply (NMDevice *self,
4199                             NMIP4Config *config,
4200                             gboolean commit,
4201                             NMDeviceStateReason *out_reason)
4202 {
4203         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4204         NMConnection *connection;
4205         gboolean success;
4206         NMIP4Config *composite;
4207         gboolean has_direct_route;
4208         const guint32 default_route_metric = nm_device_get_ip4_route_metric (self);
4209         guint32 gateway;
4210         gboolean connection_has_default_route, connection_is_never_default;
4211         gboolean routes_full_sync;
4212         gboolean ignore_auto_routes = FALSE;
4213         gboolean ignore_auto_dns = FALSE;
4214
4215         /* Merge all the configs into the composite config */
4216         if (config) {
4217                 g_clear_object (&priv->dev_ip4_config);
4218                 priv->dev_ip4_config = g_object_ref (config);
4219         }
4220
4221         /* Apply ignore-auto-routes and ignore-auto-dns settings */
4222         connection = nm_device_get_applied_connection (self);
4223         if (connection) {
4224                 NMSettingIPConfig *s_ip4 = nm_connection_get_setting_ip4_config (connection);
4225
4226                 if (s_ip4) {
4227                         ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip4);
4228                         ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip4);
4229                 }
4230         }
4231
4232         composite = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
4233
4234         if (commit)
4235                 ensure_con_ip4_config (self);
4236
4237         if (priv->dev_ip4_config) {
4238                 nm_ip4_config_merge (composite, priv->dev_ip4_config,
4239                                        (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
4240                                      | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
4241         }
4242
4243         g_slist_foreach (priv->vpn4_configs, _ip4_config_merge_default, composite);
4244
4245         if (priv->ext_ip4_config)
4246                 nm_ip4_config_merge (composite, priv->ext_ip4_config, NM_IP_CONFIG_MERGE_DEFAULT);
4247
4248         /* Merge WWAN config *last* to ensure modem-given settings overwrite
4249          * any external stuff set by pppd or other scripts.
4250          */
4251         if (priv->wwan_ip4_config) {
4252                 nm_ip4_config_merge (composite, priv->wwan_ip4_config,
4253                                        (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
4254                                      | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
4255         }
4256
4257         /* Merge user overrides into the composite config. For assumed connections,
4258          * con_ip4_config is empty. */
4259         if (priv->con_ip4_config)
4260                 nm_ip4_config_merge (composite, priv->con_ip4_config, NM_IP_CONFIG_MERGE_DEFAULT);
4261
4262         /* Add the default route.
4263          *
4264          * We keep track of the default route of a device in a private field.
4265          * NMDevice needs to know the default route at this point, because the gateway
4266          * might require a direct route (see below).
4267          *
4268          * But also, we don't want to add the default route to priv->ip4_config,
4269          * because the default route from the setting might not be the same that
4270          * NMDefaultRouteManager eventually configures (because the it might
4271          * tweak the effective metric).
4272          */
4273
4274         /* unless we come to a different conclusion below, we have no default route and
4275          * the route is assumed. */
4276         priv->default_route.v4_has = FALSE;
4277         priv->default_route.v4_is_assumed = TRUE;
4278
4279         if (!commit) {
4280                 /* during a non-commit event, we always pickup whatever is configured. */
4281                 goto END_ADD_DEFAULT_ROUTE;
4282         }
4283
4284         if (nm_device_uses_generated_assumed_connection (self)) {
4285                 /* a generate-assumed-connection always detects the default route from platform */
4286                 goto END_ADD_DEFAULT_ROUTE;
4287         }
4288
4289         /* At this point, we treat assumed and non-assumed connections alike.
4290          * For assumed connections we do that because we still manage RA and DHCP
4291          * leases for them, so we must extend/update the default route on commits.
4292          */
4293
4294         connection_has_default_route
4295             = nm_default_route_manager_ip4_connection_has_default_route (nm_default_route_manager_get (),
4296                                                                          connection, &connection_is_never_default);
4297
4298         if (   !priv->v4_commit_first_time
4299             && connection_is_never_default) {
4300                 /* If the connection is explicitly configured as never-default, we enforce the (absence of the)
4301                  * default-route only once. That allows the user to configure a connection as never-default,
4302                  * but he can add default routes externally (via a dispatcher script) and NM will not interfere. */
4303                 goto END_ADD_DEFAULT_ROUTE;
4304         }
4305
4306         /* we are about to commit (for a non-assumed connection). Enforce whatever we have
4307          * configured. */
4308         priv->default_route.v4_is_assumed = FALSE;
4309
4310         if (!connection_has_default_route)
4311                 goto END_ADD_DEFAULT_ROUTE;
4312
4313         if (!nm_ip4_config_get_num_addresses (composite)) {
4314                 /* without addresses we can have no default route. */
4315                 goto END_ADD_DEFAULT_ROUTE;
4316         }
4317
4318         gateway = nm_ip4_config_get_gateway (composite);
4319         if (   !nm_ip4_config_has_gateway (composite)
4320             && nm_device_get_device_type (self) != NM_DEVICE_TYPE_MODEM)
4321                 goto END_ADD_DEFAULT_ROUTE;
4322
4323         has_direct_route = (   gateway == 0
4324                             || nm_ip4_config_destination_is_direct (composite, gateway, 32)
4325                             || nm_ip4_config_get_direct_route_for_host (composite, gateway));
4326
4327         priv->default_route.v4_has = TRUE;
4328         memset (&priv->default_route.v4, 0, sizeof (priv->default_route.v4));
4329         priv->default_route.v4.source = NM_IP_CONFIG_SOURCE_USER;
4330         priv->default_route.v4.gateway = gateway;
4331         priv->default_route.v4.metric = default_route_metric;
4332         priv->default_route.v4.mss = nm_ip4_config_get_mss (composite);
4333
4334         if (!has_direct_route) {
4335                 NMPlatformIP4Route r = priv->default_route.v4;
4336
4337                 /* add a direct route to the gateway */
4338                 r.network = gateway;
4339                 r.plen = 32;
4340                 r.gateway = 0;
4341                 nm_ip4_config_add_route (composite, &r);
4342         }
4343
4344 END_ADD_DEFAULT_ROUTE:
4345
4346         if (priv->default_route.v4_is_assumed) {
4347                 /* If above does not explicitly assign a default route, we always pick up the
4348                  * default route based on what is currently configured.
4349                  * That means that even managed connections with never-default, can
4350                  * get a default route (if configured externally).
4351                  */
4352                 priv->default_route.v4_has = _device_get_default_route_from_platform (self, AF_INET, (NMPlatformIPRoute *) &priv->default_route.v4);
4353         }
4354
4355         nm_ip4_config_addresses_sort (composite);
4356
4357         /* Allow setting MTU etc */
4358         if (commit) {
4359                 if (NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit)
4360                         NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, composite);
4361         }
4362
4363         routes_full_sync =    commit
4364                            && priv->v4_commit_first_time
4365                            && !nm_device_uses_assumed_connection (self);
4366
4367         success = nm_device_set_ip4_config (self, composite, default_route_metric, commit, routes_full_sync, out_reason);
4368         g_object_unref (composite);
4369
4370         if (commit)
4371                 priv->v4_commit_first_time = FALSE;
4372         return success;
4373 }
4374
4375 static void
4376 dhcp4_lease_change (NMDevice *self, NMIP4Config *config)
4377 {
4378         NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
4379
4380         g_return_if_fail (config != NULL);
4381
4382         if (!ip4_config_merge_and_apply (self, config, TRUE, &reason)) {
4383                 _LOGW (LOGD_DHCP4, "failed to update IPv4 config for DHCP change.");
4384                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
4385         } else {
4386                 /* Notify dispatcher scripts of new DHCP4 config */
4387                 nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE,
4388                                     nm_device_get_settings_connection (self),
4389                                     nm_device_get_applied_connection (self),
4390                                     self,
4391                                     NULL,
4392                                     NULL,
4393                                     NULL);
4394         }
4395 }
4396
4397 static gboolean
4398 dhcp4_restart_cb (gpointer user_data)
4399 {
4400         NMDevice *self = user_data;
4401         NMDevicePrivate *priv;
4402         NMDeviceStateReason reason;
4403         NMConnection *connection;
4404
4405         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
4406
4407         priv = NM_DEVICE_GET_PRIVATE (self);
4408         priv->dhcp4_restart_id = 0;
4409         connection = nm_device_get_applied_connection (self);
4410
4411         if (dhcp4_start (self, connection, &reason) == NM_ACT_STAGE_RETURN_FAILURE)
4412                 priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self);
4413
4414         return FALSE;
4415 }
4416
4417 static void
4418 dhcp4_fail (NMDevice *self, gboolean timeout)
4419 {
4420         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4421
4422         dhcp4_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE);
4423
4424         /* Don't fail if there are static addresses configured on
4425          * the device, instead retry after some time.
4426          */
4427         if (   priv->ip4_state == IP_DONE
4428             && priv->con_ip4_config
4429             && nm_ip4_config_get_num_addresses (priv->con_ip4_config) > 0) {
4430                 _LOGI (LOGD_DHCP4, "Scheduling DHCPv4 restart because device has IP addresses");
4431                 priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self);
4432                 return;
4433         }
4434
4435         /* Instead of letting an assumed connection fail (which means that the
4436          * device will transition to the ACTIVATED state without IP configuration),
4437          * retry DHCP again.
4438          */
4439         if (nm_device_uses_assumed_connection (self)) {
4440                 _LOGI (LOGD_DHCP4, "Scheduling DHCPv4 restart because the connection is assumed");
4441                 priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self);
4442                 return;
4443         }
4444
4445         if (timeout || (priv->ip4_state == IP_CONF))
4446                 nm_device_activate_schedule_ip4_config_timeout (self);
4447         else if (priv->ip4_state == IP_DONE)
4448                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
4449         else
4450                 g_warn_if_reached ();
4451 }
4452
4453 static void
4454 dhcp4_dad_cb (NMDevice *self, NMIP4Config **configs, gboolean success)
4455 {
4456         if (success)
4457                 nm_device_activate_schedule_ip4_config_result (self, configs[1]);
4458         else {
4459                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED,
4460                                          NM_DEVICE_STATE_REASON_CONFIG_FAILED);
4461         }
4462 }
4463
4464 static void
4465 dhcp4_state_changed (NMDhcpClient *client,
4466                      NMDhcpState state,
4467                      NMIP4Config *ip4_config,
4468                      GHashTable *options,
4469                      const char *event_id,
4470                      gpointer user_data)
4471 {
4472         NMDevice *self = NM_DEVICE (user_data);
4473         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4474         NMIP4Config *manual, **configs;
4475         NMConnection *connection;
4476
4477         g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == FALSE);
4478         g_return_if_fail (!ip4_config || NM_IS_IP4_CONFIG (ip4_config));
4479
4480         _LOGD (LOGD_DHCP4, "new DHCPv4 client state %d", state);
4481
4482         switch (state) {
4483         case NM_DHCP_STATE_BOUND:
4484                 if (!ip4_config) {
4485                         _LOGW (LOGD_DHCP4, "failed to get IPv4 config in response to DHCP event.");
4486                         nm_device_state_changed (self,
4487                                                  NM_DEVICE_STATE_FAILED,
4488                                                  NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
4489                         break;
4490                 }
4491
4492                 nm_dhcp4_config_set_options (priv->dhcp4_config, options);
4493                 _notify (self, PROP_DHCP4_CONFIG);
4494
4495                 if (priv->ip4_state == IP_CONF) {
4496                         connection = nm_device_get_applied_connection (self);
4497                         g_assert (connection);
4498
4499                         manual = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
4500                         nm_ip4_config_merge_setting (manual,
4501                                                      nm_connection_get_setting_ip4_config (connection),
4502                                                      nm_device_get_ip4_route_metric (self));
4503
4504                         configs = g_new0 (NMIP4Config *, 3);
4505                         configs[0] = manual;
4506                         configs[1] = g_object_ref (ip4_config);
4507
4508                         ipv4_dad_start (self, configs, dhcp4_dad_cb);
4509                 } else if (priv->ip4_state == IP_DONE) {
4510                         dhcp4_lease_change (self, ip4_config);
4511                         nm_device_update_metered (self);
4512                 }
4513                 break;
4514         case NM_DHCP_STATE_TIMEOUT:
4515                 dhcp4_fail (self, TRUE);
4516                 break;
4517         case NM_DHCP_STATE_EXPIRE:
4518                 /* Ignore expiry before we even have a lease (NAK, old lease, etc) */
4519                 if (priv->ip4_state == IP_CONF)
4520                         break;
4521                 /* Fall through */
4522         case NM_DHCP_STATE_DONE:
4523         case NM_DHCP_STATE_FAIL:
4524                 dhcp4_fail (self, FALSE);
4525                 break;
4526         default:
4527                 break;
4528         }
4529 }
4530
4531 static int
4532 dhcp4_get_timeout (NMDevice *self, NMSettingIP4Config *s_ip4)
4533 {
4534         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4535         gs_free char *value = NULL;
4536         int timeout;
4537
4538         timeout = nm_setting_ip_config_get_dhcp_timeout (NM_SETTING_IP_CONFIG (s_ip4));
4539         if (timeout)
4540                 return timeout;
4541
4542         value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
4543                                                        "ipv4.dhcp-timeout",
4544                                                        self);
4545         timeout = _nm_utils_ascii_str_to_int64 (value, 10,
4546                                                 0, G_MAXINT32, 0);
4547         if (timeout)
4548                 return timeout;
4549
4550         return priv->dhcp_timeout;
4551 }
4552
4553 static NMActStageReturn
4554 dhcp4_start (NMDevice *self,
4555              NMConnection *connection,
4556              NMDeviceStateReason *reason)
4557 {
4558         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4559         NMSettingIPConfig *s_ip4;
4560         const guint8 *hw_addr;
4561         size_t hw_addr_len = 0;
4562         GByteArray *tmp = NULL;
4563
4564         s_ip4 = nm_connection_get_setting_ip4_config (connection);
4565
4566         /* Clear old exported DHCP options */
4567         nm_exported_object_clear_and_unexport (&priv->dhcp4_config);
4568         priv->dhcp4_config = nm_dhcp4_config_new ();
4569
4570         hw_addr = nm_platform_link_get_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), &hw_addr_len);
4571         if (hw_addr_len) {
4572                 tmp = g_byte_array_sized_new (hw_addr_len);
4573                 g_byte_array_append (tmp, hw_addr, hw_addr_len);
4574         }
4575
4576         /* Begin DHCP on the interface */
4577         g_warn_if_fail (priv->dhcp4_client == NULL);
4578         priv->dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (),
4579                                                         nm_device_get_ip_iface (self),
4580                                                         nm_device_get_ip_ifindex (self),
4581                                                         tmp,
4582                                                         nm_connection_get_uuid (connection),
4583                                                         nm_device_get_ip4_route_metric (self),
4584                                                         nm_setting_ip_config_get_dhcp_send_hostname (s_ip4),
4585                                                         nm_setting_ip_config_get_dhcp_hostname (s_ip4),
4586                                                         nm_setting_ip4_config_get_dhcp_fqdn (NM_SETTING_IP4_CONFIG (s_ip4)),
4587                                                         nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4)),
4588                                                         dhcp4_get_timeout (self, NM_SETTING_IP4_CONFIG (s_ip4)),
4589                                                         priv->dhcp_anycast_address,
4590                                                         NULL);
4591
4592         if (tmp)
4593                 g_byte_array_free (tmp, TRUE);
4594
4595         if (!priv->dhcp4_client) {
4596                 *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED;
4597                 return NM_ACT_STAGE_RETURN_FAILURE;
4598         }
4599
4600         priv->dhcp4_state_sigid = g_signal_connect (priv->dhcp4_client,
4601                                                     NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
4602                                                     G_CALLBACK (dhcp4_state_changed),
4603                                                     self);
4604
4605         nm_device_add_pending_action (self, PENDING_ACTION_DHCP4, TRUE);
4606
4607         /* DHCP devices will be notified by the DHCP manager when stuff happens */
4608         return NM_ACT_STAGE_RETURN_POSTPONE;
4609 }
4610
4611 gboolean
4612 nm_device_dhcp4_renew (NMDevice *self, gboolean release)
4613 {
4614         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4615         NMActStageReturn ret;
4616         NMDeviceStateReason reason;
4617         NMConnection *connection;
4618
4619         g_return_val_if_fail (priv->dhcp4_client != NULL, FALSE);
4620
4621         _LOGI (LOGD_DHCP4, "DHCPv4 lease renewal requested");
4622
4623         /* Terminate old DHCP instance and release the old lease */
4624         dhcp4_cleanup (self, CLEANUP_TYPE_DECONFIGURE, release);
4625
4626         connection = nm_device_get_applied_connection (self);
4627         g_assert (connection);
4628
4629         /* Start DHCP again on the interface */
4630         ret = dhcp4_start (self, connection, &reason);
4631
4632         return (ret != NM_ACT_STAGE_RETURN_FAILURE);
4633 }
4634
4635 /*********************************************/
4636
4637 static GHashTable *shared_ips = NULL;
4638
4639 static void
4640 release_shared_ip (gpointer data)
4641 {
4642         g_hash_table_remove (shared_ips, data);
4643 }
4644
4645 static gboolean
4646 reserve_shared_ip (NMDevice *self, NMSettingIPConfig *s_ip4, NMPlatformIP4Address *address)
4647 {
4648         if (G_UNLIKELY (shared_ips == NULL))
4649                 shared_ips = g_hash_table_new (g_direct_hash, g_direct_equal);
4650
4651         memset (address, 0, sizeof (*address));
4652
4653         if (s_ip4 && nm_setting_ip_config_get_num_addresses (s_ip4)) {
4654                 /* Use the first user-supplied address */
4655                 NMIPAddress *user = nm_setting_ip_config_get_address (s_ip4, 0);
4656                 in_addr_t a;
4657
4658                 g_assert (user);
4659                 nm_ip_address_get_address_binary (user, &a);
4660                 nm_platform_ip4_address_set_addr (address, a, nm_ip_address_get_prefix (user));
4661         } else {
4662                 /* Find an unused address in the 10.42.x.x range */
4663                 guint32 start = (guint32) ntohl (0x0a2a0001); /* 10.42.0.1 */
4664                 guint32 count = 0;
4665
4666                 while (g_hash_table_lookup (shared_ips, GUINT_TO_POINTER (start + count))) {
4667                         count += ntohl (0x100);
4668                         if (count > ntohl (0xFE00)) {
4669                                 _LOGE (LOGD_SHARING, "ran out of shared IP addresses!");
4670                                 return FALSE;
4671                         }
4672                 }
4673                 nm_platform_ip4_address_set_addr (address, start + count, 24);
4674                 g_hash_table_add (shared_ips, GUINT_TO_POINTER (address->address));
4675         }
4676
4677         return TRUE;
4678 }
4679
4680 static NMIP4Config *
4681 shared4_new_config (NMDevice *self, NMConnection *connection, NMDeviceStateReason *reason)
4682 {
4683         NMIP4Config *config = NULL;
4684         NMPlatformIP4Address address;
4685
4686         g_return_val_if_fail (self != NULL, NULL);
4687
4688         if (!reserve_shared_ip (self, nm_connection_get_setting_ip4_config (connection), &address)) {
4689                 *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
4690                 return NULL;
4691         }
4692
4693         config = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
4694         address.source = NM_IP_CONFIG_SOURCE_SHARED;
4695         nm_ip4_config_add_address (config, &address);
4696
4697         /* Remove the address lock when the object gets disposed */
4698         g_object_set_data_full (G_OBJECT (config), "shared-ip",
4699                                 GUINT_TO_POINTER (address.address),
4700                                 release_shared_ip);
4701
4702         return config;
4703 }
4704
4705 /*********************************************/
4706
4707 static gboolean
4708 connection_ip4_method_requires_carrier (NMConnection *connection,
4709                                         gboolean *out_ip4_enabled)
4710 {
4711         const char *method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
4712         static const char *ip4_carrier_methods[] = {
4713                 NM_SETTING_IP4_CONFIG_METHOD_AUTO,
4714                 NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
4715                 NULL
4716         };
4717
4718         if (out_ip4_enabled)
4719                 *out_ip4_enabled = !!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED);
4720         return _nm_utils_string_in_list (method, ip4_carrier_methods);
4721 }
4722
4723 static gboolean
4724 connection_ip6_method_requires_carrier (NMConnection *connection,
4725                                         gboolean *out_ip6_enabled)
4726 {
4727         const char *method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
4728         static const char *ip6_carrier_methods[] = {
4729                 NM_SETTING_IP6_CONFIG_METHOD_AUTO,
4730                 NM_SETTING_IP6_CONFIG_METHOD_DHCP,
4731                 NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
4732                 NULL
4733         };
4734
4735         if (out_ip6_enabled)
4736                 *out_ip6_enabled = !!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE);
4737         return _nm_utils_string_in_list (method, ip6_carrier_methods);
4738 }
4739
4740 static gboolean
4741 connection_requires_carrier (NMConnection *connection)
4742 {
4743         NMSettingIPConfig *s_ip4, *s_ip6;
4744         gboolean ip4_carrier_wanted, ip6_carrier_wanted;
4745         gboolean ip4_used = FALSE, ip6_used = FALSE;
4746
4747         ip4_carrier_wanted = connection_ip4_method_requires_carrier (connection, &ip4_used);
4748         if (ip4_carrier_wanted) {
4749                 /* If IPv4 wants a carrier and cannot fail, the whole connection
4750                  * requires a carrier regardless of the IPv6 method.
4751                  */
4752                 s_ip4 = nm_connection_get_setting_ip4_config (connection);
4753                 if (s_ip4 && !nm_setting_ip_config_get_may_fail (s_ip4))
4754                         return TRUE;
4755         }
4756
4757         ip6_carrier_wanted = connection_ip6_method_requires_carrier (connection, &ip6_used);
4758         if (ip6_carrier_wanted) {
4759                 /* If IPv6 wants a carrier and cannot fail, the whole connection
4760                  * requires a carrier regardless of the IPv4 method.
4761                  */
4762                 s_ip6 = nm_connection_get_setting_ip6_config (connection);
4763                 if (s_ip6 && !nm_setting_ip_config_get_may_fail (s_ip6))
4764                         return TRUE;
4765         }
4766
4767         /* If an IP version wants a carrier and and the other IP version isn't
4768          * used, the connection requires carrier since it will just fail without one.
4769          */
4770         if (ip4_carrier_wanted && !ip6_used)
4771                 return TRUE;
4772         if (ip6_carrier_wanted && !ip4_used)
4773                 return TRUE;
4774
4775         /* If both want a carrier, the whole connection wants a carrier */
4776         return ip4_carrier_wanted && ip6_carrier_wanted;
4777 }
4778
4779 static gboolean
4780 have_any_ready_slaves (NMDevice *self, const GSList *slaves)
4781 {
4782         const GSList *iter;
4783
4784         /* Any enslaved slave is "ready" in the generic case as it's
4785          * at least >= NM_DEVCIE_STATE_IP_CONFIG and has had Layer 2
4786          * properties set up.
4787          */
4788         for (iter = slaves; iter; iter = g_slist_next (iter)) {
4789                 if (nm_device_get_enslaved (iter->data))
4790                         return TRUE;
4791         }
4792         return FALSE;
4793 }
4794
4795 static gboolean
4796 ip4_requires_slaves (NMConnection *connection)
4797 {
4798         const char *method;
4799
4800         method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
4801         return strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0;
4802 }
4803
4804 static NMActStageReturn
4805 act_stage3_ip4_config_start (NMDevice *self,
4806                              NMIP4Config **out_config,
4807                              NMDeviceStateReason *reason)
4808 {
4809         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4810         NMConnection *connection;
4811         NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
4812         const char *method;
4813         GSList *slaves;
4814         gboolean ready_slaves;
4815
4816         g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
4817
4818         connection = nm_device_get_applied_connection (self);
4819         g_assert (connection);
4820
4821         if (   connection_ip4_method_requires_carrier (connection, NULL)
4822             && priv->is_master
4823             && !priv->carrier) {
4824                 _LOGI (LOGD_IP4 | LOGD_DEVICE,
4825                        "IPv4 config waiting until carrier is on");
4826                 return NM_ACT_STAGE_RETURN_WAIT;
4827         }
4828
4829         if (priv->is_master && ip4_requires_slaves (connection)) {
4830                 /* If the master has no ready slaves, and depends on slaves for
4831                  * a successful IPv4 attempt, then postpone IPv4 addressing.
4832                  */
4833                 slaves = nm_device_master_get_slaves (self);
4834                 ready_slaves = NM_DEVICE_GET_CLASS (self)->have_any_ready_slaves (self, slaves);
4835                 g_slist_free (slaves);
4836
4837                 if (ready_slaves == FALSE) {
4838                         _LOGI (LOGD_DEVICE | LOGD_IP4,
4839                                "IPv4 config waiting until slaves are ready");
4840                         return NM_ACT_STAGE_RETURN_WAIT;
4841                 }
4842         }
4843
4844         method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
4845
4846         /* Start IPv4 addressing based on the method requested */
4847         if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0)
4848                 ret = dhcp4_start (self, connection, reason);
4849         else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) == 0)
4850                 ret = ipv4ll_start (self, reason);
4851         else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0) {
4852                 NMIP4Config **configs, *config;
4853
4854                 config = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
4855                 nm_ip4_config_merge_setting (config,
4856                                              nm_connection_get_setting_ip4_config (connection),
4857                                              nm_device_get_ip4_route_metric (self));
4858
4859                 configs = g_new0 (NMIP4Config *, 2);
4860                 configs[0] = config;
4861                 ipv4_dad_start (self, configs, ipv4_manual_method_apply);
4862                 ret = NM_ACT_STAGE_RETURN_POSTPONE;
4863         } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) {
4864                 *out_config = shared4_new_config (self, connection, reason);
4865                 if (*out_config) {
4866                         priv->dnsmasq_manager = nm_dnsmasq_manager_new (nm_device_get_ip_iface (self));
4867                         ret = NM_ACT_STAGE_RETURN_SUCCESS;
4868                 } else
4869                         ret = NM_ACT_STAGE_RETURN_FAILURE;
4870         } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) {
4871                 /* Nothing to do... */
4872                 ret = NM_ACT_STAGE_RETURN_STOP;
4873         } else
4874                 _LOGW (LOGD_IP4, "unhandled IPv4 config method '%s'; will fail", method);
4875
4876         return ret;
4877 }
4878
4879 /*********************************************/
4880 /* DHCPv6 stuff */
4881
4882 static void
4883 dhcp6_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release)
4884 {
4885         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4886
4887         priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE;
4888         g_clear_object (&priv->dhcp6_ip6_config);
4889         g_clear_pointer (&priv->dhcp6_event_id, g_free);
4890         nm_clear_g_source (&priv->dhcp6_restart_id);
4891
4892         if (priv->dhcp6_client) {
4893                 nm_clear_g_signal_handler (priv->dhcp6_client, &priv->dhcp6_state_sigid);
4894
4895                 if (   cleanup_type == CLEANUP_TYPE_DECONFIGURE
4896                     || cleanup_type == CLEANUP_TYPE_REMOVED)
4897                         nm_dhcp_client_stop (priv->dhcp6_client, release);
4898
4899                 g_clear_object (&priv->dhcp6_client);
4900         }
4901
4902         nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
4903
4904         if (priv->dhcp6_config) {
4905                 nm_exported_object_clear_and_unexport (&priv->dhcp6_config);
4906                 _notify (self, PROP_DHCP6_CONFIG);
4907         }
4908 }
4909
4910 static void
4911 _ip6_config_merge_default (gpointer value, gpointer user_data)
4912 {
4913         NMIP6Config *src = (NMIP6Config *) value;
4914         NMIP6Config *dst = (NMIP6Config *) user_data;
4915
4916         nm_ip6_config_merge (dst, src, NM_IP_CONFIG_MERGE_DEFAULT);
4917 }
4918
4919 static gboolean
4920 ip6_config_merge_and_apply (NMDevice *self,
4921                             gboolean commit,
4922                             NMDeviceStateReason *out_reason)
4923 {
4924         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4925         NMConnection *connection;
4926         gboolean success;
4927         NMIP6Config *composite;
4928         gboolean has_direct_route;
4929         const struct in6_addr *gateway;
4930         gboolean connection_has_default_route, connection_is_never_default;
4931         gboolean routes_full_sync;
4932         gboolean ignore_auto_routes = FALSE;
4933         gboolean ignore_auto_dns = FALSE;
4934
4935         /* Apply ignore-auto-routes and ignore-auto-dns settings */
4936         connection = nm_device_get_applied_connection (self);
4937         if (connection) {
4938                 NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection);
4939
4940                 if (s_ip6) {
4941                         ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip6);
4942                         ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip6);
4943                 }
4944         }
4945
4946         /* If no config was passed in, create a new one */
4947         composite = nm_ip6_config_new (nm_device_get_ip_ifindex (self));
4948
4949         if (commit)
4950                 ensure_con_ip6_config (self);
4951         g_assert (composite);
4952
4953         /* Merge all the IP configs into the composite config */
4954         if (priv->ac_ip6_config) {
4955                 nm_ip6_config_merge (composite, priv->ac_ip6_config,
4956                                        (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
4957                                      | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
4958         }
4959         if (priv->dhcp6_ip6_config) {
4960                 nm_ip6_config_merge (composite, priv->dhcp6_ip6_config,
4961                                        (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
4962                                      | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
4963         }
4964
4965         g_slist_foreach (priv->vpn6_configs, _ip6_config_merge_default, composite);
4966
4967         if (priv->ext_ip6_config)
4968                 nm_ip6_config_merge (composite, priv->ext_ip6_config, NM_IP_CONFIG_MERGE_DEFAULT);
4969
4970         /* Merge WWAN config *last* to ensure modem-given settings overwrite
4971          * any external stuff set by pppd or other scripts.
4972          */
4973         if (priv->wwan_ip6_config) {
4974                 nm_ip6_config_merge (composite, priv->wwan_ip6_config,
4975                                        (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
4976                                      | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
4977         }
4978
4979         /* Merge user overrides into the composite config. For assumed connections,
4980          * con_ip6_config is empty. */
4981         if (priv->con_ip6_config)
4982                 nm_ip6_config_merge (composite, priv->con_ip6_config, NM_IP_CONFIG_MERGE_DEFAULT);
4983
4984         /* Add the default route.
4985          *
4986          * We keep track of the default route of a device in a private field.
4987          * NMDevice needs to know the default route at this point, because the gateway
4988          * might require a direct route (see below).
4989          *
4990          * But also, we don't want to add the default route to priv->ip6_config,
4991          * because the default route from the setting might not be the same that
4992          * NMDefaultRouteManager eventually configures (because the it might
4993          * tweak the effective metric).
4994          */
4995
4996         /* unless we come to a different conclusion below, we have no default route and
4997          * the route is assumed. */
4998         priv->default_route.v6_has = FALSE;
4999         priv->default_route.v6_is_assumed = TRUE;
5000
5001         if (!commit) {
5002                 /* during a non-commit event, we always pickup whatever is configured. */
5003                 goto END_ADD_DEFAULT_ROUTE;
5004         }
5005
5006         if (nm_device_uses_generated_assumed_connection (self)) {
5007                 /* a generate-assumed-connection always detects the default route from platform */
5008                 goto END_ADD_DEFAULT_ROUTE;
5009         }
5010
5011         /* At this point, we treat assumed and non-assumed connections alike.
5012          * For assumed connections we do that because we still manage RA and DHCP
5013          * leases for them, so we must extend/update the default route on commits.
5014          */
5015
5016         connection_has_default_route
5017             = nm_default_route_manager_ip6_connection_has_default_route (nm_default_route_manager_get (),
5018                                                                          connection, &connection_is_never_default);
5019
5020         if (   !priv->v6_commit_first_time
5021             && connection_is_never_default) {
5022                 /* If the connection is explicitly configured as never-default, we enforce the (absence of the)
5023                  * default-route only once. That allows the user to configure a connection as never-default,
5024                  * but he can add default routes externally (via a dispatcher script) and NM will not interfere. */
5025                 goto END_ADD_DEFAULT_ROUTE;
5026         }
5027
5028         /* we are about to commit (for a non-assumed connection). Enforce whatever we have
5029          * configured. */
5030         priv->default_route.v6_is_assumed = FALSE;
5031
5032         if (!connection_has_default_route)
5033                 goto END_ADD_DEFAULT_ROUTE;
5034
5035         if (!nm_ip6_config_get_num_addresses (composite)) {
5036                 /* without addresses we can have no default route. */
5037                 goto END_ADD_DEFAULT_ROUTE;
5038         }
5039
5040         gateway = nm_ip6_config_get_gateway (composite);
5041         if (!gateway)
5042                 goto END_ADD_DEFAULT_ROUTE;
5043
5044
5045         has_direct_route = nm_ip6_config_get_direct_route_for_host (composite, gateway) != NULL;
5046
5047
5048
5049         priv->default_route.v6_has = TRUE;
5050         memset (&priv->default_route.v6, 0, sizeof (priv->default_route.v6));
5051         priv->default_route.v6.source = NM_IP_CONFIG_SOURCE_USER;
5052         priv->default_route.v6.gateway = *gateway;
5053         priv->default_route.v6.metric = nm_device_get_ip6_route_metric (self);
5054         priv->default_route.v6.mss = nm_ip6_config_get_mss (composite);
5055
5056         if (!has_direct_route) {
5057                 NMPlatformIP6Route r = priv->default_route.v6;
5058
5059                 /* add a direct route to the gateway */
5060                 r.network = *gateway;
5061                 r.plen = 128;
5062                 r.gateway = in6addr_any;
5063                 nm_ip6_config_add_route (composite, &r);
5064         }
5065
5066 END_ADD_DEFAULT_ROUTE:
5067
5068         if (priv->default_route.v6_is_assumed) {
5069                 /* If above does not explicitly assign a default route, we always pick up the
5070                  * default route based on what is currently configured.
5071                  * That means that even managed connections with never-default, can
5072                  * get a default route (if configured externally).
5073                  */
5074                 priv->default_route.v6_has = _device_get_default_route_from_platform (self, AF_INET6, (NMPlatformIPRoute *) &priv->default_route.v6);
5075         }
5076
5077         nm_ip6_config_addresses_sort (composite,
5078             priv->rdisc ? priv->rdisc_use_tempaddr : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
5079
5080         /* Allow setting MTU etc */
5081         if (commit) {
5082                 if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit)
5083                         NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self, composite);
5084         }
5085
5086         routes_full_sync =    commit
5087                            && priv->v6_commit_first_time
5088                            && !nm_device_uses_assumed_connection (self);
5089
5090         success = nm_device_set_ip6_config (self, composite, commit, routes_full_sync, out_reason);
5091         g_object_unref (composite);
5092         if (commit)
5093                 priv->v6_commit_first_time = FALSE;
5094         return success;
5095 }
5096
5097 static void
5098 dhcp6_lease_change (NMDevice *self)
5099 {
5100         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5101         NMSettingsConnection *settings_connection;
5102         NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
5103
5104         if (priv->dhcp6_ip6_config == NULL) {
5105                 _LOGW (LOGD_DHCP6, "failed to get DHCPv6 config for rebind");
5106                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
5107                 return;
5108         }
5109
5110         g_assert (priv->dhcp6_client);  /* sanity check */
5111
5112         settings_connection = nm_device_get_settings_connection (self);
5113         g_assert (settings_connection);
5114
5115         /* Apply the updated config */
5116         if (ip6_config_merge_and_apply (self, TRUE, &reason) == FALSE) {
5117                 _LOGW (LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event.");
5118                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
5119         } else {
5120                 /* Notify dispatcher scripts of new DHCPv6 config */
5121                 nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE,
5122                                     settings_connection,
5123                                     nm_device_get_applied_connection (self),
5124                                     self, NULL, NULL, NULL);
5125         }
5126 }
5127
5128 static gboolean
5129 dhcp6_restart_cb (gpointer user_data)
5130 {
5131         NMDevice *self = user_data;
5132         NMDevicePrivate *priv;
5133         NMDeviceStateReason reason;
5134
5135         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
5136
5137         priv = NM_DEVICE_GET_PRIVATE (self);
5138         priv->dhcp6_restart_id = 0;
5139
5140         if (!dhcp6_start (self, FALSE, &reason))
5141                 priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self);
5142
5143         return FALSE;
5144 }
5145
5146 static void
5147 dhcp6_fail (NMDevice *self, gboolean timeout)
5148 {
5149         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5150
5151         dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE);
5152
5153         if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) {
5154                 /* Don't fail if there are static addresses configured on
5155                  * the device, instead retry after some time.
5156                  */
5157                 if (   priv->ip6_state == IP_DONE
5158                     && priv->con_ip6_config
5159                     && nm_ip6_config_get_num_addresses (priv->con_ip6_config)) {
5160                         _LOGI (LOGD_DHCP6, "Scheduling DHCPv6 restart because device has IP addresses");
5161                         priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self);
5162                         return;
5163                 }
5164
5165                 /* Instead of letting an assumed connection fail (which means that the
5166                  * device will transition to the ACTIVATED state without IP configuration),
5167                  * retry DHCP again.
5168                  */
5169                 if (nm_device_uses_assumed_connection (self)) {
5170                         _LOGI (LOGD_DHCP6, "Scheduling DHCPv6 restart because the connection is assumed");
5171                         priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self);
5172                         return;
5173                 }
5174
5175                 if (timeout || (priv->ip6_state == IP_CONF))
5176                         nm_device_activate_schedule_ip6_config_timeout (self);
5177                 else if (priv->ip6_state == IP_DONE)
5178                         nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
5179                 else
5180                         g_warn_if_reached ();
5181         } else {
5182                 /* not a hard failure; just live with the RA info */
5183                 if (priv->ip6_state == IP_CONF)
5184                         nm_device_activate_schedule_ip6_config_result (self);
5185         }
5186 }
5187
5188 static void
5189 dhcp6_timeout (NMDevice *self, NMDhcpClient *client)
5190 {
5191         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5192
5193         if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED)
5194                 dhcp6_fail (self, TRUE);
5195         else {
5196                 /* not a hard failure; just live with the RA info */
5197                 dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE);
5198                 if (priv->ip6_state == IP_CONF)
5199                         nm_device_activate_schedule_ip6_config_result (self);
5200         }
5201 }
5202
5203 static void
5204 dhcp6_state_changed (NMDhcpClient *client,
5205                      NMDhcpState state,
5206                      NMIP6Config *ip6_config,
5207                      GHashTable *options,
5208                      const char *event_id,
5209                      gpointer user_data)
5210 {
5211         NMDevice *self = NM_DEVICE (user_data);
5212         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5213         guint i;
5214
5215         g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == TRUE);
5216         g_return_if_fail (!ip6_config || NM_IS_IP6_CONFIG (ip6_config));
5217
5218         _LOGD (LOGD_DHCP6, "new DHCPv6 client state %d", state);
5219
5220         switch (state) {
5221         case NM_DHCP_STATE_BOUND:
5222                 /* If the server sends multiple IPv6 addresses, we receive a state
5223                  * changed event for each of them. Use the event ID to merge IPv6
5224                  * addresses from the same transaction into a single configuration.
5225                  */
5226                 if (   ip6_config
5227                     && event_id
5228                     && priv->dhcp6_event_id
5229                     && !strcmp (event_id, priv->dhcp6_event_id)) {
5230                         for (i = 0; i < nm_ip6_config_get_num_addresses (ip6_config); i++) {
5231                                 nm_ip6_config_add_address (priv->dhcp6_ip6_config,
5232                                                            nm_ip6_config_get_address (ip6_config, i));
5233                         }
5234                 } else {
5235                         g_clear_object (&priv->dhcp6_ip6_config);
5236                         g_clear_pointer (&priv->dhcp6_event_id, g_free);
5237                         if (ip6_config) {
5238                                 priv->dhcp6_ip6_config = g_object_ref (ip6_config);
5239                                 priv->dhcp6_event_id = g_strdup (event_id);
5240                                 nm_dhcp6_config_set_options (priv->dhcp6_config, options);
5241                                 _notify (self, PROP_DHCP6_CONFIG);
5242                         }
5243                 }
5244
5245                 if (priv->ip6_state == IP_CONF) {
5246                         if (priv->dhcp6_ip6_config == NULL) {
5247                                 /* FIXME: Initial DHCP failed; should we fail IPv6 entirely then? */
5248                                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED);
5249                                 break;
5250                         }
5251                         nm_device_activate_schedule_ip6_config_result (self);
5252                 } else if (priv->ip6_state == IP_DONE)
5253                         dhcp6_lease_change (self);
5254                 break;
5255         case NM_DHCP_STATE_TIMEOUT:
5256                 dhcp6_timeout (self, client);
5257                 break;
5258         case NM_DHCP_STATE_EXPIRE:
5259                 /* Ignore expiry before we even have a lease (NAK, old lease, etc) */
5260                 if (priv->ip6_state != IP_CONF)
5261                         dhcp6_fail (self, FALSE);
5262                 break;
5263         case NM_DHCP_STATE_DONE:
5264                 /* In IPv6 info-only mode, the client doesn't handle leases so it
5265                  * may exit right after getting a response from the server.  That's
5266                  * normal.  In that case we just ignore the exit.
5267                  */
5268                 if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF)
5269                         break;
5270                 /* Otherwise, fall through */
5271         case NM_DHCP_STATE_FAIL:
5272                 dhcp6_fail (self, FALSE);
5273                 break;
5274         default:
5275                 break;
5276         }
5277 }
5278
5279 static gboolean
5280 dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection)
5281 {
5282         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5283         NMSettingIPConfig *s_ip6;
5284         GByteArray *tmp = NULL;
5285         const guint8 *hw_addr;
5286         size_t hw_addr_len = 0;
5287         const NMPlatformIP6Address *ll_addr = NULL;
5288
5289         g_assert (connection);
5290         s_ip6 = nm_connection_get_setting_ip6_config (connection);
5291         g_assert (s_ip6);
5292
5293         hw_addr = nm_platform_link_get_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), &hw_addr_len);
5294         if (hw_addr_len) {
5295                 tmp = g_byte_array_sized_new (hw_addr_len);
5296                 g_byte_array_append (tmp, hw_addr, hw_addr_len);
5297         }
5298
5299         if (priv->ext_ip6_config_captured)
5300                 ll_addr = nm_ip6_config_get_address_first_nontentative (priv->ext_ip6_config_captured, TRUE);
5301
5302         g_return_val_if_fail (ll_addr, FALSE);
5303
5304         priv->dhcp6_client = nm_dhcp_manager_start_ip6 (nm_dhcp_manager_get (),
5305                                                         nm_device_get_ip_iface (self),
5306                                                         nm_device_get_ip_ifindex (self),
5307                                                         tmp,
5308                                                         &ll_addr->address,
5309                                                         nm_connection_get_uuid (connection),
5310                                                         nm_device_get_ip6_route_metric (self),
5311                                                         nm_setting_ip_config_get_dhcp_send_hostname (s_ip6),
5312                                                         nm_setting_ip_config_get_dhcp_hostname (s_ip6),
5313                                                         priv->dhcp_timeout,
5314                                                         priv->dhcp_anycast_address,
5315                                                         (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE,
5316                                                         nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)));
5317         if (tmp)
5318                 g_byte_array_free (tmp, TRUE);
5319
5320         if (priv->dhcp6_client) {
5321                 priv->dhcp6_state_sigid = g_signal_connect (priv->dhcp6_client,
5322                                                             NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
5323                                                             G_CALLBACK (dhcp6_state_changed),
5324                                                             self);
5325         }
5326
5327         return !!priv->dhcp6_client;
5328 }
5329
5330 static gboolean
5331 dhcp6_start (NMDevice *self, gboolean wait_for_ll, NMDeviceStateReason *reason)
5332 {
5333         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5334         NMConnection *connection;
5335         NMSettingIPConfig *s_ip6;
5336
5337         nm_exported_object_clear_and_unexport (&priv->dhcp6_config);
5338         priv->dhcp6_config = nm_dhcp6_config_new ();
5339
5340         g_warn_if_fail (priv->dhcp6_ip6_config == NULL);
5341         g_clear_object (&priv->dhcp6_ip6_config);
5342         g_clear_pointer (&priv->dhcp6_event_id, g_free);
5343
5344         connection = nm_device_get_applied_connection (self);
5345         g_assert (connection);
5346         s_ip6 = nm_connection_get_setting_ip6_config (connection);
5347         if (!nm_setting_ip_config_get_may_fail (s_ip6) ||
5348             !strcmp (nm_setting_ip_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_DHCP))
5349                 nm_device_add_pending_action (self, PENDING_ACTION_DHCP6, TRUE);
5350
5351         if (wait_for_ll) {
5352                 NMActStageReturn ret;
5353
5354                 /* ensure link local is ready... */
5355                 ret = linklocal6_start (self);
5356                 if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
5357                         /* success; wait for the LL address to show up */
5358                         return TRUE;
5359                 }
5360
5361                 /* success; already have the LL address; kick off DHCP */
5362                 g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS || ret == NM_ACT_STAGE_RETURN_FINISH);
5363         }
5364
5365         if (!dhcp6_start_with_link_ready (self, connection)) {
5366                 *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED;
5367                 return FALSE;
5368         }
5369
5370         return TRUE;
5371 }
5372
5373 gboolean
5374 nm_device_dhcp6_renew (NMDevice *self, gboolean release)
5375 {
5376         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5377
5378         g_return_val_if_fail (priv->dhcp6_client != NULL, FALSE);
5379
5380         _LOGI (LOGD_DHCP6, "DHCPv6 lease renewal requested");
5381
5382         /* Terminate old DHCP instance and release the old lease */
5383         dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, release);
5384
5385         /* Start DHCP again on the interface */
5386         return dhcp6_start (self, FALSE, NULL);
5387 }
5388
5389 /******************************************/
5390
5391 static void
5392 linklocal6_cleanup (NMDevice *self)
5393 {
5394         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5395
5396         nm_clear_g_source (&priv->linklocal6_timeout_id);
5397 }
5398
5399 static void
5400 linklocal6_failed (NMDevice *self)
5401 {
5402         linklocal6_cleanup (self);
5403         nm_device_activate_schedule_ip6_config_timeout (self);
5404 }
5405
5406 static gboolean
5407 linklocal6_timeout_cb (gpointer user_data)
5408 {
5409         NMDevice *self = user_data;
5410
5411         _LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses failed due to timeout");
5412         linklocal6_failed (self);
5413         return G_SOURCE_REMOVE;
5414 }
5415
5416 static void
5417 linklocal6_complete (NMDevice *self)
5418 {
5419         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5420         NMConnection *connection;
5421         const char *method;
5422
5423         g_assert (priv->linklocal6_timeout_id);
5424         g_assert (nm_ip6_config_get_address_first_nontentative (priv->ip6_config, TRUE));
5425
5426         linklocal6_cleanup (self);
5427
5428         connection = nm_device_get_applied_connection (self);
5429         g_assert (connection);
5430
5431         method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
5432
5433         _LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses successful, continue with method %s", method);
5434
5435         if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
5436                 if (!addrconf6_start_with_link_ready (self)) {
5437                         /* Time out IPv6 instead of failing the entire activation */
5438                         nm_device_activate_schedule_ip6_config_timeout (self);
5439                 }
5440         } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) {
5441                 if (!dhcp6_start_with_link_ready (self, connection)) {
5442                         /* Time out IPv6 instead of failing the entire activation */
5443                         nm_device_activate_schedule_ip6_config_timeout (self);
5444                 }
5445         } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0)
5446                 nm_device_activate_schedule_ip6_config_result (self);
5447         else
5448                 g_return_if_fail (FALSE);
5449 }
5450
5451 static void
5452 check_and_add_ipv6ll_addr (NMDevice *self)
5453 {
5454         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5455         int ip_ifindex = nm_device_get_ip_ifindex (self);
5456         struct in6_addr lladdr;
5457         guint i, n;
5458         NMConnection *connection;
5459         NMSettingIP6Config *s_ip6 = NULL;
5460         GError *error = NULL;
5461
5462         if (priv->nm_ipv6ll == FALSE)
5463                 return;
5464
5465         if (priv->ip6_config) {
5466                 n = nm_ip6_config_get_num_addresses (priv->ip6_config);
5467                 for (i = 0; i < n; i++) {
5468                         const NMPlatformIP6Address *addr;
5469
5470                         addr = nm_ip6_config_get_address (priv->ip6_config, i);
5471                         if (   IN6_IS_ADDR_LINKLOCAL (&addr->address)
5472                             && !(addr->n_ifa_flags & IFA_F_DADFAILED)) {
5473                                 /* Already have an LL address, nothing to do */
5474                                 return;
5475                         }
5476                 }
5477         }
5478
5479         memset (&lladdr, 0, sizeof (lladdr));
5480         lladdr.s6_addr16[0] = htons (0xfe80);
5481
5482         connection = nm_device_get_applied_connection (self);
5483         if (connection)
5484                 s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection));
5485
5486         if (s_ip6 && nm_setting_ip6_config_get_addr_gen_mode (s_ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) {
5487                 if (!nm_utils_ipv6_addr_set_stable_privacy (&lladdr,
5488                                                             nm_device_get_iface (self),
5489                                                             nm_connection_get_uuid (connection),
5490                                                             priv->linklocal6_dad_counter++,
5491                                                             &error)) {
5492                         _LOGW (LOGD_IP6, "linklocal6: failed to generate an address: %s", error->message);
5493                         g_clear_error (&error);
5494                         linklocal6_failed (self);
5495                         return;
5496                 }
5497                 _LOGD (LOGD_IP6, "linklocal6: using IPv6 stable-privacy addressing");
5498         } else {
5499                 NMUtilsIPv6IfaceId iid;
5500
5501                 if (priv->linklocal6_timeout_id) {
5502                         /* We already started and attempt to add a LL address. For the EUI-64
5503                          * mode we can't pick a new one, we'll just fail. */
5504                         _LOGW (LOGD_IP6, "linklocal6: DAD failed for an EUI-64 address");
5505                         linklocal6_failed (self);
5506                         return;
5507                 }
5508
5509                 if (!nm_device_get_ip_iface_identifier (self, &iid)) {
5510                         _LOGW (LOGD_IP6, "linklocal6: failed to get interface identifier; IPv6 cannot continue");
5511                         return;
5512                 }
5513                 _LOGD (LOGD_IP6, "linklocal6: using EUI-64 identifier to generate IPv6LL address");
5514
5515                 nm_utils_ipv6_addr_set_interface_identfier (&lladdr, iid);
5516         }
5517
5518         _LOGD (LOGD_IP6, "linklocal6: adding IPv6LL address %s", nm_utils_inet6_ntop (&lladdr, NULL));
5519         if (!nm_platform_ip6_address_add (NM_PLATFORM_GET,
5520                                           ip_ifindex,
5521                                           lladdr,
5522                                           64,
5523                                           in6addr_any,
5524                                           NM_PLATFORM_LIFETIME_PERMANENT,
5525                                           NM_PLATFORM_LIFETIME_PERMANENT,
5526                                           0)) {
5527                 _LOGW (LOGD_IP6, "failed to add IPv6 link-local address %s",
5528                        nm_utils_inet6_ntop (&lladdr, NULL));
5529         }
5530 }
5531
5532 static NMActStageReturn
5533 linklocal6_start (NMDevice *self)
5534 {
5535         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5536         NMConnection *connection;
5537         const char *method;
5538
5539         linklocal6_cleanup (self);
5540
5541         if (   priv->ip6_config
5542             && nm_ip6_config_get_address_first_nontentative (priv->ip6_config, TRUE))
5543                 return NM_ACT_STAGE_RETURN_FINISH;
5544
5545         connection = nm_device_get_applied_connection (self);
5546         g_assert (connection);
5547
5548         method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
5549         _LOGD (LOGD_DEVICE, "linklocal6: starting IPv6 with method '%s', but the device has no link-local addresses configured. Wait.", method);
5550
5551         check_and_add_ipv6ll_addr (self);
5552
5553         /* Depending on the network and what the 'dad_transmits' and 'retrans_time_ms'
5554          * sysctl values are, DAD for the IPv6LL address may take quite a while.
5555          * FIXME: use dad/retrans sysctl values if they are higher than a minimum time.
5556          * (rh #1101809)
5557          */
5558         priv->linklocal6_timeout_id = g_timeout_add_seconds (15, linklocal6_timeout_cb, self);
5559
5560         return NM_ACT_STAGE_RETURN_POSTPONE;
5561 }
5562
5563 /******************************************/
5564
5565 static void nm_device_ipv6_set_mtu (NMDevice *self, guint32 mtu);
5566
5567 static void
5568 nm_device_set_mtu (NMDevice *self, guint32 mtu)
5569 {
5570         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5571         int ifindex = nm_device_get_ip_ifindex (self);
5572
5573         if (mtu)
5574                 priv->mtu = mtu;
5575
5576         /* Ensure the IPv6 MTU is still alright. */
5577         if (priv->ip6_mtu)
5578                 nm_device_ipv6_set_mtu (self, priv->ip6_mtu);
5579
5580         if (priv->mtu && priv->mtu != nm_platform_link_get_mtu (NM_PLATFORM_GET, ifindex))
5581                 nm_platform_link_set_mtu (NM_PLATFORM_GET, ifindex, priv->mtu);
5582 }
5583
5584 static void
5585 nm_device_ipv6_set_mtu (NMDevice *self, guint32 mtu)
5586 {
5587         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5588         guint32 plat_mtu = nm_device_ipv6_sysctl_get_int32 (self, "mtu", priv->mtu);
5589         char val[16];
5590
5591         priv->ip6_mtu = mtu ?: plat_mtu;
5592
5593         if (priv->ip6_mtu && priv->mtu && priv->mtu < priv->ip6_mtu) {
5594                 _LOGI (LOGD_DEVICE | LOGD_IP6, "Lowering IPv6 MTU (%d) to match device MTU (%d)",
5595                        priv->ip6_mtu, priv->mtu);
5596                 priv->ip6_mtu = priv->mtu;
5597         }
5598
5599         if (priv->ip6_mtu && priv->ip6_mtu < 1280) {
5600                 _LOGI (LOGD_DEVICE | LOGD_IP6, "IPv6 MTU (%d) smaller than 1280, adjusting",
5601                        priv->ip6_mtu);
5602                 priv->ip6_mtu = 1280;
5603         }
5604
5605         if (priv->ip6_mtu && priv->mtu && priv->mtu < priv->ip6_mtu) {
5606                 _LOGI (LOGD_DEVICE | LOGD_IP6, "Raising device MTU (%d) to match IPv6 MTU (%d)",
5607                        priv->mtu, priv->ip6_mtu);
5608                 nm_device_set_mtu (self, priv->ip6_mtu);
5609         }
5610
5611         if (priv->ip6_mtu != plat_mtu) {
5612                 g_snprintf (val, sizeof (val), "%d", mtu);
5613                 nm_device_ipv6_sysctl_set (self, "mtu", val);
5614         }
5615 }
5616
5617 static void
5618 rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
5619 {
5620         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5621         int i;
5622         int system_support;
5623         guint32 ifa_flags = 0x00;
5624
5625         /*
5626          * Check, whether kernel is recent enough to help user space handling RA.
5627          * If it's not supported, we have no ipv6-privacy and must add autoconf
5628          * addresses as /128. The reason for the /128 is to prevent the kernel
5629          * from adding a prefix route for this address.
5630          **/
5631         system_support = nm_platform_check_support_kernel_extended_ifa_flags (NM_PLATFORM_GET);
5632
5633         if (system_support)
5634                 ifa_flags = IFA_F_NOPREFIXROUTE;
5635         if (   priv->rdisc_use_tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR
5636             || priv->rdisc_use_tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)
5637         {
5638                 /* without system_support, this flag will be ignored. Still set it, doesn't seem to do any harm. */
5639                 ifa_flags |= IFA_F_MANAGETEMPADDR;
5640         }
5641
5642         g_return_if_fail (priv->act_request);
5643
5644         if (!priv->ac_ip6_config)
5645                 priv->ac_ip6_config = nm_ip6_config_new (nm_device_get_ip_ifindex (self));
5646
5647         if (changed & NM_RDISC_CONFIG_GATEWAYS) {
5648                 /* Use the first gateway as ordered in router discovery cache. */
5649                 if (rdisc->gateways->len) {
5650                         NMRDiscGateway *gateway = &g_array_index (rdisc->gateways, NMRDiscGateway, 0);
5651
5652                         nm_ip6_config_set_gateway (priv->ac_ip6_config, &gateway->address);
5653                 } else
5654                         nm_ip6_config_set_gateway (priv->ac_ip6_config, NULL);
5655         }
5656
5657         if (changed & NM_RDISC_CONFIG_ADDRESSES) {
5658                 /* Rebuild address list from router discovery cache. */
5659                 nm_ip6_config_reset_addresses (priv->ac_ip6_config);
5660
5661                 /* rdisc->addresses contains at most max_addresses entries.
5662                  * This is different from what the kernel does, which
5663                  * also counts static and temporary addresses when checking
5664                  * max_addresses.
5665                  **/
5666                 for (i = 0; i < rdisc->addresses->len; i++) {
5667                         NMRDiscAddress *discovered_address = &g_array_index (rdisc->addresses, NMRDiscAddress, i);
5668                         NMPlatformIP6Address address;
5669
5670                         memset (&address, 0, sizeof (address));
5671                         address.address = discovered_address->address;
5672                         address.plen = system_support ? 64 : 128;
5673                         address.timestamp = discovered_address->timestamp;
5674                         address.lifetime = discovered_address->lifetime;
5675                         address.preferred = discovered_address->preferred;
5676                         if (address.preferred > address.lifetime)
5677                                 address.preferred = address.lifetime;
5678                         address.source = NM_IP_CONFIG_SOURCE_RDISC;
5679                         address.n_ifa_flags = ifa_flags;
5680
5681                         nm_ip6_config_add_address (priv->ac_ip6_config, &address);
5682                 }
5683         }
5684
5685         if (changed & NM_RDISC_CONFIG_ROUTES) {
5686                 /* Rebuild route list from router discovery cache. */
5687                 nm_ip6_config_reset_routes (priv->ac_ip6_config);
5688
5689                 for (i = 0; i < rdisc->routes->len; i++) {
5690                         NMRDiscRoute *discovered_route = &g_array_index (rdisc->routes, NMRDiscRoute, i);
5691                         NMPlatformIP6Route route;
5692
5693                         /* Only accept non-default routes.  The router has no idea what the
5694                          * local configuration or user preferences are, so sending routes
5695                          * with a prefix length of 0 is quite rude and thus ignored.
5696                          */
5697                         if (discovered_route->plen > 0) {
5698                                 memset (&route, 0, sizeof (route));
5699                                 route.network = discovered_route->network;
5700                                 route.plen = discovered_route->plen;
5701                                 route.gateway = discovered_route->gateway;
5702                                 route.source = NM_IP_CONFIG_SOURCE_RDISC;
5703                                 route.metric = nm_device_get_ip6_route_metric (self);
5704
5705                                 nm_ip6_config_add_route (priv->ac_ip6_config, &route);
5706                         }
5707                 }
5708         }
5709
5710         if (changed & NM_RDISC_CONFIG_DNS_SERVERS) {
5711                 /* Rebuild DNS server list from router discovery cache. */
5712                 nm_ip6_config_reset_nameservers (priv->ac_ip6_config);
5713
5714                 for (i = 0; i < rdisc->dns_servers->len; i++) {
5715                         NMRDiscDNSServer *discovered_server = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i);
5716
5717                         nm_ip6_config_add_nameserver (priv->ac_ip6_config, &discovered_server->address);
5718                 }
5719         }
5720
5721         if (changed & NM_RDISC_CONFIG_DNS_DOMAINS) {
5722                 /* Rebuild domain list from router discovery cache. */
5723                 nm_ip6_config_reset_domains (priv->ac_ip6_config);
5724
5725                 for (i = 0; i < rdisc->dns_domains->len; i++) {
5726                         NMRDiscDNSDomain *discovered_domain = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i);
5727
5728                         nm_ip6_config_add_domain (priv->ac_ip6_config, discovered_domain->domain);
5729                 }
5730         }
5731
5732         if (changed & NM_RDISC_CONFIG_DHCP_LEVEL) {
5733                 dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, TRUE);
5734
5735                 priv->dhcp6_mode = rdisc->dhcp_level;
5736                 if (priv->dhcp6_mode != NM_RDISC_DHCP_LEVEL_NONE) {
5737                         NMDeviceStateReason reason;
5738
5739                         _LOGD (LOGD_DEVICE | LOGD_DHCP6,
5740                                "Activation: Stage 3 of 5 (IP Configure Start) starting DHCPv6"
5741                                " as requested by IPv6 router...");
5742                         if (!dhcp6_start (self, FALSE, &reason)) {
5743                                 if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) {
5744                                         nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
5745                                         return;
5746                                 }
5747                         }
5748                 }
5749         }
5750
5751         if (changed & NM_RDISC_CONFIG_HOP_LIMIT)
5752                 nm_platform_sysctl_set_ip6_hop_limit_safe (NM_PLATFORM_GET, nm_device_get_ip_iface (self), rdisc->hop_limit);
5753
5754         if (changed & NM_RDISC_CONFIG_MTU)
5755                 priv->ip6_mtu = rdisc->mtu;
5756
5757         nm_device_activate_schedule_ip6_config_result (self);
5758 }
5759
5760 static void
5761 rdisc_ra_timeout (NMRDisc *rdisc, NMDevice *self)
5762 {
5763         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5764
5765         /* We don't want to stop listening for router advertisements completely,
5766          * but instead let device activation continue activating.  If an RA
5767          * shows up later, we'll use it as long as the device is not disconnected.
5768          */
5769
5770         _LOGD (LOGD_IP6, "timed out waiting for IPv6 router advertisement");
5771         if (priv->ip6_state == IP_CONF) {
5772                 /* If RA is our only source of addressing information and we don't
5773                  * ever receive one, then time out IPv6.  But if there is other
5774                  * IPv6 configuration, like manual IPv6 addresses or external IPv6
5775                  * config, consider that sufficient for IPv6 success.
5776                  */
5777                 if (   priv->ip6_config
5778                     && nm_ip6_config_get_address_first_nontentative (priv->ip6_config, FALSE))
5779                         nm_device_activate_schedule_ip6_config_result (self);
5780                 else
5781                         nm_device_activate_schedule_ip6_config_timeout (self);
5782         }
5783 }
5784
5785 static gboolean
5786 addrconf6_start_with_link_ready (NMDevice *self)
5787 {
5788         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5789         NMUtilsIPv6IfaceId iid;
5790
5791         g_assert (priv->rdisc);
5792
5793         if (nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &iid)) {
5794                 _LOGD (LOGD_IP6, "addrconf6: IPv6 tokenized identifier present");
5795                 nm_rdisc_set_iid (priv->rdisc, iid);
5796         } else if (nm_device_get_ip_iface_identifier (self, &iid)) {
5797                 _LOGD (LOGD_IP6, "addrconf6: using the device EUI-64 identifier");
5798                 nm_rdisc_set_iid (priv->rdisc, iid);
5799         } else {
5800                 /* Don't abort the addrconf at this point -- if rdisc needs the iid
5801                  * it will notice this itself. */
5802                 _LOGI (LOGD_IP6, "addrconf6: no interface identifier; IPv6 adddress creation may fail");
5803         }
5804
5805         /* Apply any manual configuration before starting RA */
5806         if (!ip6_config_merge_and_apply (self, TRUE, NULL))
5807                 _LOGW (LOGD_IP6, "failed to apply manual IPv6 configuration");
5808
5809         nm_device_ipv6_sysctl_set (self, "accept_ra", "1");
5810         nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0");
5811         nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0");
5812         nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0");
5813
5814         priv->rdisc_changed_id = g_signal_connect (priv->rdisc,
5815                                                    NM_RDISC_CONFIG_CHANGED,
5816                                                    G_CALLBACK (rdisc_config_changed),
5817                                                    self);
5818         priv->rdisc_timeout_id = g_signal_connect (priv->rdisc,
5819                                                    NM_RDISC_RA_TIMEOUT,
5820                                                    G_CALLBACK (rdisc_ra_timeout),
5821                                                    self);
5822
5823         nm_rdisc_start (priv->rdisc);
5824         return TRUE;
5825 }
5826
5827 static gboolean
5828 addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
5829 {
5830         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5831         NMConnection *connection;
5832         NMActStageReturn ret;
5833         NMSettingIP6Config *s_ip6 = NULL;
5834         GError *error = NULL;
5835
5836         connection = nm_device_get_applied_connection (self);
5837         g_assert (connection);
5838
5839         g_warn_if_fail (priv->ac_ip6_config == NULL);
5840         if (priv->ac_ip6_config) {
5841                 g_object_unref (priv->ac_ip6_config);
5842                 priv->ac_ip6_config = NULL;
5843         }
5844
5845         s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection));
5846         g_assert (s_ip6);
5847
5848         priv->rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET,
5849                                          nm_device_get_ip_ifindex (self),
5850                                          nm_device_get_ip_iface (self),
5851                                          nm_connection_get_uuid (connection),
5852                                          nm_setting_ip6_config_get_addr_gen_mode (s_ip6),
5853                                          &error);
5854         if (!priv->rdisc) {
5855                 _LOGE (LOGD_IP6, "addrconf6: failed to start router discovery: %s", error->message);
5856                 g_error_free (error);
5857                 return FALSE;
5858         }
5859
5860         priv->rdisc_use_tempaddr = use_tempaddr;
5861
5862         if (   NM_IN_SET (use_tempaddr, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)
5863             && !nm_platform_check_support_kernel_extended_ifa_flags (NM_PLATFORM_GET)) {
5864                 _LOGW (LOGD_IP6, "The kernel does not support extended IFA_FLAGS needed by NM for "
5865                                  "IPv6 private addresses. This feature is not available");
5866         }
5867
5868         if (!nm_setting_ip_config_get_may_fail (nm_connection_get_setting_ip6_config (connection)))
5869                 nm_device_add_pending_action (self, PENDING_ACTION_AUTOCONF6, TRUE);
5870
5871         /* ensure link local is ready... */
5872         ret = linklocal6_start (self);
5873         if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
5874                 /* success; wait for the LL address to show up */
5875                 return TRUE;
5876         }
5877
5878         /* success; already have the LL address; kick off router discovery */
5879         g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS || ret == NM_ACT_STAGE_RETURN_FINISH);
5880         return addrconf6_start_with_link_ready (self);
5881 }
5882
5883 static void
5884 addrconf6_cleanup (NMDevice *self)
5885 {
5886         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5887
5888         nm_clear_g_signal_handler (priv->rdisc, &priv->rdisc_changed_id);
5889         nm_clear_g_signal_handler (priv->rdisc, &priv->rdisc_timeout_id);
5890
5891         nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE);
5892
5893         g_clear_object (&priv->ac_ip6_config);
5894         g_clear_object (&priv->rdisc);
5895 }
5896
5897 /******************************************/
5898
5899 static const char *ip6_properties_to_save[] = {
5900         "accept_ra",
5901         "accept_ra_defrtr",
5902         "accept_ra_pinfo",
5903         "accept_ra_rtr_pref",
5904         "disable_ipv6",
5905         "hop_limit",
5906         "use_tempaddr",
5907 };
5908
5909 static void
5910 save_ip6_properties (NMDevice *self)
5911 {
5912         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5913         const char *ifname = nm_device_get_ip_iface (self);
5914         char *value;
5915         int i;
5916
5917         g_hash_table_remove_all (priv->ip6_saved_properties);
5918
5919         for (i = 0; i < G_N_ELEMENTS (ip6_properties_to_save); i++) {
5920                 value = nm_platform_sysctl_get (NM_PLATFORM_GET, nm_utils_ip6_property_path (ifname, ip6_properties_to_save[i]));
5921                 if (value) {
5922                         g_hash_table_insert (priv->ip6_saved_properties,
5923                                              (char *) ip6_properties_to_save[i],
5924                                              value);
5925                 }
5926         }
5927 }
5928
5929 static void
5930 restore_ip6_properties (NMDevice *self)
5931 {
5932         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5933         GHashTableIter iter;
5934         gpointer key, value;
5935
5936         g_hash_table_iter_init (&iter, priv->ip6_saved_properties);
5937         while (g_hash_table_iter_next (&iter, &key, &value)) {
5938                 /* Don't touch "disable_ipv6" if we're doing userland IPv6LL */
5939                 if (priv->nm_ipv6ll && strcmp (key, "disable_ipv6") == 0)
5940                         continue;
5941                 nm_device_ipv6_sysctl_set (self, key, value);
5942         }
5943 }
5944
5945 static inline void
5946 set_disable_ipv6 (NMDevice *self, const char *value)
5947 {
5948         /* We only touch disable_ipv6 when NM is not managing the IPv6LL address */
5949         if (NM_DEVICE_GET_PRIVATE (self)->nm_ipv6ll == FALSE)
5950                 nm_device_ipv6_sysctl_set (self, "disable_ipv6", value);
5951 }
5952
5953 static inline void
5954 set_nm_ipv6ll (NMDevice *self, gboolean enable)
5955 {
5956         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5957         int ifindex = nm_device_get_ip_ifindex (self);
5958         char *value;
5959
5960         if (!nm_platform_check_support_user_ipv6ll (NM_PLATFORM_GET))
5961                 return;
5962
5963         priv->nm_ipv6ll = enable;
5964         if (ifindex > 0) {
5965                 const char *detail = enable ? "enable" : "disable";
5966
5967                 _LOGD (LOGD_IP6, "will %s userland IPv6LL", detail);
5968                 if (!nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, ifindex, enable))
5969                         _LOGW (LOGD_IP6, "failed to %s userspace IPv6LL address handling", detail);
5970
5971                 if (enable) {
5972                         /* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */
5973                         value = nm_platform_sysctl_get (NM_PLATFORM_GET,
5974                                                         nm_utils_ip6_property_path (nm_device_get_ip_iface (self), "disable_ipv6"));
5975                         if (g_strcmp0 (value, "0") == 0)
5976                                 nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1");
5977                         g_free (value);
5978
5979                         /* Ensure IPv6 is enabled */
5980                         nm_device_ipv6_sysctl_set (self, "disable_ipv6", "0");
5981                 }
5982
5983         }
5984 }
5985
5986 /************************************************************************/
5987
5988 static NMSettingIP6ConfigPrivacy
5989 _ip6_privacy_clamp (NMSettingIP6ConfigPrivacy use_tempaddr)
5990 {
5991         switch (use_tempaddr) {
5992         case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
5993         case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR:
5994         case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR:
5995                 return use_tempaddr;
5996         default:
5997                 return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
5998         }
5999 }
6000
6001 static NMSettingIP6ConfigPrivacy
6002 _ip6_privacy_get (NMDevice *self)
6003 {
6004         NMSettingIP6ConfigPrivacy ip6_privacy;
6005         gs_free char *value = NULL;
6006         NMConnection *connection;
6007
6008         g_return_val_if_fail (self, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
6009
6010         /* 1.) First look at the per-connection setting. If it is not -1 (unknown),
6011          * use it. */
6012         connection = nm_device_get_applied_connection (self);
6013         if (connection) {
6014                 NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection);
6015
6016                 if (s_ip6) {
6017                         ip6_privacy = nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6));
6018                         ip6_privacy = _ip6_privacy_clamp (ip6_privacy);
6019                         if (ip6_privacy != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)
6020                                 return ip6_privacy;
6021                 }
6022         }
6023
6024         value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
6025                                                        "ipv6.ip6-privacy", self);
6026
6027         /* 2.) use the default value from the configuration. */
6028         ip6_privacy = _nm_utils_ascii_str_to_int64 (value, 10,
6029                                                     NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
6030                                                     NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
6031                                                     NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
6032         if (ip6_privacy != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)
6033                 return ip6_privacy;
6034
6035         /* 3.) No valid default-value configured. Fallback to reading sysctl.
6036          *
6037          * Instead of reading static config files in /etc, just read the current sysctl value.
6038          * This works as NM only writes to "/proc/sys/net/ipv6/conf/IFNAME/use_tempaddr", but leaves
6039          * the "default" entry untouched. */
6040         ip6_privacy = nm_platform_sysctl_get_int32 (NM_PLATFORM_GET, "/proc/sys/net/ipv6/conf/default/use_tempaddr", NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
6041         return _ip6_privacy_clamp (ip6_privacy);
6042 }
6043
6044 /****************************************************************/
6045
6046 static gboolean
6047 ip6_requires_slaves (NMConnection *connection)
6048 {
6049         const char *method;
6050
6051         method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
6052
6053         /* SLAAC, DHCP, and Link-Local depend on connectivity (and thus slaves)
6054          * to complete addressing.  SLAAC and DHCP obviously need a peer to
6055          * provide a prefix, while Link-Local must perform DAD on the local link.
6056          */
6057         return    strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0
6058                || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0
6059                || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0;
6060 }
6061
6062 static NMActStageReturn
6063 act_stage3_ip6_config_start (NMDevice *self,
6064                              NMIP6Config **out_config,
6065                              NMDeviceStateReason *reason)
6066 {
6067         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6068         NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
6069         NMConnection *connection;
6070         const char *method;
6071         NMSettingIP6ConfigPrivacy ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
6072         const char *ip6_privacy_str = "0\n";
6073         GSList *slaves;
6074         gboolean ready_slaves;
6075
6076         g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
6077
6078         connection = nm_device_get_applied_connection (self);
6079         g_assert (connection);
6080
6081         if (   connection_ip6_method_requires_carrier (connection, NULL)
6082             && priv->is_master
6083             && !priv->carrier) {
6084                 _LOGI (LOGD_IP6 | LOGD_DEVICE,
6085                        "IPv6 config waiting until carrier is on");
6086                 return NM_ACT_STAGE_RETURN_WAIT;
6087         }
6088
6089         if (priv->is_master && ip6_requires_slaves (connection)) {
6090                 /* If the master has no ready slaves, and depends on slaves for
6091                  * a successful IPv6 attempt, then postpone IPv6 addressing.
6092                  */
6093                 slaves = nm_device_master_get_slaves (self);
6094                 ready_slaves = NM_DEVICE_GET_CLASS (self)->have_any_ready_slaves (self, slaves);
6095                 g_slist_free (slaves);
6096
6097                 if (ready_slaves == FALSE) {
6098                         _LOGI (LOGD_DEVICE | LOGD_IP6,
6099                                "IPv6 config waiting until slaves are ready");
6100                         return NM_ACT_STAGE_RETURN_WAIT;
6101                 }
6102         }
6103
6104         priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE;
6105
6106         method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
6107
6108         if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) {
6109                 if (!priv->master) {
6110                         gboolean old_nm_ipv6ll = priv->nm_ipv6ll;
6111
6112                         /* When activating an IPv6 'ignore' connection we need to revert back
6113                          * to kernel IPv6LL, but the kernel won't actually assign an address
6114                          * to the interface until disable_ipv6 is bounced.
6115                          */
6116                         set_nm_ipv6ll (self, FALSE);
6117                         if (old_nm_ipv6ll == TRUE)
6118                                 nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1");
6119                         restore_ip6_properties (self);
6120                 }
6121                 return NM_ACT_STAGE_RETURN_STOP;
6122         }
6123
6124         /* Ensure the MTU makes sense. If it was below 1280 the kernel would not
6125          * expose any ipv6 sysctls or allow presence of any addresses on the interface,
6126          * including LL, which * would make it impossible to autoconfigure MTU to a
6127          * correct value. */
6128         if (!nm_device_uses_assumed_connection (self))
6129                 nm_device_ipv6_set_mtu (self, priv->ip6_mtu);
6130
6131         /* Any method past this point requires an IPv6LL address. Use NM-controlled
6132          * IPv6LL if this is not an assumed connection, since assumed connections
6133          * will already have IPv6 set up.
6134          */
6135         if (!nm_device_uses_assumed_connection (self))
6136                 set_nm_ipv6ll (self, TRUE);
6137
6138         /* Re-enable IPv6 on the interface */
6139         set_disable_ipv6 (self, "0");
6140
6141         ip6_privacy = _ip6_privacy_get (self);
6142
6143         if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
6144                 if (!addrconf6_start (self, ip6_privacy)) {
6145                         /* IPv6 might be disabled; allow IPv4 to proceed */
6146                         ret = NM_ACT_STAGE_RETURN_STOP;
6147                 } else
6148                         ret = NM_ACT_STAGE_RETURN_POSTPONE;
6149         } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) {
6150                 ret = linklocal6_start (self);
6151         } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) {
6152                 priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_MANAGED;
6153                 if (!dhcp6_start (self, TRUE, reason)) {
6154                         /* IPv6 might be disabled; allow IPv4 to proceed */
6155                         ret = NM_ACT_STAGE_RETURN_STOP;
6156                 } else
6157                         ret = NM_ACT_STAGE_RETURN_POSTPONE;
6158         } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0) {
6159                 /* New blank config */
6160                 *out_config = nm_ip6_config_new (nm_device_get_ip_ifindex (self));
6161                 g_assert (*out_config);
6162
6163                 ret = NM_ACT_STAGE_RETURN_SUCCESS;
6164         } else
6165                 _LOGW (LOGD_IP6, "unhandled IPv6 config method '%s'; will fail", method);
6166
6167         /* Other methods (shared) aren't implemented yet */
6168
6169         switch (ip6_privacy) {
6170         case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN:
6171         case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
6172                 ip6_privacy_str = "0";
6173         break;
6174         case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR:
6175                 ip6_privacy_str = "1";
6176         break;
6177         case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR:
6178                 ip6_privacy_str = "2";
6179         break;
6180         }
6181         nm_device_ipv6_sysctl_set (self, "use_tempaddr", ip6_privacy_str);
6182
6183         return ret;
6184 }
6185
6186 /**
6187  * nm_device_activate_stage3_ip4_start:
6188  * @self: the device
6189  *
6190  * Try starting IPv4 configuration.
6191  */
6192 gboolean
6193 nm_device_activate_stage3_ip4_start (NMDevice *self)
6194 {
6195         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6196         NMActStageReturn ret;
6197         NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
6198         NMIP4Config *ip4_config = NULL;
6199
6200         g_assert (priv->ip4_state == IP_WAIT);
6201
6202         priv->ip4_state = IP_CONF;
6203         ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip4_config_start (self, &ip4_config, &reason);
6204         if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
6205                 g_assert (ip4_config);
6206                 nm_device_activate_schedule_ip4_config_result (self, ip4_config);
6207                 g_object_unref (ip4_config);
6208         } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
6209                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
6210                 return FALSE;
6211         } else if (ret == NM_ACT_STAGE_RETURN_STOP) {
6212                 /* Early finish */
6213                 priv->ip4_state = IP_FAIL;
6214         } else if (ret == NM_ACT_STAGE_RETURN_WAIT) {
6215                 /* Wait for something to try IP config again */
6216                 priv->ip4_state = IP_WAIT;
6217         } else
6218                 g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE);
6219
6220         return TRUE;
6221 }
6222
6223 /**
6224  * nm_device_activate_stage3_ip6_start:
6225  * @self: the device
6226  *
6227  * Try starting IPv6 configuration.
6228  */
6229 gboolean
6230 nm_device_activate_stage3_ip6_start (NMDevice *self)
6231 {
6232         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6233         NMActStageReturn ret;
6234         NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
6235         NMIP6Config *ip6_config = NULL;
6236
6237         g_assert (priv->ip6_state == IP_WAIT);
6238
6239         priv->ip6_state = IP_CONF;
6240         ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip6_config_start (self, &ip6_config, &reason);
6241         if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
6242                 g_assert (ip6_config);
6243                 /* Here we get a static IPv6 config, like for Shared where it's
6244                  * autogenerated or from modems where it comes from ModemManager.
6245                  */
6246                 g_warn_if_fail (priv->ac_ip6_config == NULL);
6247                 priv->ac_ip6_config = ip6_config;
6248                 nm_device_activate_schedule_ip6_config_result (self);
6249         } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
6250                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
6251                 return FALSE;
6252         } else if (ret == NM_ACT_STAGE_RETURN_STOP) {
6253                 /* Activation not wanted */
6254                 priv->ip6_state = IP_FAIL;
6255         } else if (ret == NM_ACT_STAGE_RETURN_FINISH) {
6256                 /* Early finish, nothing more to do */
6257                 priv->ip6_state = IP_DONE;
6258                 check_ip_done (self);
6259         } else if (ret == NM_ACT_STAGE_RETURN_WAIT) {
6260                 /* Wait for something to try IP config again */
6261                 priv->ip6_state = IP_WAIT;
6262         } else
6263                 g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE);
6264
6265         return TRUE;
6266 }
6267
6268 /*
6269  * activate_stage3_ip_config_start
6270  *
6271  * Begin automatic/manual IP configuration
6272  *
6273  */
6274 static void
6275 activate_stage3_ip_config_start (NMDevice *self)
6276 {
6277         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6278         NMActiveConnection *master;
6279         NMDevice *master_device;
6280
6281         priv->ip4_state = priv->ip6_state = IP_WAIT;
6282
6283         nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE);
6284
6285         /* Device should be up before we can do anything with it */
6286         if (!nm_platform_link_is_up (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self)))
6287                 _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
6288
6289         /* If the device is a slave, then we don't do any IP configuration but we
6290          * use the IP config stage to indicate to the master we're ready for
6291          * enslavement.  If the master is already activating, it will have tried to
6292          * enslave us when we changed state to IP_CONFIG, causing us to queue a
6293          * transition to SECONDARIES (or FAILED if the enslavement failed), with
6294          * our IP states set to IP_DONE either way.  If the master isn't yet
6295          * activating, then they'll still be in IP_WAIT.  Either way, we bail out
6296          * of IP config here.
6297          */
6298         master = nm_active_connection_get_master (NM_ACTIVE_CONNECTION (priv->act_request));
6299         if (master) {
6300                 master_device = nm_active_connection_get_device (master);
6301                 if (priv->ip4_state == IP_WAIT && priv->ip6_state == IP_WAIT) {
6302                         _LOGI (LOGD_DEVICE, "Activation: connection '%s' waiting on master '%s'",
6303                                nm_connection_get_id (nm_device_get_applied_connection (self)),
6304                                master_device ? nm_device_get_iface (master_device) : "(unknown)");
6305                 }
6306                 return;
6307         }
6308
6309         /* IPv4 */
6310         if (   nm_device_activate_ip4_state_in_wait (self)
6311             && !nm_device_activate_stage3_ip4_start (self))
6312                 return;
6313
6314         /* IPv6 */
6315         if (   nm_device_activate_ip6_state_in_wait (self)
6316             && !nm_device_activate_stage3_ip6_start (self))
6317                 return;
6318
6319         check_ip_failed (self, TRUE);
6320 }
6321
6322 static gboolean
6323 fw_change_zone_handle (NMDevice *self,
6324                        NMFirewallManagerCallId call_id,
6325                        GError *error)
6326 {
6327         NMDevicePrivate *priv;
6328
6329         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
6330
6331         priv = NM_DEVICE_GET_PRIVATE (self);
6332
6333         g_return_val_if_fail (priv->fw_call == call_id, FALSE);
6334         priv->fw_call = NULL;
6335
6336         return !nm_utils_error_is_cancelled (error, FALSE);
6337 }
6338
6339 static void
6340 fw_change_zone_cb_stage2 (NMFirewallManager *firewall_manager,
6341                           NMFirewallManagerCallId call_id,
6342                           GError *error,
6343                           gpointer user_data)
6344 {
6345         NMDevice *self = user_data;
6346         NMDevicePrivate *priv;
6347
6348         if (!fw_change_zone_handle (self, call_id, error))
6349                 return;
6350
6351         /* FIXME: fail the device on error? */
6352
6353         priv = NM_DEVICE_GET_PRIVATE (self);
6354         priv->fw_ready = TRUE;
6355
6356         nm_device_activate_schedule_stage3_ip_config_start (self);
6357 }
6358
6359 static void
6360 fw_change_zone_cb_ip_check (NMFirewallManager *firewall_manager,
6361                             NMFirewallManagerCallId call_id,
6362                             GError *error,
6363                             gpointer user_data)
6364 {
6365         NMDevice *self = user_data;
6366
6367         if (!fw_change_zone_handle (self, call_id, error))
6368                 return;
6369
6370         /* FIXME: fail the device on error? */
6371         nm_device_start_ip_check (self);
6372 }
6373
6374 /*
6375  * nm_device_activate_schedule_stage3_ip_config_start
6376  *
6377  * Schedule IP configuration start
6378  */
6379 void
6380 nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self)
6381 {
6382         NMDevicePrivate *priv;
6383         NMConnection *connection;
6384         NMSettingConnection *s_con = NULL;
6385         const char *zone;
6386
6387         g_return_if_fail (NM_IS_DEVICE (self));
6388
6389         priv = NM_DEVICE_GET_PRIVATE (self);
6390         g_return_if_fail (priv->act_request);
6391
6392         /* Add the interface to the specified firewall zone */
6393         connection = nm_device_get_applied_connection (self);
6394         g_assert (connection);
6395         s_con = nm_connection_get_setting_connection (connection);
6396
6397         if (!priv->fw_ready) {
6398                 if (nm_device_uses_assumed_connection (self))
6399                         priv->fw_ready = TRUE;
6400                 else {
6401                         if (!priv->fw_call) {
6402                                 zone = nm_setting_connection_get_zone (s_con);
6403
6404                                 _LOGD (LOGD_DEVICE, "Activation: setting firewall zone '%s'", zone ? zone : "default");
6405                                 priv->fw_call = nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
6406                                                                                         nm_device_get_ip_iface (self),
6407                                                                                         zone,
6408                                                                                         FALSE,
6409                                                                                         fw_change_zone_cb_stage2,
6410                                                                                         self);
6411                         }
6412                         return;
6413                 }
6414         }
6415
6416         activation_source_schedule (self, activate_stage3_ip_config_start, AF_INET);
6417 }
6418
6419 static NMActStageReturn
6420 act_stage4_ip4_config_timeout (NMDevice *self, NMDeviceStateReason *reason)
6421 {
6422         if (!get_ip_config_may_fail (self, AF_INET)) {
6423                 *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
6424                 return NM_ACT_STAGE_RETURN_FAILURE;
6425         }
6426         return NM_ACT_STAGE_RETURN_SUCCESS;
6427 }
6428
6429
6430 /*
6431  * nm_device_activate_stage4_ip4_config_timeout
6432  *
6433  * Time out on retrieving the IPv4 config.
6434  *
6435  */
6436 static void
6437 activate_stage4_ip4_config_timeout (NMDevice *self)
6438 {
6439         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6440         NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
6441         NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
6442
6443         ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip4_config_timeout (self, &reason);
6444         if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
6445                 return;
6446         else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
6447                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
6448                 return;
6449         }
6450         g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
6451
6452         priv->ip4_state = IP_FAIL;
6453
6454         check_ip_failed (self, FALSE);
6455 }
6456
6457
6458 /*
6459  * nm_device_activate_schedule_ip4_config_timeout
6460  *
6461  * Deal with a timeout of the IPv4 configuration
6462  *
6463  */
6464 void
6465 nm_device_activate_schedule_ip4_config_timeout (NMDevice *self)
6466 {
6467         NMDevicePrivate *priv;
6468
6469         g_return_if_fail (NM_IS_DEVICE (self));
6470
6471         priv = NM_DEVICE_GET_PRIVATE (self);
6472         g_return_if_fail (priv->act_request);
6473
6474         activation_source_schedule (self, activate_stage4_ip4_config_timeout, AF_INET);
6475 }
6476
6477
6478 static NMActStageReturn
6479 act_stage4_ip6_config_timeout (NMDevice *self, NMDeviceStateReason *reason)
6480 {
6481         if (!get_ip_config_may_fail (self, AF_INET6)) {
6482                 *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
6483                 return NM_ACT_STAGE_RETURN_FAILURE;
6484         }
6485
6486         return NM_ACT_STAGE_RETURN_SUCCESS;
6487 }
6488
6489
6490 /*
6491  * activate_stage4_ip6_config_timeout
6492  *
6493  * Time out on retrieving the IPv6 config.
6494  *
6495  */
6496 static void
6497 activate_stage4_ip6_config_timeout (NMDevice *self)
6498 {
6499         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6500         NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
6501         NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
6502
6503         ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip6_config_timeout (self, &reason);
6504         if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
6505                 return;
6506         if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
6507                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
6508                 return;
6509         }
6510         g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
6511
6512         priv->ip6_state = IP_FAIL;
6513
6514         check_ip_failed (self, FALSE);
6515 }
6516
6517
6518 /*
6519  * nm_device_activate_schedule_ip6_config_timeout
6520  *
6521  * Deal with a timeout of the IPv6 configuration
6522  *
6523  */
6524 void
6525 nm_device_activate_schedule_ip6_config_timeout (NMDevice *self)
6526 {
6527         NMDevicePrivate *priv;
6528
6529         g_return_if_fail (NM_IS_DEVICE (self));
6530
6531         priv = NM_DEVICE_GET_PRIVATE (self);
6532         g_return_if_fail (priv->act_request);
6533
6534         activation_source_schedule (self, activate_stage4_ip6_config_timeout, AF_INET6);
6535 }
6536
6537 static gboolean
6538 share_init (void)
6539 {
6540         char *modules[] = { "ip_tables", "iptable_nat", "nf_nat_ftp", "nf_nat_irc",
6541                             "nf_nat_sip", "nf_nat_tftp", "nf_nat_pptp", "nf_nat_h323",
6542                             NULL };
6543         char **iter;
6544         int errsv;
6545
6546         if (!nm_platform_sysctl_set (NM_PLATFORM_GET, "/proc/sys/net/ipv4/ip_forward", "1")) {
6547                 errsv = errno;
6548                 nm_log_err (LOGD_SHARING, "share: error starting IP forwarding: (%d) %s",
6549                             errsv, strerror (errsv));
6550                 return FALSE;
6551         }
6552
6553         if (!nm_platform_sysctl_set (NM_PLATFORM_GET, "/proc/sys/net/ipv4/ip_dynaddr", "1")) {
6554                 errsv = errno;
6555                 nm_log_err (LOGD_SHARING, "share: error starting IP forwarding: (%d) %s",
6556                             errsv, strerror (errsv));
6557         }
6558
6559         for (iter = modules; *iter; iter++)
6560                 nm_utils_modprobe (NULL, FALSE, *iter, NULL);
6561
6562         return TRUE;
6563 }
6564
6565 static void
6566 add_share_rule (NMActRequest *req, const char *table, const char *fmt, ...)
6567 {
6568         va_list args;
6569         char *cmd;
6570
6571         va_start (args, fmt);
6572         cmd = g_strdup_vprintf (fmt, args);
6573         va_end (args);
6574
6575         nm_act_request_add_share_rule (req, table, cmd);
6576         g_free (cmd);
6577 }
6578
6579 static gboolean
6580 start_sharing (NMDevice *self, NMIP4Config *config)
6581 {
6582         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6583         NMActRequest *req;
6584         GError *error = NULL;
6585         char str_addr[INET_ADDRSTRLEN + 1];
6586         char str_mask[INET_ADDRSTRLEN + 1];
6587         guint32 netmask, network;
6588         const NMPlatformIP4Address *ip4_addr;
6589         const char *ip_iface;
6590
6591         g_return_val_if_fail (config != NULL, FALSE);
6592
6593         ip_iface = nm_device_get_ip_iface (self);
6594
6595         ip4_addr = nm_ip4_config_get_address (config, 0);
6596         if (!ip4_addr || !ip4_addr->address)
6597                 return FALSE;
6598
6599         netmask = nm_utils_ip4_prefix_to_netmask (ip4_addr->plen);
6600         if (!inet_ntop (AF_INET, &netmask, str_mask, sizeof (str_mask)))
6601                 return FALSE;
6602
6603         network = ip4_addr->address & netmask;
6604         if (!inet_ntop (AF_INET, &network, str_addr, sizeof (str_addr)))
6605                 return FALSE;
6606
6607         if (!share_init ())
6608                 return FALSE;
6609
6610         req = nm_device_get_act_request (self);
6611         g_assert (req);
6612
6613         add_share_rule (req, "nat", "POSTROUTING --source %s/%s ! --destination %s/%s --jump MASQUERADE", str_addr, str_mask, str_addr, str_mask);
6614         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);
6615         add_share_rule (req, "filter", "FORWARD --source %s/%s --in-interface %s --jump ACCEPT", str_addr, str_mask, ip_iface);
6616         add_share_rule (req, "filter", "FORWARD --in-interface %s --out-interface %s --jump ACCEPT", ip_iface, ip_iface);
6617         add_share_rule (req, "filter", "FORWARD --out-interface %s --jump REJECT", ip_iface);
6618         add_share_rule (req, "filter", "FORWARD --in-interface %s --jump REJECT", ip_iface);
6619         add_share_rule (req, "filter", "INPUT --in-interface %s --protocol udp --destination-port 67 --jump ACCEPT", ip_iface);
6620         add_share_rule (req, "filter", "INPUT --in-interface %s --protocol tcp --destination-port 67 --jump ACCEPT", ip_iface);
6621         add_share_rule (req, "filter", "INPUT --in-interface %s --protocol udp --destination-port 53 --jump ACCEPT", ip_iface);
6622         add_share_rule (req, "filter", "INPUT --in-interface %s --protocol tcp --destination-port 53 --jump ACCEPT", ip_iface);
6623
6624         nm_act_request_set_shared (req, TRUE);
6625
6626         if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, config, &error)) {
6627                 _LOGE (LOGD_SHARING, "share: (%s) failed to start dnsmasq: %s",
6628                        ip_iface, error->message);
6629                 g_error_free (error);
6630                 nm_act_request_set_shared (req, FALSE);
6631                 return FALSE;
6632         }
6633
6634         priv->dnsmasq_state_id = g_signal_connect (priv->dnsmasq_manager, NM_DNS_MASQ_MANAGER_STATE_CHANGED,
6635                                                    G_CALLBACK (dnsmasq_state_changed_cb),
6636                                                    self);
6637         return TRUE;
6638 }
6639
6640 static void
6641 arp_cleanup (NMDevice *self)
6642 {
6643         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6644
6645         if (priv->arping.announcing) {
6646                 nm_arping_manager_destroy (priv->arping.announcing);
6647                 priv->arping.announcing = NULL;
6648         }
6649 }
6650
6651 static void
6652 arp_announce (NMDevice *self)
6653 {
6654         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6655         NMConnection *connection;
6656         NMSettingIPConfig *s_ip4;
6657         guint num, i;
6658         const guint8 *hw_addr;
6659         size_t hw_addr_len = 0;
6660
6661         arp_cleanup (self);
6662
6663         hw_addr = nm_platform_link_get_address (NM_PLATFORM_GET,
6664                                                 nm_device_get_ip_ifindex (self),
6665                                                 &hw_addr_len);
6666
6667         if (!hw_addr_len || !hw_addr)
6668                 return;
6669
6670         /* We only care about manually-configured addresses; DHCP- and autoip-configured
6671          * ones should already have been seen on the network at this point.
6672          */
6673         connection = nm_device_get_applied_connection (self);
6674         if (!connection)
6675                 return;
6676         s_ip4 = nm_connection_get_setting_ip4_config (connection);
6677         if (!s_ip4)
6678                 return;
6679         num = nm_setting_ip_config_get_num_addresses (s_ip4);
6680         if (num == 0)
6681                 return;
6682
6683         priv->arping.announcing = nm_arping_manager_new (nm_device_get_ip_ifindex (self));
6684
6685         for (i = 0; i < num; i++) {
6686                 NMIPAddress *ip = nm_setting_ip_config_get_address (s_ip4, i);
6687                 in_addr_t addr;
6688
6689                 if (inet_pton (AF_INET, nm_ip_address_get_address (ip), &addr) == 1)
6690                         nm_arping_manager_add_address (priv->arping.announcing, addr);
6691                 else
6692                         g_warn_if_reached ();
6693         }
6694
6695         nm_arping_manager_announce_addresses (priv->arping.announcing);
6696 }
6697
6698 static void
6699 activate_stage5_ip4_config_commit (NMDevice *self)
6700 {
6701         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6702         NMActRequest *req;
6703         const char *method;
6704         NMConnection *connection;
6705         NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
6706         int ip_ifindex;
6707
6708         req = nm_device_get_act_request (self);
6709         g_assert (req);
6710         connection = nm_act_request_get_applied_connection (req);
6711         g_assert (connection);
6712
6713         /* Interface must be IFF_UP before IP config can be applied */
6714         ip_ifindex = nm_device_get_ip_ifindex (self);
6715         if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex) && !nm_device_uses_assumed_connection (self)) {
6716                 nm_platform_link_set_up (NM_PLATFORM_GET, ip_ifindex, NULL);
6717                 if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex))
6718                         _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
6719         }
6720
6721         /* NULL to use the existing priv->dev_ip4_config */
6722         if (!ip4_config_merge_and_apply (self, NULL, TRUE, &reason)) {
6723                 _LOGD (LOGD_DEVICE | LOGD_IP4, "Activation: Stage 5 of 5 (IPv4 Commit) failed");
6724                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
6725                 return;
6726         }
6727
6728         /* Start IPv4 sharing if we need it */
6729         method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
6730
6731         if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) {
6732                 if (!start_sharing (self, priv->ip4_config)) {
6733                         _LOGW (LOGD_SHARING, "Activation: Stage 5 of 5 (IPv4 Commit) start sharing failed.");
6734                         nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
6735                         return;
6736                 }
6737         }
6738
6739         /* If IPv4 wasn't the first to complete, and DHCP was used, then ensure
6740          * dispatcher scripts get the DHCP lease information.
6741          */
6742         if (   priv->dhcp4_client
6743             && nm_device_activate_ip4_state_in_conf (self)
6744             && (nm_device_get_state (self) > NM_DEVICE_STATE_IP_CONFIG)) {
6745                 /* Notify dispatcher scripts of new DHCP4 config */
6746                 nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE,
6747                                     nm_device_get_settings_connection (self),
6748                                     nm_device_get_applied_connection (self),
6749                                     self,
6750                                     NULL,
6751                                     NULL,
6752                                     NULL);
6753         }
6754
6755         arp_announce (self);
6756
6757         nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
6758
6759         /* Enter the IP_CHECK state if this is the first method to complete */
6760         priv->ip4_state = IP_DONE;
6761         check_ip_done (self);
6762 }
6763
6764 static void
6765 queued_ip4_config_change_clear (NMDevice *self)
6766 {
6767         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6768
6769         if (priv->queued_ip4_config_id) {
6770                 _LOGD (LOGD_DEVICE, "clearing queued IP4 config change");
6771                 g_source_remove (priv->queued_ip4_config_id);
6772                 priv->queued_ip4_config_id = 0;
6773         }
6774 }
6775
6776 static void
6777 queued_ip6_config_change_clear (NMDevice *self)
6778 {
6779         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6780
6781         if (priv->queued_ip6_config_id) {
6782                 _LOGD (LOGD_DEVICE, "clearing queued IP6 config change");
6783                 g_source_remove (priv->queued_ip6_config_id);
6784                 priv->queued_ip6_config_id = 0;
6785         }
6786 }
6787
6788 void
6789 nm_device_activate_schedule_ip4_config_result (NMDevice *self, NMIP4Config *config)
6790 {
6791         NMDevicePrivate *priv;
6792
6793         g_return_if_fail (NM_IS_DEVICE (self));
6794         priv = NM_DEVICE_GET_PRIVATE (self);
6795
6796         g_clear_object (&priv->dev_ip4_config);
6797         if (config)
6798                 priv->dev_ip4_config = g_object_ref (config);
6799
6800         queued_ip4_config_change_clear (self);
6801         activation_source_schedule (self, activate_stage5_ip4_config_commit, AF_INET);
6802 }
6803
6804 gboolean
6805 nm_device_activate_ip4_state_in_conf (NMDevice *self)
6806 {
6807         g_return_val_if_fail (self != NULL, FALSE);
6808         return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_CONF;
6809 }
6810
6811 gboolean
6812 nm_device_activate_ip4_state_in_wait (NMDevice *self)
6813 {
6814         g_return_val_if_fail (self != NULL, FALSE);
6815         return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT;
6816 }
6817
6818 static void
6819 activate_stage5_ip6_config_commit (NMDevice *self)
6820 {
6821         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6822         NMActRequest *req;
6823         NMConnection *connection;
6824         NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
6825         int ip_ifindex;
6826
6827         req = nm_device_get_act_request (self);
6828         g_assert (req);
6829         connection = nm_act_request_get_applied_connection (req);
6830         g_assert (connection);
6831
6832         /* Interface must be IFF_UP before IP config can be applied */
6833         ip_ifindex = nm_device_get_ip_ifindex (self);
6834         if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex) && !nm_device_uses_assumed_connection (self)) {
6835                 nm_platform_link_set_up (NM_PLATFORM_GET, ip_ifindex, NULL);
6836                 if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex))
6837                         _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
6838         }
6839
6840         if (ip6_config_merge_and_apply (self, TRUE, &reason)) {
6841                 if (   priv->dhcp6_mode != NM_RDISC_DHCP_LEVEL_NONE
6842                     && priv->ip6_state == IP_CONF) {
6843                         if (priv->dhcp6_ip6_config) {
6844                                 /* If IPv6 wasn't the first IP to complete, and DHCP was used,
6845                                  * then ensure dispatcher scripts get the DHCP lease information.
6846                                  */
6847                                 nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE,
6848                                                     nm_device_get_settings_connection (self),
6849                                                     nm_device_get_applied_connection (self),
6850                                                     self,
6851                                                     NULL,
6852                                                     NULL,
6853                                                     NULL);
6854                         } else {
6855                                 /* still waiting for first dhcp6 lease. */
6856                                 return;
6857                         }
6858                 }
6859
6860                 nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
6861                 nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE);
6862
6863                 /* Enter the IP_CHECK state if this is the first method to complete */
6864                 priv->ip6_state = IP_DONE;
6865                 check_ip_done (self);
6866         } else {
6867                 _LOGW (LOGD_DEVICE | LOGD_IP6, "Activation: Stage 5 of 5 (IPv6 Commit) failed");
6868                 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
6869         }
6870 }
6871
6872 void
6873 nm_device_activate_schedule_ip6_config_result (NMDevice *self)
6874 {
6875         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6876
6877         g_return_if_fail (NM_IS_DEVICE (self));
6878
6879         /* If IP had previously failed, move it back to IP_CONF since we
6880          * clearly now have configuration.
6881          */
6882         if (priv->ip6_state == IP_FAIL)
6883                 priv->ip6_state = IP_CONF;
6884
6885         activation_source_schedule (self, activate_stage5_ip6_config_commit, AF_INET6);
6886 }
6887
6888 gboolean
6889 nm_device_activate_ip6_state_in_conf (NMDevice *self)
6890 {
6891         g_return_val_if_fail (self != NULL, FALSE);
6892         return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_CONF;
6893 }
6894
6895 gboolean
6896 nm_device_activate_ip6_state_in_wait (NMDevice *self)
6897 {
6898         g_return_val_if_fail (self != NULL, FALSE);
6899         return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT;
6900 }
6901
6902 static void
6903 clear_act_request (NMDevice *self)
6904 {
6905         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6906
6907         if (!priv->act_request)
6908                 return;
6909
6910         nm_active_connection_set_default (NM_ACTIVE_CONNECTION (priv->act_request), FALSE);
6911
6912         priv->master_ready_handled = FALSE;
6913         nm_clear_g_signal_handler (priv->act_request, &priv->master_ready_id);
6914
6915         g_clear_object (&priv->act_request);
6916         _notify (self, PROP_ACTIVE_CONNECTION);
6917 }
6918
6919 static void
6920 dnsmasq_cleanup (NMDevice *self)
6921 {
6922         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6923
6924         if (!priv->dnsmasq_manager)
6925                 return;
6926
6927         nm_clear_g_signal_handler (priv->dnsmasq_manager, &priv->dnsmasq_state_id);
6928
6929         nm_dnsmasq_manager_stop (priv->dnsmasq_manager);
6930         g_object_unref (priv->dnsmasq_manager);
6931         priv->dnsmasq_manager = NULL;
6932 }
6933
6934 static void
6935 _update_ip4_address (NMDevice *self)
6936 {
6937         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6938         guint32 addr;
6939
6940         g_return_if_fail (NM_IS_DEVICE (self));
6941
6942         if (   priv->ip4_config
6943             && ip_config_valid (priv->state)
6944             && nm_ip4_config_get_num_addresses (priv->ip4_config)) {
6945                 addr = nm_ip4_config_get_address (priv->ip4_config, 0)->address;
6946                 if (addr != priv->ip4_address) {
6947                         priv->ip4_address = addr;
6948                         _notify (self, PROP_IP4_ADDRESS);
6949                 }
6950         }
6951 }
6952
6953 gboolean
6954 nm_device_get_is_nm_owned (NMDevice *self)
6955 {
6956         return NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
6957 }
6958
6959 /*
6960  * delete_on_deactivate_link_delete
6961  *
6962  * Function will be queued with g_idle_add to call
6963  * nm_platform_link_delete for the underlying resources
6964  * of the device.
6965  */
6966 static gboolean
6967 delete_on_deactivate_link_delete (gpointer user_data)
6968 {
6969         DeleteOnDeactivateData *data = user_data;
6970         NMDevice *self = data->device;
6971
6972         _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)",
6973                data->ifindex, data->idle_add_id);
6974
6975         if (data->device) {
6976                 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (data->device);
6977                 gs_free_error GError *error = NULL;
6978
6979                 g_object_remove_weak_pointer (G_OBJECT (data->device), (void **) &data->device);
6980                 priv->delete_on_deactivate_data = NULL;
6981
6982                 if (!nm_device_unrealize (data->device, TRUE, &error))
6983                         _LOGD (LOGD_DEVICE, "delete_on_deactivate: unrealizing %d failed (%s)", data->ifindex, error->message);
6984         } else
6985                 nm_platform_link_delete (NM_PLATFORM_GET, data->ifindex);
6986
6987         g_free (data);
6988         return FALSE;
6989 }
6990
6991 static void
6992 delete_on_deactivate_unschedule (NMDevice *self)
6993 {
6994         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6995
6996         if (priv->delete_on_deactivate_data) {
6997                 DeleteOnDeactivateData *data = priv->delete_on_deactivate_data;
6998
6999                 priv->delete_on_deactivate_data = NULL;
7000
7001                 g_source_remove (data->idle_add_id);
7002                 g_object_remove_weak_pointer (G_OBJECT (self), (void **) &data->device);
7003                 _LOGD (LOGD_DEVICE, "delete_on_deactivate: cancel cleanup and delete virtual link #%d (id=%u)",
7004                        data->ifindex, data->idle_add_id);
7005                 g_free (data);
7006         }
7007 }
7008
7009 static void
7010 delete_on_deactivate_check_and_schedule (NMDevice *self, int ifindex)
7011 {
7012         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7013         DeleteOnDeactivateData *data;
7014
7015         if (ifindex <= 0)
7016                 return;
7017         if (!priv->is_nm_owned)
7018                 return;
7019         if (priv->queued_act_request)
7020                 return;
7021         if (!nm_device_is_software (self) || !nm_device_is_real (self))
7022                 return;
7023         if (nm_device_get_state (self) == NM_DEVICE_STATE_UNMANAGED)
7024                 return;
7025         if (nm_device_get_state (self) == NM_DEVICE_STATE_UNAVAILABLE)
7026                 return;
7027         delete_on_deactivate_unschedule (self); /* always cancel and reschedule */
7028
7029         data = g_new (DeleteOnDeactivateData, 1);
7030         g_object_add_weak_pointer (G_OBJECT (self), (void **) &data->device);
7031         data->device = self;
7032         data->ifindex = ifindex;
7033         data->idle_add_id = g_idle_add (delete_on_deactivate_link_delete, data);
7034         priv->delete_on_deactivate_data = data;
7035
7036         _LOGD (LOGD_DEVICE, "delete_on_deactivate: schedule cleanup and delete virtual link #%d (id=%u)",
7037                ifindex, data->idle_add_id);
7038 }
7039
7040 static void
7041 _cleanup_ip4_pre (NMDevice *self, CleanupType cleanup_type)
7042 {
7043         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7044
7045         priv->ip4_state =  IP_NONE;
7046         queued_ip4_config_change_clear (self);
7047
7048         dhcp4_cleanup (self, cleanup_type, FALSE);
7049         arp_cleanup (self);
7050         dnsmasq_cleanup (self);
7051         ipv4ll_cleanup (self);
7052 }
7053
7054 static void
7055 _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type)
7056 {
7057         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7058
7059         priv->ip6_state = IP_NONE;
7060         queued_ip6_config_change_clear (self);
7061
7062         dhcp6_cleanup (self, cleanup_type, FALSE);
7063         linklocal6_cleanup (self);
7064         addrconf6_cleanup (self);
7065 }
7066
7067 static gboolean
7068 _hash_check_invalid_keys_impl (GHashTable *hash, const char *setting_name, GError **error, const char **argv)
7069 {
7070         guint found_keys = 0;
7071         guint i;
7072
7073         nm_assert (argv && argv[0]);
7074
7075 #if NM_MORE_ASSERTS > 10
7076         /* Assert that the keys are unique. */
7077         {
7078                 gs_unref_hashtable GHashTable *check_dups = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
7079
7080                 for (i = 0; argv[i]; i++) {
7081                         if (!g_hash_table_add (check_dups, (char *) argv[i]))
7082                                 nm_assert (FALSE);
7083                 }
7084                 nm_assert (g_hash_table_size (check_dups) > 0);
7085         }
7086 #endif
7087
7088         if (!hash || g_hash_table_size (hash) == 0)
7089                 return TRUE;
7090
7091         for (i = 0; argv[i]; i++) {
7092                 if (g_hash_table_contains (hash, argv[i]))
7093                         found_keys++;
7094         }
7095
7096         if (found_keys != g_hash_table_size (hash)) {
7097                 GHashTableIter iter;
7098                 const char *k = NULL;
7099                 const char *first_invalid_key = NULL;
7100
7101                 if (!error)
7102                         return FALSE;
7103
7104                 g_hash_table_iter_init (&iter, hash);
7105                 while (g_hash_table_iter_next (&iter, (gpointer *) &k, NULL)) {
7106                         for (i = 0; argv[i]; i++) {
7107                                 if (!strcmp (argv[i], k)) {
7108                                         first_invalid_key = k;
7109                                         break;
7110                                 }
7111                         }
7112                         if (first_invalid_key)
7113                                 break;
7114                 }
7115                 g_set_error (error,
7116                              NM_DEVICE_ERROR,
7117                              NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
7118                              "Can't reapply changes to '%s%s%s' setting",
7119                              setting_name ? : "",
7120                              setting_name ? "." : "",
7121                              first_invalid_key ? : "<UNKNOWN>");
7122                 g_return_val_if_fail (first_invalid_key, FALSE);
7123                 return FALSE;
7124         }
7125
7126         return TRUE;
7127 }
7128 #define _hash_check_invalid_keys(hash, setting_name, error, ...) _hash_check_invalid_keys_impl (hash, setting_name, error, ((const char *[]) { __VA_ARGS__, NULL }))
7129
7130 void
7131 nm_device_reactivate_ip4_config (NMDevice *self,
7132                                  NMSettingIPConfig *s_ip4_old,
7133                                  NMSettingIPConfig *s_ip4_new)
7134 {
7135         NMDevicePrivate *priv;
7136
7137         g_return_if_fail (NM_IS_DEVICE (self));
7138         priv = NM_DEVICE_GET_PRIVATE (self);
7139
7140         if (priv->ip4_state != IP_NONE) {
7141                 g_clear_object (&priv->con_ip4_config);
7142                 g_clear_object (&priv->ext_ip4_config);
7143                 priv->con_ip4_config = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
7144                 nm_ip4_config_merge_setting (priv->con_ip4_config,
7145                                              s_ip4_new,
7146                                              nm_device_get_ip4_route_metric (self));
7147
7148                 if (strcmp (nm_setting_ip_config_get_method (s_ip4_new),
7149                             nm_setting_ip_config_get_method (s_ip4_old))) {
7150                         _cleanup_ip4_pre (self, CLEANUP_TYPE_DECONFIGURE);
7151                         priv->ip4_state = IP_WAIT;
7152                         if (!nm_device_activate_stage3_ip4_start (self))
7153                                 _LOGW (LOGD_IP4, "Failed to apply IPv4 configuration");
7154                 } else {
7155                         if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL))
7156                                 _LOGW (LOGD_IP4, "Failed to reapply IPv4 configuration");
7157                 }
7158         }
7159 }
7160
7161 void
7162 nm_device_reactivate_ip6_config (NMDevice *self,
7163                                  NMSettingIPConfig *s_ip6_old,
7164                                  NMSettingIPConfig *s_ip6_new)
7165 {
7166         NMDevicePrivate *priv;
7167
7168         g_return_if_fail (NM_IS_DEVICE (self));
7169         priv = NM_DEVICE_GET_PRIVATE (self);
7170
7171         if (priv->ip6_state != IP_NONE) {
7172                 g_clear_object (&priv->con_ip6_config);
7173                 g_clear_object (&priv->ext_ip6_config);
7174                 priv->con_ip6_config = nm_ip6_config_new (nm_device_get_ip_ifindex (self));
7175                 nm_ip6_config_merge_setting (priv->con_ip6_config,
7176                                              s_ip6_new,
7177                                              nm_device_get_ip6_route_metric (self));
7178
7179                 if (strcmp (nm_setting_ip_config_get_method (s_ip6_new),
7180                             nm_setting_ip_config_get_method (s_ip6_old))) {
7181                         _cleanup_ip6_pre (self, CLEANUP_TYPE_DECONFIGURE);
7182                         priv->ip6_state = IP_WAIT;
7183                         if (!nm_device_activate_stage3_ip6_start (self))
7184                                 _LOGW (LOGD_IP6, "Failed to apply IPv6 configuration");
7185                 } else {
7186                         if (!ip6_config_merge_and_apply (self, TRUE, NULL))
7187                                 _LOGW (LOGD_IP4, "Failed to reapply IPv6 configuration");
7188                 }
7189         }
7190 }
7191
7192
7193 /* reapply_connection:
7194  * @connection: the new connection settings to be applied or %NULL to reapply
7195  *   the current settings connection
7196  * @version_id: either zero, or the current version id for the applied
7197  *   connection.
7198  * @error: the error if %FALSE is returned
7199  *
7200  * Change configuration of an already configured device if possible.
7201  * Updates the device's applied connection upon success.
7202  *
7203  * Return: %FALSE if the new configuration can not be reapplied.
7204  */
7205 static gboolean
7206 reapply_connection (NMDevice *self,
7207                     NMConnection *connection,
7208                     guint64 version_id,
7209                     GError **error)
7210 {
7211         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7212         NMConnection *applied = nm_device_get_applied_connection (self);
7213         gs_unref_object NMConnection *applied_clone = NULL;
7214         gs_unref_hashtable GHashTable *diffs = NULL;
7215         NMConnection *con_old, *con_new;
7216         NMSettingIPConfig *s_ip4_old, *s_ip4_new;
7217         NMSettingIPConfig *s_ip6_old, *s_ip6_new;
7218
7219         if (priv->state != NM_DEVICE_STATE_ACTIVATED) {
7220                 g_set_error_literal (error,
7221                                      NM_DEVICE_ERROR,
7222                                      NM_DEVICE_ERROR_NOT_ACTIVE,
7223                                      "Device is not activated");
7224                 return FALSE;
7225         }
7226
7227         nm_connection_diff (connection,
7228                             applied,
7229                             NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP |
7230                             NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS,
7231                             &diffs);
7232
7233         /**************************************************************************
7234          * check for unsupported changes and reject to reapply
7235          *************************************************************************/
7236         if (!_hash_check_invalid_keys (diffs, NULL, error,
7237                                        NM_SETTING_IP4_CONFIG_SETTING_NAME,
7238                                        NM_SETTING_IP6_CONFIG_SETTING_NAME,
7239                                        NM_SETTING_CONNECTION_SETTING_NAME))
7240                 return FALSE;
7241
7242         if (!_hash_check_invalid_keys (diffs ? g_hash_table_lookup (diffs, NM_SETTING_CONNECTION_SETTING_NAME) : NULL,
7243                                        NM_SETTING_CONNECTION_SETTING_NAME,
7244                                        error,
7245                                        NM_SETTING_CONNECTION_ZONE,
7246                                        NM_SETTING_CONNECTION_METERED))
7247                 return FALSE;
7248
7249         if (   version_id != 0
7250             && version_id != nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request)) {
7251                 g_set_error_literal (error,
7252                                      NM_DEVICE_ERROR,
7253                                      NM_DEVICE_ERROR_VERSION_ID_MISMATCH,
7254                                      "Reapply failed because device changed in the meantime and the version-id mismatches");
7255                 return FALSE;
7256         }
7257
7258         /**************************************************************************
7259          * Update applied connection
7260          *************************************************************************/
7261
7262         if (diffs)
7263                 nm_active_connection_version_id_bump ((NMActiveConnection *) priv->act_request);
7264
7265         _LOGD (LOGD_DEVICE, "reapply (version-id %llu%s)",
7266                (long long unsigned) nm_active_connection_version_id_get (((NMActiveConnection *) priv->act_request)),
7267                diffs ? "" : " (unmodified)");
7268
7269         if (diffs) {
7270                 con_old = applied_clone  = nm_simple_connection_new_clone (applied);
7271                 con_new = applied;
7272                 nm_connection_replace_settings_from_connection (applied, connection);
7273         } else
7274                 con_old = con_new = applied;
7275
7276         s_ip4_new = nm_connection_get_setting_ip4_config (con_new);
7277         s_ip4_old = nm_connection_get_setting_ip4_config (con_old);
7278         s_ip6_new = nm_connection_get_setting_ip6_config (con_new);
7279         s_ip6_old = nm_connection_get_setting_ip6_config (con_old);
7280
7281         /**************************************************************************
7282          * Reapply changes
7283          *************************************************************************/
7284
7285         nm_device_update_firewall_zone (self);
7286         nm_device_update_metered (self);
7287
7288         nm_device_reactivate_ip4_config (self, s_ip4_old, s_ip4_new);
7289         nm_device_reactivate_ip6_config (self, s_ip6_old, s_ip6_new);
7290
7291         return TRUE;
7292 }
7293
7294 typedef struct {
7295         NMConnection *connection;
7296         guint64 version_id;
7297 } ReapplyData;
7298
7299 static void
7300 reapply_cb (NMDevice *self,
7301             GDBusMethodInvocation *context,
7302             NMAuthSubject *subject,
7303             GError *error,
7304             gpointer user_data)
7305 {
7306         ReapplyData *reapply_data = user_data;
7307         guint64 version_id = 0;
7308         gs_unref_object NMConnection *connection = NULL;
7309         GError *local = NULL;
7310
7311         if (reapply_data) {
7312                 connection = reapply_data->connection;
7313                 version_id = reapply_data->version_id;
7314                 g_slice_free (ReapplyData, reapply_data);
7315         }
7316
7317         if (error) {
7318                 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, subject, error->message);
7319                 g_dbus_method_invocation_return_gerror (context, error);
7320                 return;
7321         }
7322
7323         if (!reapply_connection (self,
7324                                  connection ? : (NMConnection *) nm_device_get_settings_connection (self),
7325                                  version_id,
7326                                  &local)) {
7327                 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, subject, local->message);
7328                 g_dbus_method_invocation_take_error (context, local);
7329                 local = NULL;
7330         } else {
7331                 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, TRUE, subject, NULL);
7332                 g_dbus_method_invocation_return_value (context, NULL);
7333         }
7334 }
7335
7336 static void
7337 impl_device_reapply (NMDevice *self,
7338                      GDBusMethodInvocation *context,
7339                      GVariant *settings,
7340                      guint64 version_id,
7341                      guint32 flags)
7342 {
7343         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7344         NMSettingsConnection *settings_connection;
7345         NMConnection *connection = NULL;
7346         GError *error = NULL;
7347         ReapplyData *reapply_data;
7348
7349         /* No flags supported as of now. */
7350         if (flags != 0) {
7351                 error = g_error_new_literal (NM_DEVICE_ERROR,
7352                                              NM_DEVICE_ERROR_FAILED,
7353                                              "Invalid flags specified");
7354                 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message);
7355                 g_dbus_method_invocation_take_error (context, error);
7356                 return;
7357         }
7358
7359         if (priv->state != NM_DEVICE_STATE_ACTIVATED) {
7360                 error = g_error_new_literal (NM_DEVICE_ERROR,
7361                                              NM_DEVICE_ERROR_NOT_ACTIVE,
7362                                              "Device is not activated");
7363                 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message);
7364                 g_dbus_method_invocation_take_error (context, error);
7365                 return;
7366         }
7367
7368         settings_connection = nm_device_get_settings_connection (self);
7369         g_return_if_fail (settings_connection);
7370
7371         if (settings && g_variant_n_children (settings)) {
7372                 /* New settings specified inline. */
7373                 connection = _nm_simple_connection_new_from_dbus (settings,
7374                                                                     NM_SETTING_PARSE_FLAGS_STRICT
7375                                                                   | NM_SETTING_PARSE_FLAGS_NORMALIZE,
7376                                                                   &error);
7377                 if (!connection) {
7378                         g_prefix_error (&error, "The settings specified are invalid: ");
7379                         nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message);
7380                         g_dbus_method_invocation_take_error (context, error);
7381                         return;
7382                 }
7383                 nm_connection_clear_secrets (connection);
7384         }
7385
7386         if (connection || version_id) {
7387                 reapply_data = g_slice_new (ReapplyData);
7388                 reapply_data->connection = connection;
7389                 reapply_data->version_id = version_id;
7390         } else
7391                 reapply_data = NULL;
7392
7393         /* Ask the manager to authenticate this request for us */
7394         g_signal_emit (self, signals[AUTH_REQUEST], 0,
7395                        context,
7396                        nm_device_get_applied_connection (self),
7397                        NM_AUTH_PERMISSION_NETWORK_CONTROL,
7398                        TRUE,
7399                        reapply_cb,
7400                        reapply_data);
7401 }
7402
7403 /*****************************************************************************/
7404
7405 static void
7406 get_applied_connection_cb (NMDevice *self,
7407                            GDBusMethodInvocation *context,
7408                            NMAuthSubject *subject,
7409                            GError *error,
7410                            gpointer user_data /* possibly dangling pointer */)
7411 {
7412         NMDevicePrivate *priv;
7413         NMConnection *applied_connection;
7414         GVariant *settings;
7415
7416         g_return_if_fail (NM_IS_DEVICE (self));
7417
7418         if (error) {
7419                 g_dbus_method_invocation_return_gerror (context, error);
7420                 return;
7421         }
7422
7423         priv = NM_DEVICE_GET_PRIVATE (self);
7424
7425         applied_connection = nm_device_get_applied_connection (self);
7426
7427         if (!applied_connection) {
7428                 error = g_error_new_literal (NM_DEVICE_ERROR,
7429                                              NM_DEVICE_ERROR_NOT_ACTIVE,
7430                                              "Device is not activated");
7431                 g_dbus_method_invocation_take_error (context, error);
7432                 return;
7433         }
7434
7435         if (applied_connection != user_data) {
7436                 /* The applied connection changed due to a race. Reauthenticate. */
7437                 g_signal_emit (self, signals[AUTH_REQUEST], 0,
7438                                context,
7439                                applied_connection,
7440                                NM_AUTH_PERMISSION_NETWORK_CONTROL,
7441                                TRUE,
7442                                get_applied_connection_cb,
7443                                applied_connection /* no need take a ref. We will not dereference this pointer. */);
7444                 return;
7445         }
7446
7447         settings = nm_connection_to_dbus (applied_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS);
7448         if (!settings)
7449                 settings = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
7450
7451         g_dbus_method_invocation_return_value (context,
7452                                                g_variant_new ("(@a{sa{sv}}t)",
7453                                                               settings,
7454                                                               nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request)));
7455 }
7456
7457 static void
7458 impl_device_get_applied_connection (NMDevice *self,
7459                                     GDBusMethodInvocation *context,
7460                                     guint32 flags)
7461 {
7462         NMConnection *applied_connection;
7463         GError *error = NULL;
7464
7465         g_return_if_fail (NM_IS_DEVICE (self));
7466
7467         /* No flags supported as of now. */
7468         if (flags != 0) {
7469                 error = g_error_new_literal (NM_DEVICE_ERROR,
7470                                              NM_DEVICE_ERROR_FAILED,
7471                                              "Invalid flags specified");
7472                 g_dbus_method_invocation_take_error (context, error);
7473                 return;
7474         }
7475
7476         applied_connection = nm_device_get_applied_connection (self);
7477         if (!applied_connection) {
7478                 error = g_error_new_literal (NM_DEVICE_ERROR,
7479                                              NM_DEVICE_ERROR_NOT_ACTIVE,
7480                                              "Device is not activated");
7481                 g_dbus_method_invocation_take_error (context, error);
7482                 return;
7483         }
7484
7485         /* Ask the manager to authenticate this request for us */
7486         g_signal_emit (self, signals[AUTH_REQUEST], 0,
7487                        context,
7488                        applied_connection,
7489                        NM_AUTH_PERMISSION_NETWORK_CONTROL,
7490                        TRUE,
7491                        get_applied_connection_cb,
7492                        applied_connection /* no need take a ref. We will not dereference this pointer. */);
7493 }
7494
7495 /*****************************************************************************/
7496
7497 static void
7498 disconnect_cb (NMDevice *self,
7499                GDBusMethodInvocation *context,
7500                NMAuthSubject *subject,
7501                GError *error,
7502                gpointer user_data)
7503 {
7504         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7505         GError *local = NULL;
7506
7507         if (error) {
7508                 g_dbus_method_invocation_return_gerror (context, error);
7509                 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, subject, error->message);
7510                 return;
7511         }
7512
7513         /* Authorized */
7514         if (priv->state <= NM_DEVICE_STATE_DISCONNECTED) {
7515                 local = g_error_new_literal (NM_DEVICE_ERROR,
7516                                              NM_DEVICE_ERROR_NOT_ACTIVE,
7517                                              "Device is not active");
7518                 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, subject, local->message);
7519                 g_dbus_method_invocation_take_error (context, local);
7520         } else {
7521                 nm_device_set_autoconnect (self, FALSE);
7522
7523                 nm_device_state_changed (self,
7524                                          NM_DEVICE_STATE_DEACTIVATING,
7525                                          NM_DEVICE_STATE_REASON_USER_REQUESTED);
7526                 g_dbus_method_invocation_return_value (context, NULL);
7527                 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, TRUE, subject, NULL);
7528         }
7529 }
7530
7531 static void
7532 _clear_queued_act_request (NMDevicePrivate *priv)
7533 {
7534         if (priv->queued_act_request) {
7535                 nm_active_connection_set_state ((NMActiveConnection *) priv->queued_act_request, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
7536                 g_clear_object (&priv->queued_act_request);
7537         }
7538 }
7539
7540 static void
7541 impl_device_disconnect (NMDevice *self, GDBusMethodInvocation *context)
7542 {
7543         NMConnection *connection;
7544         GError *error = NULL;
7545
7546         if (NM_DEVICE_GET_PRIVATE (self)->act_request == NULL) {
7547                 error = g_error_new_literal (NM_DEVICE_ERROR,
7548                                              NM_DEVICE_ERROR_NOT_ACTIVE,
7549                                              "This device is not active");
7550                 g_dbus_method_invocation_take_error (context, error);
7551                 return;
7552         }
7553
7554         connection = nm_device_get_applied_connection (self);
7555         g_assert (connection);
7556
7557         /* Ask the manager to authenticate this request for us */
7558         g_signal_emit (self, signals[AUTH_REQUEST], 0,
7559                        context,
7560                        connection,
7561                        NM_AUTH_PERMISSION_NETWORK_CONTROL,
7562                        TRUE,
7563                        disconnect_cb,
7564                        NULL);
7565 }
7566
7567 static void
7568 delete_cb (NMDevice *self,
7569            GDBusMethodInvocation *context,
7570            NMAuthSubject *subject,
7571            GError *error,
7572            gpointer user_data)
7573 {
7574         GError *local = NULL;
7575
7576         if (error) {
7577                 g_dbus_method_invocation_return_gerror (context, error);
7578                 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, FALSE, subject, error->message);
7579                 return;
7580         }
7581
7582         /* Authorized */
7583         nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, TRUE, subject, NULL);
7584         if (nm_device_unrealize (self, TRUE, &local))
7585                 g_dbus_method_invocation_return_value (context, NULL);
7586         else
7587                 g_dbus_method_invocation_take_error (context, local);
7588 }
7589
7590 static void
7591 impl_device_delete (NMDevice *self, GDBusMethodInvocation *context)
7592 {
7593         GError *error = NULL;
7594
7595         if (!nm_device_is_software (self) || !nm_device_is_real (self)) {
7596                 error = g_error_new_literal (NM_DEVICE_ERROR,
7597                                              NM_DEVICE_ERROR_NOT_SOFTWARE,
7598                                              "This device is not a software device or is not realized");
7599                 g_dbus_method_invocation_take_error (context, error);
7600                 return;
7601         }
7602
7603         /* Ask the manager to authenticate this request for us */
7604         g_signal_emit (self, signals[AUTH_REQUEST], 0,
7605                        context,
7606                        NULL,
7607                        NM_AUTH_PERMISSION_NETWORK_CONTROL,
7608                        TRUE,
7609                        delete_cb,
7610                        NULL);
7611 }
7612
7613 static gboolean
7614 _device_activate (NMDevice *self, NMActRequest *req)
7615 {
7616         NMDevicePrivate *priv;
7617         NMConnection *connection;
7618
7619         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
7620         g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
7621         g_return_val_if_fail (nm_device_get_managed (self, FALSE), FALSE);
7622
7623         /* Ensure the activation request is still valid; the master may have
7624          * already failed in which case activation of this device should not proceed.
7625          */
7626         if (nm_active_connection_get_state (NM_ACTIVE_CONNECTION (req)) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING)
7627                 return FALSE;
7628
7629         priv = NM_DEVICE_GET_PRIVATE (self);
7630
7631         connection = nm_act_request_get_applied_connection (req);
7632         g_assert (connection);
7633
7634         _LOGI (LOGD_DEVICE, "Activation: starting connection '%s' (%s)",
7635                nm_connection_get_id (connection),
7636                nm_connection_get_uuid (connection));
7637
7638         delete_on_deactivate_unschedule (self);
7639
7640         /* note: don't notify D-Bus of the new AC here, but do it later when
7641          * changing state to PREPARE so that the two properties change together.
7642          */
7643         priv->act_request = g_object_ref (req);
7644
7645         nm_device_activate_schedule_stage1_device_prepare (self);
7646         return TRUE;
7647 }
7648
7649 static void
7650 _carrier_wait_check_queued_act_request (NMDevice *self)
7651 {
7652         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7653         NMActRequest *queued_req;
7654
7655         if (   !priv->queued_act_request
7656             || !priv->queued_act_request_is_waiting_for_carrier)
7657                 return;
7658
7659         priv->queued_act_request_is_waiting_for_carrier = FALSE;
7660         if (!priv->carrier) {
7661                 _LOGD (LOGD_DEVICE, "Cancel queued activation request as we have no carrier after timeout");
7662                 _clear_queued_act_request (priv);
7663         } else {
7664                 _LOGD (LOGD_DEVICE, "Activate queued activation request as we now have carrier");
7665                 queued_req = priv->queued_act_request;
7666                 priv->queued_act_request = NULL;
7667                 _device_activate (self, queued_req);
7668                 g_object_unref (queued_req);
7669         }
7670 }
7671
7672 static gboolean
7673 _carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req)
7674 {
7675         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7676         NMConnection *connection;
7677
7678         /* If we have carrier or if we are not waiting for it, the activation
7679          * request is not blocked waiting for carrier. */
7680         if (priv->carrier)
7681                 return FALSE;
7682         if (priv->carrier_wait_id == 0)
7683                 return FALSE;
7684
7685         connection = nm_act_request_get_applied_connection (req);
7686         if (!connection_requires_carrier (connection))
7687                 return FALSE;
7688
7689         if (!nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL, NULL)) {
7690                 /* We passed all @flags we have, and no @specific_object.
7691                  * This equals maximal availability, if a connection is not available
7692                  * in this case, it is not waiting for carrier.
7693                  *
7694                  * Actually, why are we even trying to activate it? Strange, but whatever
7695                  * the reason, don't wait for carrier.
7696                  */
7697                 return FALSE;
7698         }
7699
7700         if (nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL & ~_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER, NULL)) {
7701                 /* The connection was available with flags ALL, and it is still available
7702                  * if we pretend not to wait for carrier. That means that the
7703                  * connection is available now, and does not wait for carrier.
7704                  *
7705                  * Since the flags increase the availability of a connection, when checking
7706                  * ALL&~WAITING_CARRIER, it means that we certainly would wait for carrier. */
7707                 return FALSE;
7708         }
7709
7710         /* The activation request must wait for carrier. */
7711         return TRUE;
7712 }
7713
7714 void
7715 nm_device_steal_connection (NMDevice *self, NMSettingsConnection *connection)
7716 {
7717         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7718
7719         _LOGW (LOGD_DEVICE, "disconnecting connection '%s' for new activation request.",
7720                nm_settings_connection_get_id (connection));
7721
7722         if (   priv->queued_act_request
7723             && connection == nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (priv->queued_act_request)))
7724                 _clear_queued_act_request (priv);
7725
7726         if (   priv->act_request
7727             && connection == nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (priv->act_request))
7728             && priv->state < NM_DEVICE_STATE_DEACTIVATING)
7729                 nm_device_state_changed (self,
7730                                          NM_DEVICE_STATE_DEACTIVATING,
7731                                          NM_DEVICE_STATE_REASON_NEW_ACTIVATION);
7732 }
7733
7734 void
7735 nm_device_queue_activation (NMDevice *self, NMActRequest *req)
7736 {
7737         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7738         gboolean must_queue;
7739
7740         must_queue = _carrier_wait_check_act_request_must_queue (self, req);
7741
7742         if (!priv->act_request && !must_queue && nm_device_is_real (self)) {
7743                 /* Just activate immediately */
7744                 if (!_device_activate (self, req))
7745                         g_assert_not_reached ();
7746                 return;
7747         }
7748
7749         /* supercede any already-queued request */
7750         _clear_queued_act_request (priv);
7751         priv->queued_act_request = g_object_ref (req);
7752         priv->queued_act_request_is_waiting_for_carrier = must_queue;
7753
7754         _LOGD (LOGD_DEVICE, "queue activation request waiting for %s", must_queue ? "carrier" : "currently active connection to disconnect");
7755
7756         /* Deactivate existing activation request first */
7757         if (priv->act_request) {
7758                 _LOGI (LOGD_DEVICE, "disconnecting for new activation request.");
7759                 nm_device_state_changed (self,
7760                                          NM_DEVICE_STATE_DEACTIVATING,
7761                                          NM_DEVICE_STATE_REASON_NEW_ACTIVATION);
7762         }
7763 }
7764
7765 /*
7766  * nm_device_is_activating
7767  *
7768  * Return whether or not the device is currently activating itself.
7769  *
7770  */
7771 gboolean
7772 nm_device_is_activating (NMDevice *self)
7773 {
7774         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7775         NMDeviceState state;
7776
7777         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
7778
7779         state = nm_device_get_state (self);
7780         if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_SECONDARIES)
7781                 return TRUE;
7782
7783         /* There's a small race between the time when stage 1 is scheduled
7784          * and when the device actually sets STATE_PREPARE when the activation
7785          * handler is actually run.  If there's an activation handler scheduled
7786          * we're activating anyway.
7787          */
7788         return priv->act_handle4.id ? TRUE : FALSE;
7789 }
7790
7791 /* IP Configuration stuff */
7792
7793 NMDhcp4Config *
7794 nm_device_get_dhcp4_config (NMDevice *self)
7795 {
7796         g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
7797
7798         return NM_DEVICE_GET_PRIVATE (self)->dhcp4_config;
7799 }
7800
7801 NMIP4Config *
7802 nm_device_get_ip4_config (NMDevice *self)
7803 {
7804         g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
7805
7806         return NM_DEVICE_GET_PRIVATE (self)->ip4_config;
7807 }
7808
7809
7810 static gboolean
7811 nm_device_set_ip4_config (NMDevice *self,
7812                           NMIP4Config *new_config,
7813                           guint32 default_route_metric,
7814                           gboolean commit,
7815                           gboolean routes_full_sync,
7816                           NMDeviceStateReason *reason)
7817 {
7818         NMDevicePrivate *priv;
7819         NMIP4Config *old_config = NULL;
7820         gboolean has_changes = FALSE;
7821         gboolean success = TRUE;
7822         NMDeviceStateReason reason_local = NM_DEVICE_STATE_REASON_NONE;
7823         int ip_ifindex, config_ifindex;
7824
7825         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
7826
7827         priv = NM_DEVICE_GET_PRIVATE (self);
7828         ip_ifindex = nm_device_get_ip_ifindex (self);
7829
7830         if (new_config) {
7831                 config_ifindex = nm_ip4_config_get_ifindex (new_config);
7832                 if (config_ifindex > 0)
7833                         g_return_val_if_fail (ip_ifindex == config_ifindex, FALSE);
7834         }
7835
7836         old_config = priv->ip4_config;
7837
7838         /* Always commit to nm-platform to update lifetimes */
7839         if (commit && new_config) {
7840                 gboolean assumed = nm_device_uses_assumed_connection (self);
7841
7842                 nm_device_set_mtu (self, nm_ip4_config_get_mtu (new_config));
7843
7844                 /* For assumed devices we must not touch the kernel-routes, such as the device-route.
7845                  * FIXME: this is wrong in case where "assumed" means "take-over-seamlessly". In this
7846                  * case, we should manage the device route, for example on new DHCP lease. */
7847                 success = nm_ip4_config_commit (new_config, ip_ifindex,
7848                                                 routes_full_sync,
7849                                                 assumed ? (gint64) -1 : (gint64) default_route_metric);
7850                 if (!success)
7851                         reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
7852         }
7853
7854         if (new_config) {
7855                 if (old_config) {
7856                         /* has_changes is set only on relevant changes, because when the configuration changes,
7857                          * this causes a re-read and reset. This should only happen for relevant changes */
7858                         nm_ip4_config_replace (old_config, new_config, &has_changes);
7859                         if (has_changes) {
7860                                 _LOGD (LOGD_IP4, "update IP4Config instance (%s)",
7861                                        nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
7862                         }
7863                 } else {
7864                         has_changes = TRUE;
7865                         priv->ip4_config = g_object_ref (new_config);
7866
7867                         if (success && !nm_exported_object_is_exported (NM_EXPORTED_OBJECT (new_config)))
7868                                 nm_exported_object_export (NM_EXPORTED_OBJECT (new_config));
7869
7870                         _LOGD (LOGD_IP4, "set IP4Config instance (%s)",
7871                                nm_exported_object_get_path (NM_EXPORTED_OBJECT (new_config)));
7872                 }
7873         } else if (old_config) {
7874                 has_changes = TRUE;
7875                 priv->ip4_config = NULL;
7876                 _LOGD (LOGD_IP4, "clear IP4Config instance (%s)",
7877                        nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
7878                 /* Device config is invalid if combined config is invalid */
7879                 g_clear_object (&priv->dev_ip4_config);
7880         }
7881
7882         nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self);
7883
7884         if (has_changes) {
7885                 _update_ip4_address (self);
7886
7887                 if (old_config != priv->ip4_config)
7888                         _notify (self, PROP_IP4_CONFIG);
7889                 g_signal_emit (self, signals[IP4_CONFIG_CHANGED], 0, priv->ip4_config, old_config);
7890
7891                 if (old_config != priv->ip4_config)
7892                         nm_exported_object_clear_and_unexport (&old_config);
7893
7894                 if (nm_device_uses_generated_assumed_connection (self)) {
7895                         NMConnection *connection = nm_device_get_applied_connection (self);
7896                         NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (self));
7897                         NMSetting *s_ip4;
7898
7899                         g_object_freeze_notify (G_OBJECT (connection));
7900                         g_object_freeze_notify (G_OBJECT (settings_connection));
7901
7902                         nm_connection_remove_setting (settings_connection, NM_TYPE_SETTING_IP4_CONFIG);
7903                         s_ip4 = nm_ip4_config_create_setting (priv->ip4_config);
7904                         nm_connection_add_setting (settings_connection, s_ip4);
7905
7906                         nm_connection_remove_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
7907                         s_ip4 = nm_ip4_config_create_setting (priv->ip4_config);
7908                         nm_connection_add_setting (connection, s_ip4);
7909
7910                         g_object_thaw_notify (G_OBJECT (settings_connection));
7911                         g_object_thaw_notify (G_OBJECT (connection));
7912                 }
7913
7914                 nm_device_queue_recheck_assume (self);
7915         }
7916
7917         if (reason)
7918                 *reason = reason_local;
7919
7920         return success;
7921 }
7922
7923 static gboolean
7924 _replace_vpn_config_in_list (GSList **plist, GObject *old, GObject *new)
7925 {
7926         GSList *old_link;
7927
7928         /* Below, assert that @new is not yet tracked, but still behave
7929          * correctly in any case. Don't complain for missing @old since
7930          * it could have been removed when the parent device became
7931          * unmanaged. */
7932
7933         if (   old
7934             && (old_link = g_slist_find (*plist, old))) {
7935                 if (old != new) {
7936                         if (new)
7937                                 old_link->data = g_object_ref (new);
7938                         else
7939                                 *plist = g_slist_delete_link (*plist, old_link);
7940                         g_object_unref (old);
7941                 }
7942                 return TRUE;
7943         }
7944
7945         if (new) {
7946                 if (!g_slist_find (*plist, new))
7947                         *plist = g_slist_append (*plist, g_object_ref (new));
7948                 else
7949                         g_return_val_if_reached (TRUE);
7950                 return TRUE;
7951         }
7952
7953         return FALSE;
7954 }
7955
7956 void
7957 nm_device_replace_vpn4_config (NMDevice *self, NMIP4Config *old, NMIP4Config *config)
7958 {
7959         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7960
7961         if (!_replace_vpn_config_in_list (&priv->vpn4_configs, (GObject *) old, (GObject *) config))
7962                 return;
7963
7964         /* NULL to use existing configs */
7965         if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL))
7966                 _LOGW (LOGD_IP4, "failed to set VPN routes for device");
7967 }
7968
7969 void
7970 nm_device_set_wwan_ip4_config (NMDevice *self, NMIP4Config *config)
7971 {
7972         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7973
7974         if (priv->wwan_ip4_config == config)
7975                 return;
7976
7977         g_clear_object (&priv->wwan_ip4_config);
7978         if (config)
7979                 priv->wwan_ip4_config = g_object_ref (config);
7980
7981         /* NULL to use existing configs */
7982         if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL))
7983                 _LOGW (LOGD_IP4, "failed to set WWAN IPv4 configuration");
7984 }
7985
7986 static gboolean
7987 nm_device_set_ip6_config (NMDevice *self,
7988                           NMIP6Config *new_config,
7989                           gboolean commit,
7990                           gboolean routes_full_sync,
7991                           NMDeviceStateReason *reason)
7992 {
7993         NMDevicePrivate *priv;
7994         NMIP6Config *old_config = NULL;
7995         gboolean has_changes = FALSE;
7996         gboolean success = TRUE;
7997         NMDeviceStateReason reason_local = NM_DEVICE_STATE_REASON_NONE;
7998         int ip_ifindex, config_ifindex;
7999
8000         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
8001
8002         priv = NM_DEVICE_GET_PRIVATE (self);
8003         ip_ifindex = nm_device_get_ip_ifindex (self);
8004
8005         if (new_config) {
8006                 config_ifindex = nm_ip6_config_get_ifindex (new_config);
8007                 if (config_ifindex > 0)
8008                         g_return_val_if_fail (ip_ifindex == config_ifindex, FALSE);
8009         }
8010
8011         old_config = priv->ip6_config;
8012
8013         /* Always commit to nm-platform to update lifetimes */
8014         if (commit && new_config) {
8015                 nm_device_ipv6_set_mtu (self, priv->ip6_mtu);
8016                 success = nm_ip6_config_commit (new_config,
8017                                                 ip_ifindex,
8018                                                 routes_full_sync);
8019                 if (!success)
8020                         reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
8021         }
8022
8023         if (new_config) {
8024                 if (old_config) {
8025                         /* has_changes is set only on relevant changes, because when the configuration changes,
8026                          * this causes a re-read and reset. This should only happen for relevant changes */
8027                         nm_ip6_config_replace (old_config, new_config, &has_changes);
8028                         if (has_changes) {
8029                                 _LOGD (LOGD_IP6, "update IP6Config instance (%s)",
8030                                        nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
8031                         }
8032                 } else {
8033                         has_changes = TRUE;
8034                         priv->ip6_config = g_object_ref (new_config);
8035
8036                         if (success && !nm_exported_object_is_exported (NM_EXPORTED_OBJECT (new_config)))
8037                                 nm_exported_object_export (NM_EXPORTED_OBJECT (new_config));
8038
8039                         _LOGD (LOGD_IP6, "set IP6Config instance (%s)",
8040                                nm_exported_object_get_path (NM_EXPORTED_OBJECT (new_config)));
8041                 }
8042         } else if (old_config) {
8043                 has_changes = TRUE;
8044                 priv->ip6_config = NULL;
8045                 _LOGD (LOGD_IP6, "clear IP6Config instance (%s)",
8046                        nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
8047         }
8048
8049         nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self);
8050
8051         if (has_changes) {
8052                 if (old_config != priv->ip6_config)
8053                         _notify (self, PROP_IP6_CONFIG);
8054                 g_signal_emit (self, signals[IP6_CONFIG_CHANGED], 0, priv->ip6_config, old_config);
8055
8056                 if (old_config != priv->ip6_config)
8057                         nm_exported_object_clear_and_unexport (&old_config);
8058
8059                 if (nm_device_uses_generated_assumed_connection (self)) {
8060                         NMConnection *connection = nm_device_get_applied_connection (self);
8061                         NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (self));
8062                         NMSetting *s_ip6;
8063
8064                         g_object_freeze_notify (G_OBJECT (connection));
8065                         g_object_freeze_notify (G_OBJECT (settings_connection));
8066
8067                         nm_connection_remove_setting (settings_connection, NM_TYPE_SETTING_IP6_CONFIG);
8068                         s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
8069                         nm_connection_add_setting (settings_connection, s_ip6);
8070
8071                         nm_connection_remove_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
8072                         s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
8073                         nm_connection_add_setting (connection, s_ip6);
8074
8075                         g_object_thaw_notify (G_OBJECT (settings_connection));
8076                         g_object_thaw_notify (G_OBJECT (connection));
8077                 }
8078
8079                 nm_device_queue_recheck_assume (self);
8080         }
8081
8082         if (reason)
8083                 *reason = reason_local;
8084
8085         return success;
8086 }
8087
8088 void
8089 nm_device_replace_vpn6_config (NMDevice *self, NMIP6Config *old, NMIP6Config *config)
8090 {
8091         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8092
8093         if (!_replace_vpn_config_in_list (&priv->vpn6_configs, (GObject *) old, (GObject *) config))
8094                 return;
8095
8096         /* NULL to use existing configs */
8097         if (!ip6_config_merge_and_apply (self, TRUE, NULL))
8098                 _LOGW (LOGD_IP6, "failed to set VPN routes for device");
8099 }
8100
8101 void
8102 nm_device_set_wwan_ip6_config (NMDevice *self, NMIP6Config *config)
8103 {
8104         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8105
8106         if (priv->wwan_ip6_config == config)
8107                 return;
8108
8109         g_clear_object (&priv->wwan_ip6_config);
8110         if (config)
8111                 priv->wwan_ip6_config = g_object_ref (config);
8112
8113         /* NULL to use existing configs */
8114         if (!ip6_config_merge_and_apply (self, TRUE, NULL))
8115                 _LOGW (LOGD_IP6, "failed to set WWAN IPv6 configuration");
8116 }
8117
8118 NMDhcp6Config *
8119 nm_device_get_dhcp6_config (NMDevice *self)
8120 {
8121         g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
8122
8123         return NM_DEVICE_GET_PRIVATE (self)->dhcp6_config;
8124 }
8125
8126 NMIP6Config *
8127 nm_device_get_ip6_config (NMDevice *self)
8128 {
8129         g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
8130
8131         return NM_DEVICE_GET_PRIVATE (self)->ip6_config;
8132 }
8133
8134 /****************************************************************/
8135
8136 static void
8137 dispatcher_cleanup (NMDevice *self)
8138 {
8139         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8140
8141         if (priv->dispatcher.call_id) {
8142                 nm_dispatcher_call_cancel (priv->dispatcher.call_id);
8143                 priv->dispatcher.call_id = 0;
8144                 priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN;
8145                 priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
8146         }
8147 }
8148
8149 static void
8150 dispatcher_complete_proceed_state (guint call_id, gpointer user_data)
8151 {
8152         NMDevice *self = NM_DEVICE (user_data);
8153         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8154
8155         g_return_if_fail (call_id == priv->dispatcher.call_id);
8156
8157         priv->dispatcher.call_id = 0;
8158         nm_device_queue_state (self, priv->dispatcher.post_state,
8159                                priv->dispatcher.post_state_reason);
8160         priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN;
8161         priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
8162 }
8163
8164 /****************************************************************/
8165
8166 static void
8167 ip_check_pre_up (NMDevice *self)
8168 {
8169         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8170
8171         if (priv->dispatcher.call_id != 0) {
8172                 g_warn_if_reached ();
8173                 dispatcher_cleanup (self);
8174         }
8175
8176         priv->dispatcher.post_state = NM_DEVICE_STATE_SECONDARIES;
8177         priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
8178         if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_UP,
8179                                  nm_device_get_settings_connection (self),
8180                                  nm_device_get_applied_connection (self),
8181                                  self,
8182                                  dispatcher_complete_proceed_state,
8183                                  self,
8184                                  &priv->dispatcher.call_id)) {
8185                 /* Just proceed on errors */
8186                 dispatcher_complete_proceed_state (0, self);
8187         }
8188 }
8189
8190 static void
8191 ip_check_gw_ping_cleanup (NMDevice *self)
8192 {
8193         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8194
8195         nm_clear_g_source (&priv->gw_ping.watch);
8196         nm_clear_g_source (&priv->gw_ping.timeout);
8197
8198         if (priv->gw_ping.pid) {
8199                 nm_utils_kill_child_async (priv->gw_ping.pid, SIGTERM, priv->gw_ping.log_domain, "ping", 1000, NULL, NULL);
8200                 priv->gw_ping.pid = 0;
8201         }
8202
8203         g_clear_pointer (&priv->gw_ping.binary, g_free);
8204         g_clear_pointer (&priv->gw_ping.address, g_free);
8205 }
8206
8207 static gboolean
8208 spawn_ping (NMDevice *self)
8209 {
8210         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8211         gs_free char *str_timeout = NULL;
8212         gs_free char *tmp_str = NULL;
8213         const char *args[] = { priv->gw_ping.binary, "-I", nm_device_get_ip_iface (self),
8214                                "-c", "1", "-w", NULL, priv->gw_ping.address, NULL };
8215         gs_free_error GError *error = NULL;
8216         gboolean ret;
8217
8218         args[6] = str_timeout = g_strdup_printf ("%u", priv->gw_ping.deadline);
8219         tmp_str = g_strjoinv (" ", (gchar **) args);
8220         _LOGD (priv->gw_ping.log_domain, "ping: running '%s'", tmp_str);
8221
8222         ret = g_spawn_async ("/",
8223                              (gchar **) args,
8224                               NULL,
8225                               G_SPAWN_DO_NOT_REAP_CHILD,
8226                               NULL,
8227                               NULL,
8228                               &priv->gw_ping.pid,
8229                               &error);
8230
8231         if (!ret) {
8232                 _LOGW (priv->gw_ping.log_domain, "ping: could not spawn %s: %s",
8233                        priv->gw_ping.binary, error->message);
8234         }
8235
8236         return ret;
8237 }
8238
8239 static gboolean
8240 respawn_ping_cb (gpointer user_data)
8241 {
8242         NMDevice *self = NM_DEVICE (user_data);
8243         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8244
8245         priv->gw_ping.watch = 0;
8246
8247         if (spawn_ping (self)) {
8248                 priv->gw_ping.watch = g_child_watch_add (priv->gw_ping.pid,
8249                                                          ip_check_ping_watch_cb, self);
8250         } else {
8251                 ip_check_gw_ping_cleanup (self);
8252                 ip_check_pre_up (self);
8253         }
8254
8255         return FALSE;
8256 }
8257
8258 static void
8259 ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data)
8260 {
8261         NMDevice *self = NM_DEVICE (user_data);
8262         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8263         NMLogDomain log_domain = priv->gw_ping.log_domain;
8264         gboolean success = FALSE;
8265
8266         if (!priv->gw_ping.watch)
8267                 return;
8268         priv->gw_ping.watch = 0;
8269         priv->gw_ping.pid = 0;
8270
8271         if (WIFEXITED (status)) {
8272                 if (WEXITSTATUS (status) == 0) {
8273                         _LOGD (log_domain, "ping: gateway ping succeeded");
8274                         success = TRUE;
8275                 } else {
8276                         _LOGW (log_domain, "ping: gateway ping failed with error code %d",
8277                                WEXITSTATUS (status));
8278                 }
8279         } else
8280                 _LOGW (log_domain, "ping: stopped unexpectedly with status %d", status);
8281
8282         if (success) {
8283                 /* We've got connectivity, proceed to pre_up */
8284                 ip_check_gw_ping_cleanup (self);
8285                 ip_check_pre_up (self);
8286         } else {
8287                 /* If ping exited with an error it may have returned early,
8288                  * wait 1 second and restart it */
8289                 priv->gw_ping.watch = g_timeout_add_seconds (1, respawn_ping_cb, self);
8290         }
8291 }
8292
8293 static gboolean
8294 ip_check_ping_timeout_cb (gpointer user_data)
8295 {
8296         NMDevice *self = NM_DEVICE (user_data);
8297         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8298
8299         priv->gw_ping.timeout = 0;
8300
8301         _LOGW (priv->gw_ping.log_domain, "ping: gateway ping timed out");
8302
8303         ip_check_gw_ping_cleanup (self);
8304         ip_check_pre_up (self);
8305         return FALSE;
8306 }
8307
8308 static gboolean
8309 start_ping (NMDevice *self,
8310             NMLogDomain log_domain,
8311             const char *binary,
8312             const char *address,
8313             guint timeout)
8314 {
8315         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8316
8317         g_return_val_if_fail (priv->gw_ping.watch == 0, FALSE);
8318         g_return_val_if_fail (priv->gw_ping.timeout == 0, FALSE);
8319
8320         priv->gw_ping.log_domain = log_domain;
8321         priv->gw_ping.address = g_strdup (address);
8322         priv->gw_ping.binary = g_strdup (binary);
8323         priv->gw_ping.deadline = timeout + 10;  /* the proper termination is enforced by a timer */
8324
8325         if (spawn_ping (self)) {
8326                 priv->gw_ping.watch = g_child_watch_add (priv->gw_ping.pid, ip_check_ping_watch_cb, self);
8327                 priv->gw_ping.timeout = g_timeout_add_seconds (timeout, ip_check_ping_timeout_cb, self);
8328                 return TRUE;
8329         }
8330
8331         ip_check_gw_ping_cleanup (self);
8332         return FALSE;
8333 }
8334
8335 static void
8336 nm_device_start_ip_check (NMDevice *self)
8337 {
8338         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8339         NMConnection *connection;
8340         NMSettingConnection *s_con;
8341         guint timeout = 0;
8342         const char *ping_binary = NULL;
8343         char buf[INET6_ADDRSTRLEN] = { 0 };
8344         NMLogDomain log_domain = LOGD_IP4;
8345
8346         /* Shouldn't be any active ping here, since IP_CHECK happens after the
8347          * first IP method completes.  Any subsequently completing IP method doesn't
8348          * get checked.
8349          */
8350         g_assert (!priv->gw_ping.watch);
8351         g_assert (!priv->gw_ping.timeout);
8352         g_assert (!priv->gw_ping.pid);
8353         g_assert (priv->ip4_state == IP_DONE || priv->ip6_state == IP_DONE);
8354
8355         connection = nm_device_get_applied_connection (self);
8356         g_assert (connection);
8357
8358         s_con = nm_connection_get_setting_connection (connection);
8359         g_assert (s_con);
8360         timeout = nm_setting_connection_get_gateway_ping_timeout (s_con);
8361
8362         if (timeout) {
8363                 if (priv->ip4_config && priv->ip4_state == IP_DONE) {
8364                         guint gw = 0;
8365
8366                         ping_binary = nm_utils_find_helper ("ping", "/usr/bin/ping", NULL);
8367                         log_domain = LOGD_IP4;
8368
8369                         gw = nm_ip4_config_get_gateway (priv->ip4_config);
8370                         if (gw && !inet_ntop (AF_INET, &gw, buf, sizeof (buf)))
8371                                 buf[0] = '\0';
8372                 } else if (priv->ip6_config && priv->ip6_state == IP_DONE) {
8373                         const struct in6_addr *gw = NULL;
8374
8375                         ping_binary = nm_utils_find_helper ("ping6", "/usr/bin/ping6", NULL);
8376                         log_domain = LOGD_IP6;
8377
8378                         gw = nm_ip6_config_get_gateway (priv->ip6_config);
8379                         if (gw && !inet_ntop (AF_INET6, gw, buf, sizeof (buf)))
8380                                 buf[0] = '\0';
8381                 }
8382         }
8383
8384         if (buf[0])
8385                 start_ping (self, log_domain, ping_binary, buf, timeout);
8386
8387         /* If no ping was started, just advance to pre_up */
8388         if (!priv->gw_ping.pid)
8389                 ip_check_pre_up (self);
8390 }
8391
8392 /****************************************************************/
8393
8394 static gboolean
8395 carrier_wait_timeout (gpointer user_data)
8396 {
8397         NMDevice *self = NM_DEVICE (user_data);
8398
8399         NM_DEVICE_GET_PRIVATE (self)->carrier_wait_id = 0;
8400         nm_device_remove_pending_action (self, "carrier wait", TRUE);
8401
8402         _carrier_wait_check_queued_act_request (self);
8403
8404         return G_SOURCE_REMOVE;
8405 }
8406
8407 static gboolean
8408 nm_device_is_up (NMDevice *self)
8409 {
8410         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
8411
8412         if (NM_DEVICE_GET_CLASS (self)->is_up)
8413                 return NM_DEVICE_GET_CLASS (self)->is_up (self);
8414
8415         return TRUE;
8416 }
8417
8418 static gboolean
8419 is_up (NMDevice *self)
8420 {
8421         int ifindex = nm_device_get_ip_ifindex (self);
8422
8423         return ifindex > 0 ? nm_platform_link_is_up (NM_PLATFORM_GET, ifindex) : TRUE;
8424 }
8425
8426 gboolean
8427 nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware)
8428 {
8429         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8430         gboolean device_is_up = FALSE;
8431
8432         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
8433
8434         _LOGD (LOGD_HW, "bringing up device");
8435
8436         if (NM_DEVICE_GET_CLASS (self)->bring_up) {
8437                 if (!NM_DEVICE_GET_CLASS (self)->bring_up (self, no_firmware))
8438                         return FALSE;
8439         }
8440
8441         device_is_up = nm_device_is_up (self);
8442         if (block && !device_is_up) {
8443                 int ifindex = nm_device_get_ip_ifindex (self);
8444                 gint64 wait_until = nm_utils_get_monotonic_timestamp_us () + 10000 /* microseconds */;
8445
8446                 do {
8447                         g_usleep (200);
8448                         if (!nm_platform_link_refresh (NM_PLATFORM_GET, ifindex))
8449                                 return FALSE;
8450                         device_is_up = nm_device_is_up (self);
8451                 } while (!device_is_up && nm_utils_get_monotonic_timestamp_us () < wait_until);
8452         }
8453
8454         if (!device_is_up) {
8455                 if (block)
8456                         _LOGW (LOGD_HW, "device not up after timeout!");
8457                 else
8458                         _LOGD (LOGD_HW, "device not up immediately");
8459                 return FALSE;
8460         }
8461
8462         /* Devices that support carrier detect must be IFF_UP to report carrier
8463          * changes; so after setting the device IFF_UP we must suppress startup
8464          * complete (via a pending action) until either the carrier turns on, or
8465          * a timeout is reached.
8466          */
8467         if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
8468                 if (!nm_clear_g_source (&priv->carrier_wait_id))
8469                         nm_device_add_pending_action (self, "carrier wait", TRUE);
8470                 priv->carrier_wait_id = g_timeout_add_seconds (5, carrier_wait_timeout, self);
8471         }
8472
8473         /* Can only get HW address of some devices when they are up */
8474         nm_device_update_hw_address (self);
8475
8476         _update_ip4_address (self);
8477         return TRUE;
8478 }
8479
8480 static gboolean
8481 bring_up (NMDevice *self, gboolean *no_firmware)
8482 {
8483         int ifindex = nm_device_get_ip_ifindex (self);
8484         gboolean result;
8485
8486         if (ifindex <= 0) {
8487                 if (no_firmware)
8488                         *no_firmware = FALSE;
8489                 return TRUE;
8490         }
8491
8492         result = nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, no_firmware);
8493
8494         /* Store carrier immediately. */
8495         if (result && nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT))
8496                 check_carrier (self);
8497
8498         return result;
8499 }
8500
8501 void
8502 nm_device_take_down (NMDevice *self, gboolean block)
8503 {
8504         gboolean device_is_up;
8505
8506         g_return_if_fail (NM_IS_DEVICE (self));
8507
8508         _LOGD (LOGD_HW, "taking down device");
8509
8510         if (NM_DEVICE_GET_CLASS (self)->take_down) {
8511                 if (!NM_DEVICE_GET_CLASS (self)->take_down (self))
8512                         return;
8513         }
8514
8515         device_is_up = nm_device_is_up (self);
8516         if (block && device_is_up) {
8517                 int ifindex = nm_device_get_ip_ifindex (self);
8518                 gint64 wait_until = nm_utils_get_monotonic_timestamp_us () + 10000 /* microseconds */;
8519
8520                 do {
8521                         g_usleep (200);
8522                         if (!nm_platform_link_refresh (NM_PLATFORM_GET, ifindex))
8523                                 return;
8524                         device_is_up = nm_device_is_up (self);
8525                 } while (device_is_up && nm_utils_get_monotonic_timestamp_us () < wait_until);
8526         }
8527
8528         if (device_is_up) {
8529                 if (block)
8530                         _LOGW (LOGD_HW, "device not down after timeout!");
8531                 else
8532                         _LOGD (LOGD_HW, "device not down immediately");
8533         }
8534 }
8535
8536 static gboolean
8537 take_down (NMDevice *self)
8538 {
8539         int ifindex = nm_device_get_ip_ifindex (self);
8540
8541         if (ifindex > 0)
8542                 return nm_platform_link_set_down (NM_PLATFORM_GET, ifindex);
8543
8544         /* devices without ifindex are always up. */
8545         _LOGD (LOGD_HW, "cannot take down device without ifindex");
8546         return FALSE;
8547 }
8548
8549 void
8550 nm_device_set_firmware_missing (NMDevice *self, gboolean new_missing)
8551 {
8552         NMDevicePrivate *priv;
8553
8554         g_return_if_fail (NM_IS_DEVICE (self));
8555
8556         priv = NM_DEVICE_GET_PRIVATE (self);
8557         if (priv->firmware_missing != new_missing) {
8558                 priv->firmware_missing = new_missing;
8559                 _notify (self, PROP_FIRMWARE_MISSING);
8560         }
8561 }
8562
8563 gboolean
8564 nm_device_get_firmware_missing (NMDevice *self)
8565 {
8566         return NM_DEVICE_GET_PRIVATE (self)->firmware_missing;
8567 }
8568
8569 void
8570 nm_device_set_nm_plugin_missing (NMDevice *self, gboolean new_missing)
8571 {
8572         NMDevicePrivate *priv;
8573
8574         g_return_if_fail (NM_IS_DEVICE (self));
8575
8576         priv = NM_DEVICE_GET_PRIVATE (self);
8577         if (priv->nm_plugin_missing != new_missing) {
8578                 priv->nm_plugin_missing = new_missing;
8579                 _notify (self, PROP_NM_PLUGIN_MISSING);
8580         }
8581 }
8582
8583 gboolean
8584 nm_device_get_nm_plugin_missing (NMDevice *self)
8585 {
8586         return NM_DEVICE_GET_PRIVATE (self)->nm_plugin_missing;
8587 }
8588
8589 static NMIP4Config *
8590 find_ip4_lease_config (NMDevice *self,
8591                        NMConnection *connection,
8592                        NMIP4Config *ext_ip4_config)
8593 {
8594         const char *ip_iface = nm_device_get_ip_iface (self);
8595         int ip_ifindex = nm_device_get_ip_ifindex (self);
8596         GSList *leases, *liter;
8597         NMIP4Config *found = NULL;
8598
8599         g_return_val_if_fail (NM_IS_IP4_CONFIG (ext_ip4_config), NULL);
8600         g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
8601
8602         leases = nm_dhcp_manager_get_lease_ip_configs (nm_dhcp_manager_get (),
8603                                                        ip_iface,
8604                                                        ip_ifindex,
8605                                                        nm_connection_get_uuid (connection),
8606                                                        FALSE,
8607                                                        nm_device_get_ip4_route_metric (self));
8608         for (liter = leases; liter && !found; liter = liter->next) {
8609                 NMIP4Config *lease_config = liter->data;
8610                 const NMPlatformIP4Address *address = nm_ip4_config_get_address (lease_config, 0);
8611                 guint32 gateway = nm_ip4_config_get_gateway (lease_config);
8612
8613                 g_assert (address);
8614                 if (!nm_ip4_config_address_exists (ext_ip4_config, address))
8615                         continue;
8616                 if (gateway != nm_ip4_config_get_gateway (ext_ip4_config))
8617                         continue;
8618                 found = g_object_ref (lease_config);
8619         }
8620
8621         g_slist_free_full (leases, g_object_unref);
8622         return found;
8623 }
8624
8625 static void
8626 capture_lease_config (NMDevice *self,
8627                       NMIP4Config *ext_ip4_config,
8628                       NMIP4Config **out_ip4_config,
8629                       NMIP6Config *ext_ip6_config,
8630                       NMIP6Config **out_ip6_config)
8631 {
8632         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8633         const GSList *connections, *citer;
8634         guint i;
8635         gboolean dhcp_used = FALSE;
8636
8637         /* Ensure at least one address on the device has a non-infinite lifetime,
8638          * otherwise DHCP cannot possibly be active on the device right now.
8639          */
8640         if (ext_ip4_config && out_ip4_config) {
8641                 for (i = 0; i < nm_ip4_config_get_num_addresses (ext_ip4_config); i++) {
8642                         const NMPlatformIP4Address *addr = nm_ip4_config_get_address (ext_ip4_config, i);
8643
8644                         if (addr->lifetime != NM_PLATFORM_LIFETIME_PERMANENT) {
8645                                 dhcp_used = TRUE;
8646                                 break;
8647                         }
8648                 }
8649         } else if (ext_ip6_config && out_ip6_config) {
8650                 for (i = 0; i < nm_ip6_config_get_num_addresses (ext_ip6_config); i++) {
8651                         const NMPlatformIP6Address *addr = nm_ip6_config_get_address (ext_ip6_config, i);
8652
8653                         if (addr->lifetime != NM_PLATFORM_LIFETIME_PERMANENT) {
8654                                 dhcp_used = TRUE;
8655                                 break;
8656                         }
8657                 }
8658         } else {
8659                 g_return_if_fail (   (ext_ip6_config && out_ip6_config)
8660                                   || (ext_ip4_config && out_ip4_config));
8661         }
8662
8663         if (!dhcp_used)
8664                 return;
8665
8666         connections = nm_connection_provider_get_connections (priv->con_provider);
8667         for (citer = connections; citer; citer = citer->next) {
8668                 NMConnection *candidate = citer->data;
8669                 const char *method;
8670
8671                 if (!nm_device_check_connection_compatible (self, candidate))
8672                         continue;
8673
8674                 /* IPv4 leases */
8675                 method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP4_CONFIG);
8676                 if (out_ip4_config && strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) {
8677                         *out_ip4_config = find_ip4_lease_config (self, candidate, ext_ip4_config);
8678                         if (*out_ip4_config)
8679                                 return;
8680                 }
8681
8682                 /* IPv6 leases */
8683                 method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP6_CONFIG);
8684                 if (out_ip6_config && strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
8685                         /* FIXME: implement find_ip6_lease_config() */
8686                 }
8687         }
8688 }
8689
8690 static void
8691 _ip4_config_intersect (gpointer value, gpointer user_data)
8692 {
8693         NMIP4Config *dst = (NMIP4Config *) value;
8694         NMIP4Config *src = (NMIP4Config *) user_data;
8695
8696         nm_ip4_config_intersect (dst, src);
8697 }
8698
8699 static void
8700 _ip4_config_subtract (gpointer value, gpointer user_data)
8701 {
8702         NMIP4Config *dst = (NMIP4Config *) user_data;
8703         NMIP4Config *src = (NMIP4Config *) value;
8704
8705         nm_ip4_config_subtract (dst, src);
8706 }
8707
8708 static void
8709 update_ip4_config (NMDevice *self, gboolean initial)
8710 {
8711         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8712         int ifindex;
8713         gboolean capture_resolv_conf;
8714         NMDnsManagerResolvConfMode resolv_conf_mode;
8715
8716         ifindex = nm_device_get_ip_ifindex (self);
8717         if (!ifindex)
8718                 return;
8719
8720         resolv_conf_mode = nm_dns_manager_get_resolv_conf_mode (nm_dns_manager_get ());
8721         capture_resolv_conf = initial && (resolv_conf_mode == NM_DNS_MANAGER_RESOLV_CONF_EXPLICIT);
8722
8723         /* IPv4 */
8724         g_clear_object (&priv->ext_ip4_config);
8725         priv->ext_ip4_config = nm_ip4_config_capture (ifindex, capture_resolv_conf);
8726         if (priv->ext_ip4_config) {
8727                 if (initial) {
8728                         g_clear_object (&priv->dev_ip4_config);
8729                         capture_lease_config (self, priv->ext_ip4_config, &priv->dev_ip4_config, NULL, NULL);
8730                 }
8731
8732                 /* FIXME: ext_ip4_config does not contain routes with source==RTPROT_KERNEL.
8733                  * Hence, we will wrongly remove device-routes with metric=0 if they were added by
8734                  * the user on purpose. This should be fixed by also tracking and exposing
8735                  * kernel routes. */
8736
8737                 /* This function was called upon external changes. Remove the configuration
8738                  * (addresses,routes) that is no longer present externally from the internal
8739                  * config. This way, we don't re-add addresses that were manually removed
8740                  * by the user. */
8741                 if (priv->con_ip4_config)
8742                         nm_ip4_config_intersect (priv->con_ip4_config, priv->ext_ip4_config);
8743                 if (priv->dev_ip4_config)
8744                         nm_ip4_config_intersect (priv->dev_ip4_config, priv->ext_ip4_config);
8745
8746                 g_slist_foreach (priv->vpn4_configs, _ip4_config_intersect, priv->ext_ip4_config);
8747
8748                 if (priv->wwan_ip4_config)
8749                         nm_ip4_config_intersect (priv->wwan_ip4_config, priv->ext_ip4_config);
8750
8751                 /* Remove parts from ext_ip4_config to only contain the information that
8752                  * was configured externally -- we already have the same configuration from
8753                  * internal origins. */
8754                 if (priv->con_ip4_config)
8755                         nm_ip4_config_subtract (priv->ext_ip4_config, priv->con_ip4_config);
8756                 if (priv->dev_ip4_config)
8757                         nm_ip4_config_subtract (priv->ext_ip4_config, priv->dev_ip4_config);
8758
8759                 g_slist_foreach (priv->vpn4_configs, _ip4_config_subtract, priv->ext_ip4_config);
8760
8761                 if (priv->wwan_ip4_config)
8762                         nm_ip4_config_subtract (priv->ext_ip4_config, priv->wwan_ip4_config);
8763
8764                 ip4_config_merge_and_apply (self, NULL, FALSE, NULL);
8765         }
8766 }
8767
8768 static void
8769 _ip6_config_intersect (gpointer value, gpointer user_data)
8770 {
8771         NMIP6Config *dst = (NMIP6Config *) value;
8772         NMIP6Config *src = (NMIP6Config *) user_data;
8773
8774         nm_ip6_config_intersect (dst, src);
8775 }
8776
8777 static void
8778 _ip6_config_subtract (gpointer value, gpointer user_data)
8779 {
8780         NMIP6Config *dst = (NMIP6Config *) user_data;
8781         NMIP6Config *src = (NMIP6Config *) value;
8782
8783         nm_ip6_config_subtract (dst, src);
8784 }
8785
8786 static void
8787 update_ip6_config (NMDevice *self, gboolean initial)
8788 {
8789         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8790         int ifindex;
8791         gboolean capture_resolv_conf;
8792         NMDnsManagerResolvConfMode resolv_conf_mode;
8793
8794         ifindex = nm_device_get_ip_ifindex (self);
8795         if (!ifindex)
8796                 return;
8797
8798         resolv_conf_mode = nm_dns_manager_get_resolv_conf_mode (nm_dns_manager_get ());
8799         capture_resolv_conf = initial && (resolv_conf_mode == NM_DNS_MANAGER_RESOLV_CONF_EXPLICIT);
8800
8801         /* IPv6 */
8802         g_clear_object (&priv->ext_ip6_config);
8803         g_clear_object (&priv->ext_ip6_config_captured);
8804         priv->ext_ip6_config_captured = nm_ip6_config_capture (ifindex, capture_resolv_conf, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
8805         if (priv->ext_ip6_config_captured) {
8806
8807                 priv->ext_ip6_config = nm_ip6_config_new_cloned (priv->ext_ip6_config_captured);
8808
8809                 /* This function was called upon external changes. Remove the configuration
8810                  * (addresses,routes) that is no longer present externally from the internal
8811                  * config. This way, we don't re-add addresses that were manually removed
8812                  * by the user. */
8813                 if (priv->con_ip6_config)
8814                         nm_ip6_config_intersect (priv->con_ip6_config, priv->ext_ip6_config);
8815                 if (priv->ac_ip6_config)
8816                         nm_ip6_config_intersect (priv->ac_ip6_config, priv->ext_ip6_config);
8817                 if (priv->dhcp6_ip6_config)
8818                         nm_ip6_config_intersect (priv->dhcp6_ip6_config, priv->ext_ip6_config);
8819                 if (priv->wwan_ip6_config)
8820                         nm_ip6_config_intersect (priv->wwan_ip6_config, priv->ext_ip6_config);
8821                 g_slist_foreach (priv->vpn6_configs, _ip6_config_intersect, priv->ext_ip6_config);
8822
8823                 /* Remove parts from ext_ip6_config to only contain the information that
8824                  * was configured externally -- we already have the same configuration from
8825                  * internal origins. */
8826                 if (priv->con_ip6_config)
8827                         nm_ip6_config_subtract (priv->ext_ip6_config, priv->con_ip6_config);
8828                 if (priv->ac_ip6_config)
8829                         nm_ip6_config_subtract (priv->ext_ip6_config, priv->ac_ip6_config);
8830                 if (priv->dhcp6_ip6_config)
8831                         nm_ip6_config_subtract (priv->ext_ip6_config, priv->dhcp6_ip6_config);
8832                 if (priv->wwan_ip6_config)
8833                         nm_ip6_config_subtract (priv->ext_ip6_config, priv->wwan_ip6_config);
8834                 g_slist_foreach (priv->vpn6_configs, _ip6_config_subtract, priv->ext_ip6_config);
8835
8836                 ip6_config_merge_and_apply (self, FALSE, NULL);
8837         }
8838
8839         if (   priv->linklocal6_timeout_id
8840             && priv->ext_ip6_config_captured
8841             && nm_ip6_config_get_address_first_nontentative (priv->ext_ip6_config_captured, TRUE)) {
8842                 /* linklocal6 is ready now, do the state transition... we are also
8843                  * invoked as g_idle_add, so no problems with reentrance doing it now.
8844                  */
8845                 linklocal6_complete (self);
8846         }
8847 }
8848
8849 void
8850 nm_device_capture_initial_config (NMDevice *self)
8851 {
8852         update_ip4_config (self, TRUE);
8853         update_ip6_config (self, TRUE);
8854 }
8855
8856 static gboolean
8857 queued_ip4_config_change (gpointer user_data)
8858 {
8859         NMDevice *self = NM_DEVICE (user_data);
8860         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8861
8862         /* Wait for any queued state changes */
8863         if (priv->queued_state.id)
8864                 return TRUE;
8865
8866         priv->queued_ip4_config_id = 0;
8867         g_object_ref (self);
8868         update_ip4_config (self, FALSE);
8869         g_object_unref (self);
8870
8871         return FALSE;
8872 }
8873
8874 static gboolean
8875 queued_ip6_config_change (gpointer user_data)
8876 {
8877         NMDevice *self = NM_DEVICE (user_data);
8878         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8879         GSList *iter;
8880         gboolean need_ipv6ll = FALSE;
8881
8882         /* Wait for any queued state changes */
8883         if (priv->queued_state.id)
8884                 return TRUE;
8885
8886         priv->queued_ip6_config_id = 0;
8887         g_object_ref (self);
8888         update_ip6_config (self, FALSE);
8889
8890         if (   nm_platform_link_get (NM_PLATFORM_GET, priv->ifindex)
8891             && priv->state < NM_DEVICE_STATE_DEACTIVATING) {
8892                 /* Handle DAD falures */
8893                 for (iter = priv->dad6_failed_addrs; iter; iter = g_slist_next (iter)) {
8894                         NMPlatformIP6Address *addr = iter->data;
8895
8896                         if (addr->source >= NM_IP_CONFIG_SOURCE_USER)
8897                                 continue;
8898
8899                         _LOGI (LOGD_IP6, "ipv6: duplicate address check failed for the %s address",
8900                                nm_platform_ip6_address_to_string (addr, NULL, 0));
8901
8902                         if (IN6_IS_ADDR_LINKLOCAL (&addr->address))
8903                                 need_ipv6ll = TRUE;
8904                         else if (priv->rdisc)
8905                                 nm_rdisc_dad_failed (priv->rdisc, &addr->address);
8906                 }
8907
8908                 /* If no IPv6 link-local address exists but other addresses do then we
8909                  * must add the LL address to remain conformant with RFC 3513 chapter 2.1
8910                  * ("Addressing Model"): "All interfaces are required to have at least
8911                  * one link-local unicast address".
8912                  */
8913                 if (priv->ip6_config && nm_ip6_config_get_num_addresses (priv->ip6_config))
8914                         need_ipv6ll = TRUE;
8915
8916                 if (need_ipv6ll)
8917                         check_and_add_ipv6ll_addr (self);
8918         }
8919
8920         g_slist_free_full (priv->dad6_failed_addrs, g_free);
8921         priv->dad6_failed_addrs = NULL;
8922
8923         g_object_unref (self);
8924
8925         return FALSE;
8926 }
8927
8928 static void
8929 device_ipx_changed (NMPlatform *platform,
8930                     NMPObjectType obj_type,
8931                     int ifindex,
8932                     gpointer platform_object,
8933                     NMPlatformSignalChangeType change_type,
8934                     NMDevice *self)
8935 {
8936         NMDevicePrivate *priv;
8937         NMPlatformIP6Address *addr;
8938
8939         if (nm_device_get_ip_ifindex (self) != ifindex)
8940                 return;
8941
8942         priv = NM_DEVICE_GET_PRIVATE (self);
8943
8944         switch (obj_type) {
8945         case NMP_OBJECT_TYPE_IP4_ADDRESS:
8946         case NMP_OBJECT_TYPE_IP4_ROUTE:
8947                 if (!priv->queued_ip4_config_id) {
8948                         priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
8949                         _LOGD (LOGD_DEVICE, "queued IP4 config change");
8950                 }
8951                 break;
8952         case NMP_OBJECT_TYPE_IP6_ADDRESS:
8953                 addr = platform_object;
8954
8955                 if (   priv->state > NM_DEVICE_STATE_DISCONNECTED
8956                     && priv->state < NM_DEVICE_STATE_DEACTIVATING
8957                     && (   (change_type == NM_PLATFORM_SIGNAL_CHANGED && addr->n_ifa_flags & IFA_F_DADFAILED)
8958                         || (change_type == NM_PLATFORM_SIGNAL_REMOVED && addr->n_ifa_flags & IFA_F_TENTATIVE))) {
8959                         priv->dad6_failed_addrs = g_slist_append (priv->dad6_failed_addrs,
8960                                                                   g_memdup (addr, sizeof (NMPlatformIP6Address)));
8961                 }
8962                 /* fallthrough */
8963         case NMP_OBJECT_TYPE_IP6_ROUTE:
8964                 if (!priv->queued_ip6_config_id) {
8965                         priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
8966                         _LOGD (LOGD_DEVICE, "queued IP6 config change");
8967                 }
8968                 break;
8969         default:
8970                 g_return_if_reached ();
8971         }
8972 }
8973
8974 /*****************************************************************************/
8975
8976 NM_UTILS_FLAGS2STR_DEFINE (nm_unmanaged_flags2str, NMUnmanagedFlags,
8977         NM_UTILS_FLAGS2STR (NM_UNMANAGED_SLEEPING, "sleeping"),
8978         NM_UTILS_FLAGS2STR (NM_UNMANAGED_QUITTING, "quitting"),
8979         NM_UTILS_FLAGS2STR (NM_UNMANAGED_PARENT, "parent"),
8980         NM_UTILS_FLAGS2STR (NM_UNMANAGED_LOOPBACK, "loopback"),
8981         NM_UTILS_FLAGS2STR (NM_UNMANAGED_PLATFORM_INIT, "platform-init"),
8982         NM_UTILS_FLAGS2STR (NM_UNMANAGED_USER_EXPLICIT, "user-explicit"),
8983         NM_UTILS_FLAGS2STR (NM_UNMANAGED_BY_DEFAULT, "by-default"),
8984         NM_UTILS_FLAGS2STR (NM_UNMANAGED_USER_SETTINGS, "user-settings"),
8985         NM_UTILS_FLAGS2STR (NM_UNMANAGED_USER_UDEV, "user-udev"),
8986         NM_UTILS_FLAGS2STR (NM_UNMANAGED_EXTERNAL_DOWN, "external-down"),
8987         NM_UTILS_FLAGS2STR (NM_UNMANAGED_IS_SLAVE, "is-slave"),
8988 );
8989
8990 static const char *
8991 _unmanaged_flags2str (NMUnmanagedFlags flags, NMUnmanagedFlags mask, char *buf, gsize len)
8992 {
8993         char buf2[512];
8994         char *b;
8995         char *tmp, *tmp2;
8996         gsize l;
8997
8998         nm_utils_to_string_buffer_init (&buf, &len);
8999         if (!len)
9000                 return buf;
9001
9002         b = buf;
9003
9004         mask |= flags;
9005
9006         nm_unmanaged_flags2str (flags, b, len);
9007         l = strlen (b);
9008         b += l;
9009         len -= l;
9010
9011         nm_unmanaged_flags2str (mask & ~flags, buf2, sizeof (buf2));
9012         if (buf2[0]) {
9013                 gboolean add_separator = l > 0;
9014
9015                 tmp = buf2;
9016                 while (TRUE) {
9017                         if (add_separator)
9018                                 nm_utils_strbuf_append_c (&b, &len, ',');
9019                         add_separator = TRUE;
9020
9021                         tmp2 = strchr (tmp, ',');
9022                         if (tmp2)
9023                                 tmp2[0] = '\0';
9024
9025                         nm_utils_strbuf_append_c (&b, &len, '!');
9026                         nm_utils_strbuf_append_str (&b, &len, tmp);
9027                         if (!tmp2)
9028                                 break;
9029
9030                         tmp = &tmp2[1];
9031                 }
9032         }
9033
9034         return buf;
9035 }
9036
9037 static gboolean
9038 _get_managed_by_flags(NMUnmanagedFlags flags, NMUnmanagedFlags mask, gboolean for_user_request)
9039 {
9040         /* Evaluate the managed state based on the unmanaged flags.
9041          *
9042          * Some flags are authoritative, meaning they always cause
9043          * the device to be unmanaged (e.g. @NM_UNMANAGED_PLATFORM_INIT).
9044          *
9045          * OTOH, some flags can be overwritten. For example NM_UNMANAGED_USER_SETTINGS
9046          * is ignored once NM_UNMANAGED_USER_EXPLICIT is set. The idea is that
9047          * the flag from the configuration has no effect once the user explicitly
9048          * touches the unmanaged flags. */
9049
9050         if (for_user_request) {
9051
9052                 /* @for_user_request can make the result only ~more~ managed.
9053                  * If the flags already indicate a managed state for a non-user-request,
9054                  * then it is also managed for an explict user-request.
9055                  *
9056                  * Effectively, this check is redundant, as the code below already
9057                  * already ensures that. Still, express this invariant explictly here. */
9058                 if (_get_managed_by_flags (flags, mask, FALSE))
9059                         return TRUE;
9060
9061                 /* A for-user-request, is effectively the same as pretending
9062                  * that user-dbus flag is cleared. */
9063                 mask |= NM_UNMANAGED_USER_EXPLICIT;
9064                 flags &= ~NM_UNMANAGED_USER_EXPLICIT;
9065         }
9066
9067         if (   NM_FLAGS_ANY (mask, NM_UNMANAGED_USER_SETTINGS)
9068             && !NM_FLAGS_ANY (flags, NM_UNMANAGED_USER_SETTINGS)) {
9069                 /* NM_UNMANAGED_USER_SETTINGS can only explicitly unmanage a device. It cannot
9070                  * *manage* it. Having NM_UNMANAGED_USER_SETTINGS explicitly not set, is the
9071                  * same as having it not set at all. */
9072                 mask &= ~NM_UNMANAGED_USER_SETTINGS;
9073         }
9074
9075         if (NM_FLAGS_ANY (mask, NM_UNMANAGED_USER_UDEV)) {
9076                 /* configuration from udev or nm-config overwrites the by-default flag
9077                  * which is based on the device type. */
9078                 flags &= ~NM_UNMANAGED_BY_DEFAULT;
9079         }
9080
9081         if (   NM_FLAGS_HAS (mask, NM_UNMANAGED_IS_SLAVE)
9082             && !NM_FLAGS_HAS (flags, NM_UNMANAGED_IS_SLAVE)) {
9083                 /* for an enslaved device, by-default doesn't matter */
9084                 flags &= ~NM_UNMANAGED_BY_DEFAULT;
9085         }
9086
9087         if (NM_FLAGS_HAS (mask, NM_UNMANAGED_USER_EXPLICIT)) {
9088                 /* if the device is managed by user-decision, certain other flags
9089                  * are ignored. */
9090
9091                 flags &= ~(  NM_UNMANAGED_BY_DEFAULT
9092                            | NM_UNMANAGED_USER_UDEV
9093                            | NM_UNMANAGED_EXTERNAL_DOWN);
9094         }
9095
9096         return flags == NM_UNMANAGED_NONE;
9097 }
9098
9099 /**
9100  * nm_device_get_managed:
9101  * @self: the #NMDevice
9102  * @for_user_request: whether to check the flags for an explict user-request
9103  *
9104  * Whether the device is unmanaged according to the unmanaged flags.
9105  *
9106  * Returns: %TRUE if the device is unmanaged because of the flags.
9107  */
9108 gboolean
9109 nm_device_get_managed (NMDevice *self, gboolean for_user_request)
9110 {
9111         NMDevicePrivate *priv;
9112
9113         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
9114
9115         if (!nm_device_is_real (self)) {
9116                 /* a unrealized device is always considered unmanaged. */
9117                 return FALSE;
9118         }
9119
9120         priv = NM_DEVICE_GET_PRIVATE (self);
9121
9122         return _get_managed_by_flags (priv->unmanaged_flags, priv->unmanaged_mask, for_user_request);
9123 }
9124
9125 /**
9126  * nm_device_get_unmanaged_mask:
9127  * @self: the #NMDevice
9128  * @flag: the unmanaged flags to check.
9129  *
9130  * Return the unmanaged flags mask set on this device.
9131  *
9132  * Returns: the flags of the device ( & @flag)
9133  */
9134 NMUnmanagedFlags
9135 nm_device_get_unmanaged_mask (NMDevice *self, NMUnmanagedFlags flag)
9136 {
9137         g_return_val_if_fail (NM_IS_DEVICE (self), NM_UNMANAGED_NONE);
9138         g_return_val_if_fail (flag != NM_UNMANAGED_NONE, NM_UNMANAGED_NONE);
9139
9140         return NM_DEVICE_GET_PRIVATE (self)->unmanaged_mask & flag;
9141 }
9142
9143 /**
9144  * nm_device_get_unmanaged_flags:
9145  * @self: the #NMDevice
9146  * @flag: the unmanaged flags to check.
9147  *
9148  * Return the unmanaged flags of the device.
9149  *
9150  * Returns: the flags of the device ( & @flag)
9151  */
9152 NMUnmanagedFlags
9153 nm_device_get_unmanaged_flags (NMDevice *self, NMUnmanagedFlags flag)
9154 {
9155         g_return_val_if_fail (NM_IS_DEVICE (self), NM_UNMANAGED_NONE);
9156         g_return_val_if_fail (flag != NM_UNMANAGED_NONE, NM_UNMANAGED_NONE);
9157
9158         return NM_DEVICE_GET_PRIVATE (self)->unmanaged_flags & flag;
9159 }
9160
9161 /**
9162  * _set_unmanaged_flags:
9163  * @self: the #NMDevice instance
9164  * @flags: which #NMUnmanagedFlags to set.
9165  * @set_op: whether to set/clear/forget the flags. You can also pass
9166  *   boolean values %TRUE and %FALSE, which mean %NM_UNMAN_FLAG_OP_SET_UNMANAGED
9167  *   and %NM_UNMAN_FLAG_OP_SET_MANAGED, respectively.
9168  * @allow_state_transition: if %FALSE, setting flags never triggers a device
9169  *   state change. If %TRUE, the device can change state, if it is real and
9170  *   switches from managed to unmanaged (or vice versa).
9171  * @reason: the device state reason passed to nm_device_state_changed() if
9172  *   the device becomes managed/unmanaged. This is only relevant if the
9173  *   device switches state and if @allow_state_transition is %TRUE.
9174  *
9175  * Set the unmanaged flags of the device.
9176  **/
9177 static void
9178 _set_unmanaged_flags (NMDevice *self,
9179                       NMUnmanagedFlags flags,
9180                       NMUnmanFlagOp set_op,
9181                       gboolean allow_state_transition,
9182                       NMDeviceStateReason reason)
9183 {
9184         NMDevicePrivate *priv;
9185         gboolean was_managed, transition_state;
9186         NMUnmanagedFlags old_flags, old_mask;
9187         const char *operation = NULL;
9188         char str1[512];
9189         char str2[512];
9190
9191         g_return_if_fail (NM_IS_DEVICE (self));
9192         g_return_if_fail (flags);
9193
9194         priv = NM_DEVICE_GET_PRIVATE (self);
9195
9196         if (!priv->real)
9197                 allow_state_transition = FALSE;
9198         was_managed = allow_state_transition && nm_device_get_managed (self, FALSE);
9199
9200         old_flags = priv->unmanaged_flags;
9201         old_mask = priv->unmanaged_mask;
9202
9203         switch (set_op) {
9204         case NM_UNMAN_FLAG_OP_FORGET:
9205                 priv->unmanaged_mask &= ~flags;
9206                 priv->unmanaged_flags &= ~flags;
9207                 operation = "forget";
9208                 break;
9209         case NM_UNMAN_FLAG_OP_SET_UNMANAGED:
9210                 priv->unmanaged_mask |= flags;
9211                 priv->unmanaged_flags |= flags;
9212                 operation = "set-unmanaged";
9213                 break;
9214         case NM_UNMAN_FLAG_OP_SET_MANAGED:
9215                 priv->unmanaged_mask |= flags;
9216                 priv->unmanaged_flags &= ~flags;
9217                 operation = "set-managed";
9218                 break;
9219         default:
9220                 g_return_if_reached ();
9221         }
9222
9223         if (   old_flags == priv->unmanaged_flags
9224             && old_mask == priv->unmanaged_mask)
9225                 return;
9226
9227         transition_state =    allow_state_transition
9228                            && was_managed != nm_device_get_managed (self, FALSE)
9229                            && (   was_managed
9230                                || (   !was_managed
9231                                    && nm_device_get_state (self) == NM_DEVICE_STATE_UNMANAGED));
9232
9233 #define _FMTX "[%s%s0x%0x/0x%x/%s"
9234 #define _FMT(flags, mask, str) \
9235         _unmanaged_flags2str ((flags), (mask), str, sizeof (str)), \
9236         ((flags) | (mask)) ? "=" : "", \
9237         (flags), \
9238         (mask), \
9239         (_get_managed_by_flags (flags, mask, FALSE) \
9240              ? "managed" \
9241              : (_get_managed_by_flags (flags, mask, TRUE) \
9242                     ? "manageable" \
9243                     : "unmanaged"))
9244         _LOGD (LOGD_DEVICE, "unmanaged: flags set to "_FMTX"%s, %s [%s=0x%0x]%s%s%s)",
9245                _FMT (priv->unmanaged_flags, priv->unmanaged_mask, str1),
9246                priv->real ? "" : "/unrealized",
9247                operation,
9248                nm_unmanaged_flags2str (flags, str2, sizeof (str2)),
9249                flags,
9250                NM_PRINT_FMT_QUOTED (allow_state_transition,
9251                                     ", reason ",
9252                                     reason_to_string (reason),
9253                                     transition_state ? ", transition-state" : "",
9254                                     ""));
9255 #undef _FMT
9256
9257         if (transition_state) {
9258                 if (was_managed)
9259                         nm_device_state_changed (self, NM_DEVICE_STATE_UNMANAGED, reason);
9260                 else
9261                         nm_device_state_changed (self, NM_DEVICE_STATE_UNAVAILABLE, reason);
9262         }
9263 }
9264
9265 /**
9266  * @self: the #NMDevice instance
9267  * @flags: which #NMUnmanagedFlags to set.
9268  * @set_op: whether to set/clear/forget the flags. You can also pass
9269  *   boolean values %TRUE and %FALSE, which mean %NM_UNMAN_FLAG_OP_SET_UNMANAGED
9270  *   and %NM_UNMAN_FLAG_OP_SET_MANAGED, respectively.
9271  *
9272  * Set the unmanaged flags of the device (does not trigger a state change).
9273  **/
9274 void
9275 nm_device_set_unmanaged_flags (NMDevice *self,
9276                                NMUnmanagedFlags flags,
9277                                NMUnmanFlagOp set_op)
9278 {
9279         _set_unmanaged_flags (self, flags, set_op, FALSE, NM_DEVICE_STATE_REASON_NONE);
9280 }
9281
9282 /**
9283  * nm_device_set_unmanaged_by_flags:
9284  * @self: the #NMDevice instance
9285  * @flags: which #NMUnmanagedFlags to set.
9286  * @set_op: whether to set/clear/forget the flags. You can also pass
9287  *   boolean values %TRUE and %FALSE, which mean %NM_UNMAN_FLAG_OP_SET_UNMANAGED
9288  *   and %NM_UNMAN_FLAG_OP_SET_MANAGED, respectively.
9289  * @reason: the device state reason passed to nm_device_state_changed() if
9290  *   the device becomes managed/unmanaged.
9291  *
9292  * Set the unmanaged flags of the device and possibly trigger a state change.
9293  **/
9294 void
9295 nm_device_set_unmanaged_by_flags (NMDevice *self,
9296                                   NMUnmanagedFlags flags,
9297                                   NMUnmanFlagOp set_op,
9298                                   NMDeviceStateReason reason)
9299 {
9300         _set_unmanaged_flags (self, flags, set_op, TRUE, reason);
9301 }
9302
9303 void
9304 nm_device_set_unmanaged_by_user_config (NMDevice *self, const GSList *unmanaged_specs)
9305 {
9306         NMDevicePrivate *priv;
9307         gboolean unmanaged;
9308
9309         g_return_if_fail (NM_IS_DEVICE (self));
9310
9311         priv = NM_DEVICE_GET_PRIVATE (self);
9312
9313         unmanaged = nm_device_spec_match_list (self, unmanaged_specs);
9314
9315         nm_device_set_unmanaged_by_flags (self,
9316                                           NM_UNMANAGED_USER_SETTINGS,
9317                                           unmanaged,
9318                                           unmanaged
9319                                               ? NM_DEVICE_STATE_REASON_NOW_UNMANAGED
9320                                               : NM_DEVICE_STATE_REASON_NOW_MANAGED);
9321 }
9322
9323 void
9324 nm_device_set_unmanaged_by_user_udev (NMDevice *self)
9325 {
9326         int ifindex;
9327         gboolean platform_unmanaged = FALSE;
9328
9329         ifindex = self->priv->ifindex;
9330
9331         if (   ifindex <= 0
9332             || !nm_platform_link_get_unmanaged (NM_PLATFORM_GET, ifindex, &platform_unmanaged))
9333                 return;
9334
9335         nm_device_set_unmanaged_by_flags (self,
9336                                           NM_UNMANAGED_USER_UDEV,
9337                                           platform_unmanaged,
9338                                           NM_DEVICE_STATE_REASON_USER_REQUESTED);
9339 }
9340
9341 void
9342 nm_device_set_unmanaged_by_quitting (NMDevice *self)
9343 {
9344         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9345         gboolean need_deactivate = nm_device_is_activating (self) ||
9346                                    priv->state == NM_DEVICE_STATE_ACTIVATED;
9347
9348         /* It's OK to block here because we're quitting */
9349         if (need_deactivate)
9350                 _set_state_full (self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_NOW_UNMANAGED, TRUE);
9351
9352         nm_device_set_unmanaged_by_flags (self,
9353                                           NM_UNMANAGED_QUITTING,
9354                                           TRUE,
9355                                           need_deactivate ? NM_DEVICE_STATE_REASON_REMOVED
9356                                                           : NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
9357 }
9358
9359 /*****************************************************************************/
9360
9361 void
9362 nm_device_set_dhcp_timeout (NMDevice *self, guint32 timeout)
9363 {
9364         g_return_if_fail (NM_IS_DEVICE (self));
9365
9366         NM_DEVICE_GET_PRIVATE (self)->dhcp_timeout = timeout;
9367 }
9368
9369 void
9370 nm_device_set_dhcp_anycast_address (NMDevice *self, const char *addr)
9371 {
9372         NMDevicePrivate *priv;
9373
9374         g_return_if_fail (NM_IS_DEVICE (self));
9375         g_return_if_fail (!addr || nm_utils_hwaddr_valid (addr, ETH_ALEN));
9376
9377         priv = NM_DEVICE_GET_PRIVATE (self);
9378
9379         g_free (priv->dhcp_anycast_address);
9380         priv->dhcp_anycast_address = g_strdup (addr);
9381 }
9382
9383 void
9384 nm_device_reapply_settings_immediately (NMDevice *self)
9385 {
9386         NMConnection *applied_connection;
9387         NMSettingsConnection *settings_connection;
9388         NMDeviceState state;
9389         NMSettingConnection *s_con_settings;
9390         NMSettingConnection *s_con_applied;
9391         const char *zone;
9392         NMMetered metered;
9393         guint64 version_id;
9394
9395         g_return_if_fail (NM_IS_DEVICE (self));
9396
9397         state = nm_device_get_state (self);
9398         if (   state <= NM_DEVICE_STATE_DISCONNECTED
9399             || state > NM_DEVICE_STATE_ACTIVATED)
9400                 return;
9401
9402         applied_connection = nm_device_get_applied_connection (self);
9403         settings_connection = nm_device_get_settings_connection (self);
9404
9405         if (!nm_settings_connection_has_unmodified_applied_connection (settings_connection,
9406                                                                        applied_connection,
9407                                                                        NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY))
9408                 return;
9409
9410         s_con_settings = nm_connection_get_setting_connection ((NMConnection *) settings_connection);
9411         s_con_applied = nm_connection_get_setting_connection (applied_connection);
9412
9413         if (g_strcmp0 ((zone = nm_setting_connection_get_zone (s_con_settings)),
9414                        nm_setting_connection_get_zone (s_con_applied)) != 0) {
9415
9416                 version_id = nm_active_connection_version_id_bump ((NMActiveConnection *) self->priv->act_request);
9417                 _LOGD (LOGD_DEVICE, "reapply setting: zone = %s%s%s (version-id %llu)", NM_PRINT_FMT_QUOTE_STRING (zone), (long long unsigned) version_id);
9418
9419                 g_object_set (G_OBJECT (s_con_applied),
9420                               NM_SETTING_CONNECTION_ZONE, zone,
9421                               NULL);
9422
9423                 nm_device_update_firewall_zone (self);
9424         }
9425
9426         if ((metered = nm_setting_connection_get_metered (s_con_settings)) != nm_setting_connection_get_metered (s_con_applied)) {
9427
9428                 version_id = nm_active_connection_version_id_bump ((NMActiveConnection *) self->priv->act_request);
9429                 _LOGD (LOGD_DEVICE, "reapply setting: metered = %d (version-id %llu)", (int) metered, (long long unsigned) version_id);
9430
9431                 g_object_set (G_OBJECT (s_con_applied),
9432                               NM_SETTING_CONNECTION_METERED, metered,
9433                               NULL);
9434
9435                 nm_device_update_metered (self);
9436         }
9437 }
9438
9439 void
9440 nm_device_update_firewall_zone (NMDevice *self)
9441 {
9442         NMConnection *applied_connection;
9443         NMSettingConnection *s_con;
9444
9445         g_return_if_fail (NM_IS_DEVICE (self));
9446
9447         applied_connection = nm_device_get_applied_connection (self);
9448         if (!applied_connection)
9449                 return;
9450
9451         s_con = nm_connection_get_setting_connection (applied_connection);
9452         if (    nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED
9453             && !nm_device_uses_assumed_connection (self)) {
9454                 nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
9455                                                         nm_device_get_ip_iface (self),
9456                                                         nm_setting_connection_get_zone (s_con),
9457                                                         FALSE, /* change zone */
9458                                                         NULL,
9459                                                         NULL);
9460         }
9461 }
9462
9463 void
9464 nm_device_update_metered (NMDevice *self)
9465 {
9466 #define NM_METERED_INVALID ((NMMetered) -1)
9467         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9468         NMSettingConnection *setting;
9469         NMMetered conn_value, value = NM_METERED_INVALID;
9470         NMConnection *connection = NULL;
9471         NMDeviceState state;
9472
9473         g_return_if_fail (NM_IS_DEVICE (self));
9474
9475         state = nm_device_get_state (self);
9476         if (   state <= NM_DEVICE_STATE_DISCONNECTED
9477             || state > NM_DEVICE_STATE_ACTIVATED)
9478                 value = NM_METERED_UNKNOWN;
9479
9480         if (value == NM_METERED_INVALID) {
9481                 connection = nm_device_get_applied_connection (self);
9482                 if (connection) {
9483                         setting = nm_connection_get_setting_connection (connection);
9484                         if (setting) {
9485                                 conn_value = nm_setting_connection_get_metered (setting);
9486                                 if (conn_value != NM_METERED_UNKNOWN)
9487                                         value = conn_value;
9488                         }
9489                 }
9490         }
9491
9492         /* Try to guess a value using the metered flag in IP configuration */
9493         if (value == NM_METERED_INVALID) {
9494                 if (   priv->ip4_config
9495                     && priv->ip4_state == IP_DONE
9496                     && nm_ip4_config_get_metered (priv->ip4_config))
9497                         value = NM_METERED_GUESS_YES;
9498         }
9499
9500         /* Otherwise look at connection type */
9501         if (value == NM_METERED_INVALID) {
9502                 if (   nm_connection_is_type (connection, NM_SETTING_GSM_SETTING_NAME)
9503                     || nm_connection_is_type (connection, NM_SETTING_CDMA_SETTING_NAME))
9504                         value = NM_METERED_GUESS_YES;
9505                 else
9506                         value = NM_METERED_GUESS_NO;
9507         }
9508
9509         if (value != priv->metered) {
9510                 _LOGD (LOGD_DEVICE, "set metered value %d", value);
9511                 priv->metered = value;
9512                 _notify (self, PROP_METERED);
9513         }
9514 }
9515
9516 static gboolean
9517 _nm_device_check_connection_available (NMDevice *self,
9518                                        NMConnection *connection,
9519                                        NMDeviceCheckConAvailableFlags flags,
9520                                        const char *specific_object)
9521 {
9522         NMDeviceState state;
9523
9524         /* an unrealized software device is always available, hardware devices never. */
9525         if (!nm_device_is_real (self)) {
9526                 if (nm_device_is_software (self))
9527                         return nm_device_check_connection_compatible (self, connection);
9528                 return FALSE;
9529         }
9530
9531         state = nm_device_get_state (self);
9532         if (state < NM_DEVICE_STATE_UNMANAGED)
9533                 return FALSE;
9534         if (   state < NM_DEVICE_STATE_UNAVAILABLE
9535             && (   (   !NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST)
9536                     && !nm_device_get_managed (self, FALSE))
9537                 || (    NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST)
9538                     && !nm_device_get_managed (self, TRUE))))
9539                 return FALSE;
9540         if (   state < NM_DEVICE_STATE_DISCONNECTED
9541             && !nm_device_is_software (self)
9542             && (   (   !NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST)
9543                     && !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE))
9544                 || (    NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST)
9545                     && !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST))))
9546                 return FALSE;
9547
9548         if (!nm_device_check_connection_compatible (self, connection))
9549                 return FALSE;
9550
9551         return NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, flags, specific_object);
9552 }
9553
9554 /**
9555  * nm_device_check_connection_available():
9556  * @self: the #NMDevice
9557  * @connection: the #NMConnection to check for availability
9558  * @flags: flags to affect the decision making of whether a connection
9559  *   is available. Adding a flag can only make a connection more available,
9560  *   not less.
9561  * @specific_object: a device type dependent argument to further
9562  *   filter the result. Passing a non %NULL specific object can only reduce
9563  *   the availability of a connection.
9564  *
9565  * Check if @connection is available to be activated on @self.
9566  *
9567  * Returns: %TRUE if @connection can be activated on @self
9568  */
9569 gboolean
9570 nm_device_check_connection_available (NMDevice *self,
9571                                       NMConnection *connection,
9572                                       NMDeviceCheckConAvailableFlags flags,
9573                                       const char *specific_object)
9574 {
9575         gboolean available;
9576
9577         available = _nm_device_check_connection_available (self, connection, flags, specific_object);
9578
9579 #if NM_MORE_ASSERTS >= 2
9580         {
9581                 /* The meaning of the flags is so that *adding* a flag relaxes a condition, thus making
9582                  * the device *more* available. Assert against that requirement by testing all the flags. */
9583                 NMDeviceCheckConAvailableFlags i, j, k;
9584                 gboolean available_all[NM_DEVICE_CHECK_CON_AVAILABLE_ALL + 1] = { FALSE };
9585
9586                 for (i = 0; i <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; i++)
9587                         available_all[i] = _nm_device_check_connection_available (self, connection, i, specific_object);
9588
9589                 for (i = 0; i <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; i++) {
9590                         for (j = 1; j <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; j <<= 1) {
9591                                 if (NM_FLAGS_HAS (i, j)) {
9592                                         k = i & ~j;
9593                                         nm_assert (   available_all[i] == available_all[k]
9594                                                    || available_all[i]);
9595                                 }
9596                         }
9597                 }
9598         }
9599 #endif
9600
9601         return available;
9602 }
9603
9604 static void
9605 available_connections_notify (NMDevice *self)
9606 {
9607         _notify (self, PROP_AVAILABLE_CONNECTIONS);
9608 }
9609
9610 static gboolean
9611 available_connections_del_all (NMDevice *self)
9612 {
9613         if (g_hash_table_size (self->priv->available_connections) == 0)
9614                 return FALSE;
9615         g_hash_table_remove_all (self->priv->available_connections);
9616         return TRUE;
9617 }
9618
9619 static gboolean
9620 available_connections_add (NMDevice *self, NMConnection *connection)
9621 {
9622         return nm_g_hash_table_add (self->priv->available_connections, g_object_ref (connection));
9623 }
9624
9625 static gboolean
9626 available_connections_del (NMDevice *self, NMConnection *connection)
9627 {
9628         return g_hash_table_remove (self->priv->available_connections, connection);
9629 }
9630
9631 static gboolean
9632 check_connection_available (NMDevice *self,
9633                             NMConnection *connection,
9634                             NMDeviceCheckConAvailableFlags flags,
9635                             const char *specific_object)
9636 {
9637         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
9638
9639         /* Connections which require a network connection are not available when
9640          * the device has no carrier, even with ignore-carrer=TRUE.
9641          */
9642         if (   priv->carrier
9643             || !connection_requires_carrier (connection))
9644                 return TRUE;
9645
9646         if (   NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)
9647             && priv->carrier_wait_id != 0) {
9648                 /* The device has no carrier though the connection requires it.
9649                  *
9650                  * If we are still waiting for carrier, the connection is available
9651                  * for an explicit user-request. */
9652                 return TRUE;
9653         }
9654
9655         return FALSE;
9656 }
9657
9658 void
9659 nm_device_recheck_available_connections (NMDevice *self)
9660 {
9661         NMDevicePrivate *priv;
9662         const GSList *connections, *iter;
9663         gboolean changed = FALSE;
9664         GHashTableIter h_iter;
9665         NMConnection *connection;
9666
9667         g_return_if_fail (NM_IS_DEVICE (self));
9668
9669         priv = NM_DEVICE_GET_PRIVATE(self);
9670
9671         if (priv->con_provider) {
9672                 gs_unref_hashtable GHashTable *prune_list = NULL;
9673
9674                 if (g_hash_table_size (priv->available_connections) > 0) {
9675                         prune_list = g_hash_table_new (g_direct_hash, g_direct_equal);
9676                         g_hash_table_iter_init (&h_iter, priv->available_connections);
9677                         while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL))
9678                                 g_hash_table_add (prune_list, connection);
9679                 }
9680
9681                 connections = nm_connection_provider_get_connections (priv->con_provider);
9682                 for (iter = connections; iter; iter = g_slist_next (iter)) {
9683                         connection = NM_CONNECTION (iter->data);
9684
9685                         if (nm_device_check_connection_available (self,
9686                                                                   connection,
9687                                                                   NM_DEVICE_CHECK_CON_AVAILABLE_NONE,
9688                                                                   NULL)) {
9689                                 if (available_connections_add (self, connection))
9690                                         changed = TRUE;
9691                                 if (prune_list)
9692                                         g_hash_table_remove (prune_list, connection);
9693                         }
9694                 }
9695
9696                 if (prune_list) {
9697                         g_hash_table_iter_init (&h_iter, prune_list);
9698                         while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL)) {
9699                                 if (available_connections_del (self, connection))
9700                                         changed = TRUE;
9701                         }
9702                 }
9703         } else {
9704                 if (available_connections_del_all (self))
9705                         changed = TRUE;
9706         }
9707
9708         if (changed)
9709                 available_connections_notify (self);
9710         available_connections_check_delete_unrealized (self);
9711 }
9712
9713 /**
9714  * nm_device_get_best_connection:
9715  * @self: the #NMDevice
9716  * @specific_object: a specific object path if any
9717  * @error: reason why no connection was returned
9718  *
9719  * Returns a connection that's most suitable for user-initiated activation
9720  * of a device, optionally with a given specific object.
9721  *
9722  * Returns: the #NMSettingsConnection or %NULL (setting an @error)
9723  */
9724 NMSettingsConnection *
9725 nm_device_get_best_connection (NMDevice *self,
9726                                const char *specific_object,
9727                                GError **error)
9728 {
9729         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9730         NMSettingsConnection *connection = NULL;
9731         NMSettingsConnection *candidate;
9732         guint64 best_timestamp = 0;
9733         GHashTableIter iter;
9734
9735         g_hash_table_iter_init (&iter, priv->available_connections);
9736         while (g_hash_table_iter_next (&iter, (gpointer) &candidate, NULL)) {
9737                 guint64 candidate_timestamp = 0;
9738
9739                 /* If a specific object is given, only include connections that are
9740                  * compatible with it.
9741                  */
9742                 if (    specific_object /* << Optimization: we know that the connection is available without @specific_object.  */
9743                     && !nm_device_check_connection_available (self,
9744                                                               NM_CONNECTION (candidate),
9745                                                               _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST,
9746                                                               specific_object))
9747                         continue;
9748
9749                 nm_settings_connection_get_timestamp (candidate, &candidate_timestamp);
9750                 if (!connection || (candidate_timestamp > best_timestamp)) {
9751                         connection = candidate;
9752                         best_timestamp = candidate_timestamp;
9753                 }
9754         }
9755
9756         if (!connection) {
9757                 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
9758                              "The device '%s' has no connections available for activation.",
9759                               nm_device_get_iface (self));
9760         }
9761
9762         return connection;
9763 }
9764
9765 static void
9766 cp_connection_added_or_updated (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
9767 {
9768         gboolean changed;
9769         NMDevice *self = user_data;
9770
9771         g_return_if_fail (NM_IS_DEVICE (self));
9772         g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection));
9773
9774         if (nm_device_check_connection_available (self,
9775                                                   connection,
9776                                                   _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST,
9777                                                   NULL))
9778                 changed = available_connections_add (self, connection);
9779         else
9780                 changed = available_connections_del (self, connection);
9781
9782         if (changed) {
9783                 available_connections_notify (self);
9784                 available_connections_check_delete_unrealized (self);
9785         }
9786 }
9787
9788 static void
9789 cp_connection_removed (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
9790 {
9791         NMDevice *self = user_data;
9792
9793         g_return_if_fail (NM_IS_DEVICE (self));
9794
9795         if (available_connections_del (self, connection)) {
9796                 available_connections_notify (self);
9797                 available_connections_check_delete_unrealized (self);
9798         }
9799 }
9800
9801 gboolean
9802 nm_device_supports_vlans (NMDevice *self)
9803 {
9804         return nm_platform_link_supports_vlans (NM_PLATFORM_GET, nm_device_get_ifindex (self));
9805 }
9806
9807 /**
9808  * nm_device_add_pending_action():
9809  * @self: the #NMDevice to add the pending action to
9810  * @action: a static string that identifies the action
9811  * @assert_not_yet_pending: if %TRUE, assert that the @action is currently not yet pending.
9812  * Otherwise, ignore duplicate scheduling of the same action silently.
9813  *
9814  * Adds a pending action to the device.
9815  *
9816  * Returns: %TRUE if the action was added (and not already added before). %FALSE
9817  * if the same action is already scheduled. In the latter case, the action was not scheduled
9818  * a second time.
9819  */
9820 gboolean
9821 nm_device_add_pending_action (NMDevice *self, const char *action, gboolean assert_not_yet_pending)
9822 {
9823         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9824         GSList *iter;
9825         guint count = 0;
9826
9827         g_return_val_if_fail (action, FALSE);
9828
9829         /* Check if the action is already pending. Cannot add duplicate actions */
9830         for (iter = priv->pending_actions; iter; iter = iter->next) {
9831                 if (!strcmp (action, iter->data)) {
9832                         if (assert_not_yet_pending) {
9833                                 _LOGW (LOGD_DEVICE, "add_pending_action (%d): '%s' already pending",
9834                                        count + g_slist_length (iter), action);
9835                                 g_return_val_if_reached (FALSE);
9836                         } else {
9837                                 _LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s' already pending (expected)",
9838                                        count + g_slist_length (iter), action);
9839                         }
9840                         return FALSE;
9841                 }
9842                 count++;
9843         }
9844
9845         priv->pending_actions = g_slist_append (priv->pending_actions, g_strdup (action));
9846         count++;
9847
9848         _LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s'", count, action);
9849
9850         if (count == 1)
9851                 _notify (self, PROP_HAS_PENDING_ACTION);
9852
9853         return TRUE;
9854 }
9855
9856 /**
9857  * nm_device_remove_pending_action():
9858  * @self: the #NMDevice to remove the pending action from
9859  * @action: a static string that identifies the action
9860  * @assert_is_pending: if %TRUE, assert that the @action is pending.
9861  * If %FALSE, don't do anything if the current action is not pending and
9862  * return %FALSE.
9863  *
9864  * Removes a pending action previously added by nm_device_add_pending_action().
9865  *
9866  * Returns: whether the @action was pending and is now removed.
9867  */
9868 gboolean
9869 nm_device_remove_pending_action (NMDevice *self, const char *action, gboolean assert_is_pending)
9870 {
9871         NMDevicePrivate *priv;
9872         GSList *iter, *next;
9873         guint count = 0;
9874
9875         g_return_val_if_fail (self, FALSE);
9876         g_return_val_if_fail (action, FALSE);
9877
9878         priv = NM_DEVICE_GET_PRIVATE (self);
9879
9880         for (iter = priv->pending_actions; iter; iter = next) {
9881                 next = iter->next;
9882                 if (!strcmp (action, iter->data)) {
9883                         _LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s'",
9884                                count + g_slist_length (iter->next), /* length excluding 'iter' */
9885                                action);
9886                         g_free (iter->data);
9887                         priv->pending_actions = g_slist_delete_link (priv->pending_actions, iter);
9888                         if (priv->pending_actions == NULL)
9889                                 _notify (self, PROP_HAS_PENDING_ACTION);
9890                         return TRUE;
9891                 }
9892                 count++;
9893         }
9894
9895         if (assert_is_pending) {
9896                 _LOGW (LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending", count, action);
9897                 g_return_val_if_reached (FALSE);
9898         } else
9899                 _LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending (expected)", count, action);
9900
9901         return FALSE;
9902 }
9903
9904 gboolean
9905 nm_device_has_pending_action (NMDevice *self)
9906 {
9907         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9908
9909         return !!priv->pending_actions;
9910 }
9911
9912 /***********************************************************/
9913
9914 static void
9915 _cancel_activation (NMDevice *self)
9916 {
9917         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9918
9919         /* Clean up when device was deactivated during call to firewall */
9920         if (priv->fw_call) {
9921                 nm_firewall_manager_cancel_call (priv->fw_call);
9922                 g_warn_if_fail (!priv->fw_call);
9923                 priv->fw_call = NULL;
9924         }
9925         priv->fw_ready = FALSE;
9926
9927         ip_check_gw_ping_cleanup (self);
9928
9929         /* Break the activation chain */
9930         activation_source_clear (self, AF_INET);
9931         activation_source_clear (self, AF_INET6);
9932 }
9933
9934 static void
9935 _cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type)
9936 {
9937         NMConnection *connection;
9938
9939         _cancel_activation (self);
9940
9941         connection = nm_device_get_applied_connection (self);
9942         if (   cleanup_type == CLEANUP_TYPE_DECONFIGURE
9943             && connection
9944             && !nm_device_uses_assumed_connection (self)) {
9945                 nm_firewall_manager_remove_from_zone (nm_firewall_manager_get (),
9946                                                       nm_device_get_ip_iface (self),
9947                                                       NULL,
9948                                                       NULL,
9949                                                       NULL);
9950         }
9951
9952         /* Clear any queued transitions */
9953         nm_device_queued_state_clear (self);
9954
9955         _cleanup_ip4_pre (self, cleanup_type);
9956         _cleanup_ip6_pre (self, cleanup_type);
9957 }
9958
9959 static void
9960 _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type)
9961 {
9962         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9963         NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE;
9964
9965         priv->default_route.v4_has = FALSE;
9966         priv->default_route.v6_has = FALSE;
9967
9968         if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) {
9969                 priv->default_route.v4_is_assumed = FALSE;
9970                 priv->default_route.v6_is_assumed = FALSE;
9971                 nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self);
9972                 nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self);
9973         }
9974
9975         priv->default_route.v4_is_assumed = TRUE;
9976         priv->default_route.v6_is_assumed = TRUE;
9977         nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self);
9978         nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self);
9979
9980         priv->v4_commit_first_time = TRUE;
9981         priv->v6_commit_first_time = TRUE;
9982
9983         priv->linklocal6_dad_counter = 0;
9984
9985         /* Clean up IP configs; this does not actually deconfigure the
9986          * interface; the caller must flush routes and addresses explicitly.
9987          */
9988         nm_device_set_ip4_config (self, NULL, 0, TRUE, TRUE, &ignored);
9989         nm_device_set_ip6_config (self, NULL, TRUE, TRUE, &ignored);
9990         g_clear_object (&priv->con_ip4_config);
9991         g_clear_object (&priv->dev_ip4_config);
9992         g_clear_object (&priv->ext_ip4_config);
9993         g_clear_object (&priv->wwan_ip4_config);
9994         g_clear_object (&priv->ip4_config);
9995         g_clear_object (&priv->con_ip6_config);
9996         g_clear_object (&priv->ac_ip6_config);
9997         g_clear_object (&priv->ext_ip6_config);
9998         g_clear_object (&priv->ext_ip6_config_captured);
9999         g_clear_object (&priv->wwan_ip6_config);
10000         g_clear_object (&priv->ip6_config);
10001
10002         g_slist_free_full (priv->vpn4_configs, g_object_unref);
10003         priv->vpn4_configs = NULL;
10004         g_slist_free_full (priv->vpn6_configs, g_object_unref);
10005         priv->vpn6_configs = NULL;
10006
10007         clear_act_request (self);
10008
10009         /* Clear legacy IPv4 address property */
10010         if (priv->ip4_address) {
10011                 priv->ip4_address = 0;
10012                 _notify (self, PROP_IP4_ADDRESS);
10013         }
10014
10015         if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) {
10016                 /* Check if the device was deactivated, and if so, delete_link.
10017                  * Don't call delete_link synchronously because we are currently
10018                  * handling a state change -- which is not reentrant. */
10019                 delete_on_deactivate_check_and_schedule (self, nm_device_get_ip_ifindex (self));
10020         }
10021
10022         /* ip_iface should be cleared after flushing all routes and addreses, since
10023          * those are identified by ip_iface, not by iface (which might be a tty
10024          * or ATM device).
10025          */
10026         nm_device_set_ip_iface (self, NULL);
10027 }
10028
10029 /*
10030  * nm_device_cleanup
10031  *
10032  * Remove a device's routing table entries and IP addresses.
10033  *
10034  */
10035 static void
10036 nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType cleanup_type)
10037 {
10038         NMDevicePrivate *priv;
10039         int ifindex;
10040
10041         g_return_if_fail (NM_IS_DEVICE (self));
10042
10043         if (reason == NM_DEVICE_STATE_REASON_NOW_MANAGED)
10044                 _LOGD (LOGD_DEVICE, "preparing device");
10045         else
10046                 _LOGD (LOGD_DEVICE, "deactivating device (reason '%s') [%d]", reason_to_string (reason), reason);
10047
10048         /* Save whether or not we tried IPv6 for later */
10049         priv = NM_DEVICE_GET_PRIVATE (self);
10050
10051         _cleanup_generic_pre (self, cleanup_type);
10052
10053         /* Turn off kernel IPv6 */
10054         if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) {
10055                 set_disable_ipv6 (self, "1");
10056                 nm_device_ipv6_sysctl_set (self, "accept_ra", "0");
10057                 nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0");
10058         }
10059
10060         /* Call device type-specific deactivation */
10061         if (NM_DEVICE_GET_CLASS (self)->deactivate)
10062                 NM_DEVICE_GET_CLASS (self)->deactivate (self);
10063
10064         /* master: release slaves */
10065         nm_device_master_release_slaves (self);
10066
10067         /* slave: mark no longer enslaved */
10068         if (   priv->master
10069             && nm_platform_link_get_master (NM_PLATFORM_GET, priv->ifindex) <= 0)
10070                 nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
10071
10072         /* Take out any entries in the routing table and any IP address the device had. */
10073         ifindex = nm_device_get_ip_ifindex (self);
10074         if (ifindex > 0) {
10075                 nm_route_manager_route_flush (nm_route_manager_get (), ifindex);
10076                 nm_platform_address_flush (NM_PLATFORM_GET, ifindex);
10077         }
10078
10079         if (priv->lldp_listener)
10080                 nm_lldp_listener_stop (priv->lldp_listener);
10081
10082         nm_device_update_metered (self);
10083         _cleanup_generic_post (self, cleanup_type);
10084 }
10085
10086 static char *
10087 bin2hexstr (const char *bytes, gsize len)
10088 {
10089         GString *str;
10090         int i;
10091
10092         g_return_val_if_fail (bytes != NULL, NULL);
10093         g_return_val_if_fail (len > 0, NULL);
10094
10095         str = g_string_sized_new (len * 2 + 1);
10096         for (i = 0; i < len; i++) {
10097                 if (str->len)
10098                         g_string_append_c (str, ':');
10099                 g_string_append_printf (str, "%02x", (guint8) bytes[i]);
10100         }
10101         return g_string_free (str, FALSE);
10102 }
10103
10104 static char *
10105 find_dhcp4_address (NMDevice *self)
10106 {
10107         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10108         guint i, n;
10109
10110         if (!priv->ip4_config)
10111                 return NULL;
10112
10113         n = nm_ip4_config_get_num_addresses (priv->ip4_config);
10114         for (i = 0; i < n; i++) {
10115                 const NMPlatformIP4Address *a = nm_ip4_config_get_address (priv->ip4_config, i);
10116
10117                 if (a->source == NM_IP_CONFIG_SOURCE_DHCP)
10118                         return g_strdup (nm_utils_inet4_ntop (a->address, NULL));
10119         }
10120         return NULL;
10121 }
10122
10123 void
10124 nm_device_spawn_iface_helper (NMDevice *self)
10125 {
10126         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10127         gboolean configured = FALSE;
10128         NMConnection *connection;
10129         GError *error = NULL;
10130         const char *method;
10131         GPtrArray *argv;
10132         gs_free char *dhcp4_address = NULL;
10133         char *logging_backend;
10134
10135         if (priv->state != NM_DEVICE_STATE_ACTIVATED)
10136                 return;
10137         if (!nm_device_can_assume_connections (self))
10138                 return;
10139
10140         connection = nm_device_get_applied_connection (self);
10141         g_assert (connection);
10142
10143         argv = g_ptr_array_sized_new (10);
10144         g_ptr_array_set_free_func (argv, g_free);
10145
10146         g_ptr_array_add (argv, g_strdup (LIBEXECDIR "/nm-iface-helper"));
10147         g_ptr_array_add (argv, g_strdup ("--ifname"));
10148         g_ptr_array_add (argv, g_strdup (nm_device_get_ip_iface (self)));
10149         g_ptr_array_add (argv, g_strdup ("--uuid"));
10150         g_ptr_array_add (argv, g_strdup (nm_connection_get_uuid (connection)));
10151
10152         logging_backend = nm_config_get_is_debug (nm_config_get ())
10153                           ? g_strdup ("debug")
10154                           : nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG,
10155                                                       NM_CONFIG_KEYFILE_GROUP_LOGGING,
10156                                                       NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND,
10157                                                       NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY);
10158         if (logging_backend) {
10159                 g_ptr_array_add (argv, g_strdup ("--logging-backend"));
10160                 g_ptr_array_add (argv, logging_backend);
10161         }
10162
10163         dhcp4_address = find_dhcp4_address (self);
10164
10165         method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
10166         if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) {
10167                 NMSettingIPConfig *s_ip4;
10168                 char *hex_client_id;
10169
10170                 s_ip4 = nm_connection_get_setting_ip4_config (connection);
10171                 g_assert (s_ip4);
10172
10173                 g_ptr_array_add (argv, g_strdup ("--priority4"));
10174                 g_ptr_array_add (argv, g_strdup_printf ("%u", nm_device_get_ip4_route_metric (self)));
10175
10176                 g_ptr_array_add (argv, g_strdup ("--dhcp4"));
10177                 g_ptr_array_add (argv, g_strdup (dhcp4_address));
10178                 if (nm_setting_ip_config_get_may_fail (s_ip4) == FALSE)
10179                         g_ptr_array_add (argv, g_strdup ("--dhcp4-required"));
10180
10181                 if (priv->dhcp4_client) {
10182                         const char *hostname, *fqdn;
10183                         GBytes *client_id;
10184
10185                         client_id = nm_dhcp_client_get_client_id (priv->dhcp4_client);
10186                         if (client_id) {
10187                                 g_ptr_array_add (argv, g_strdup ("--dhcp4-clientid"));
10188                                 hex_client_id = bin2hexstr (g_bytes_get_data (client_id, NULL),
10189                                                             g_bytes_get_size (client_id));
10190                                 g_ptr_array_add (argv, hex_client_id);
10191                         }
10192
10193                         hostname = nm_dhcp_client_get_hostname (priv->dhcp4_client);
10194                         if (hostname) {
10195                                 g_ptr_array_add (argv, g_strdup ("--dhcp4-hostname"));
10196                                 g_ptr_array_add (argv, g_strdup (hostname));
10197                         }
10198
10199                         fqdn = nm_dhcp_client_get_fqdn (priv->dhcp4_client);
10200                         if (fqdn) {
10201                                 g_ptr_array_add (argv, g_strdup ("--dhcp4-fqdn"));
10202                                 g_ptr_array_add (argv, g_strdup (fqdn));
10203                         }
10204                 }
10205
10206                 configured = TRUE;
10207         }
10208
10209         method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
10210         if (g_strcmp0 (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
10211                 NMSettingIPConfig *s_ip6;
10212                 char *hex_iid;
10213                 NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT;
10214
10215                 s_ip6 = nm_connection_get_setting_ip6_config (connection);
10216                 g_assert (s_ip6);
10217
10218                 g_ptr_array_add (argv, g_strdup ("--priority6"));
10219                 g_ptr_array_add (argv, g_strdup_printf ("%u", nm_device_get_ip6_route_metric (self)));
10220
10221                 g_ptr_array_add (argv, g_strdup ("--slaac"));
10222
10223                 if (nm_setting_ip_config_get_may_fail (s_ip6) == FALSE)
10224                         g_ptr_array_add (argv, g_strdup ("--slaac-required"));
10225
10226                 g_ptr_array_add (argv, g_strdup ("--slaac-tempaddr"));
10227                 g_ptr_array_add (argv, g_strdup_printf ("%d", priv->rdisc_use_tempaddr));
10228
10229                 if (nm_device_get_ip_iface_identifier (self, &iid)) {
10230                         g_ptr_array_add (argv, g_strdup ("--iid"));
10231                         hex_iid = bin2hexstr ((const char *) iid.id_u8, sizeof (NMUtilsIPv6IfaceId));
10232                         g_ptr_array_add (argv, hex_iid);
10233                 }
10234
10235                 g_ptr_array_add (argv, g_strdup ("--addr-gen-mode"));
10236                 g_ptr_array_add (argv, g_strdup_printf ("%d", nm_setting_ip6_config_get_addr_gen_mode (NM_SETTING_IP6_CONFIG (s_ip6))));
10237
10238                 configured = TRUE;
10239         }
10240
10241         if (configured) {
10242                 GPid pid;
10243
10244                 g_ptr_array_add (argv, NULL);
10245
10246                 if (nm_logging_enabled (LOGL_DEBUG, LOGD_DEVICE)) {
10247                         char *tmp;
10248
10249                         tmp = g_strjoinv (" ", (char **) argv->pdata);
10250                         _LOGD (LOGD_DEVICE, "running '%s'", tmp);
10251                         g_free (tmp);
10252                 }
10253
10254                 if (g_spawn_async (NULL, (char **) argv->pdata, NULL,
10255                                    G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &error)) {
10256                         _LOGI (LOGD_DEVICE, "spawned helper PID %u", (guint) pid);
10257                 } else {
10258                         _LOGW (LOGD_DEVICE, "failed to spawn helper: %s", error->message);
10259                         g_error_free (error);
10260                 }
10261         }
10262
10263         g_ptr_array_unref (argv);
10264 }
10265
10266 /***********************************************************/
10267
10268 static gboolean
10269 ip_config_valid (NMDeviceState state)
10270 {
10271         return (state == NM_DEVICE_STATE_UNMANAGED) ||
10272                 (state >= NM_DEVICE_STATE_IP_CHECK &&
10273                  state <= NM_DEVICE_STATE_DEACTIVATING);
10274 }
10275
10276 static void
10277 notify_ip_properties (NMDevice *self)
10278 {
10279         _notify (self, PROP_IP_IFACE);
10280         _notify (self, PROP_IP4_CONFIG);
10281         _notify (self, PROP_DHCP4_CONFIG);
10282         _notify (self, PROP_IP6_CONFIG);
10283         _notify (self, PROP_DHCP6_CONFIG);
10284 }
10285
10286 static void
10287 ip6_managed_setup (NMDevice *self)
10288 {
10289         set_nm_ipv6ll (self, TRUE);
10290         set_disable_ipv6 (self, "1");
10291         nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0");
10292         nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0");
10293         nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0");
10294         nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0");
10295 }
10296
10297 static void
10298 deactivate_async_ready (NMDevice *self,
10299                         GAsyncResult *res,
10300                         gpointer user_data)
10301 {
10302         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10303         NMDeviceStateReason reason = GPOINTER_TO_UINT (user_data);
10304         GError *error = NULL;
10305
10306         NM_DEVICE_GET_CLASS (self)->deactivate_async_finish (self, res, &error);
10307
10308         /* If operation cancelled, just return */
10309         if (   g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)
10310             || (priv->deactivating_cancellable && g_cancellable_is_cancelled (priv->deactivating_cancellable))) {
10311                 _LOGW (LOGD_DEVICE, "Deactivation cancelled");
10312         }
10313         /* In every other case, transition to the DISCONNECTED state */
10314         else {
10315                 if (error) {
10316                         _LOGW (LOGD_DEVICE, "Deactivation failed: %s",
10317                                error->message);
10318                 }
10319                 nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
10320         }
10321
10322         g_clear_object (&priv->deactivating_cancellable);
10323         g_clear_error (&error);
10324 }
10325
10326 static void
10327 deactivate_dispatcher_complete (guint call_id, gpointer user_data)
10328 {
10329         NMDevice *self = NM_DEVICE (user_data);
10330         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10331         NMDeviceStateReason reason;
10332
10333         g_return_if_fail (call_id == priv->dispatcher.call_id);
10334         g_return_if_fail (priv->dispatcher.post_state == NM_DEVICE_STATE_DISCONNECTED);
10335
10336         reason = priv->dispatcher.post_state_reason;
10337
10338         priv->dispatcher.call_id = 0;
10339         priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN;
10340         priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
10341
10342         if (priv->deactivating_cancellable) {
10343                 g_warn_if_reached ();
10344                 g_cancellable_cancel (priv->deactivating_cancellable);
10345                 g_clear_object (&priv->deactivating_cancellable);
10346         }
10347
10348         if (   NM_DEVICE_GET_CLASS (self)->deactivate_async
10349             && NM_DEVICE_GET_CLASS (self)->deactivate_async_finish) {
10350                 priv->deactivating_cancellable = g_cancellable_new ();
10351                 NM_DEVICE_GET_CLASS (self)->deactivate_async (self,
10352                                                               priv->deactivating_cancellable,
10353                                                               (GAsyncReadyCallback) deactivate_async_ready,
10354                                                               GUINT_TO_POINTER (reason));
10355         } else
10356                 nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
10357 }
10358
10359 static void
10360 _set_state_full (NMDevice *self,
10361                  NMDeviceState state,
10362                  NMDeviceStateReason reason,
10363                  gboolean quitting)
10364 {
10365         NMDevicePrivate *priv;
10366         NMDeviceState old_state;
10367         NMActRequest *req;
10368         gboolean no_firmware = FALSE;
10369         NMSettingsConnection *connection;
10370         NMConnection *applied_connection;
10371
10372         g_return_if_fail (NM_IS_DEVICE (self));
10373
10374         priv = NM_DEVICE_GET_PRIVATE (self);
10375
10376         /* Track re-entry */
10377         g_warn_if_fail (priv->in_state_changed == FALSE);
10378
10379         old_state = priv->state;
10380
10381         /* Do nothing if state isn't changing, but as a special case allow
10382          * re-setting UNAVAILABLE if the device is missing firmware so that we
10383          * can retry device initialization.
10384          */
10385         if (   (priv->state == state)
10386             && (   state != NM_DEVICE_STATE_UNAVAILABLE
10387                 || !priv->firmware_missing)) {
10388                 _LOGD (LOGD_DEVICE, "state change: %s -> %s (reason '%s') [%d %d %d]%s",
10389                        state_to_string (old_state),
10390                        state_to_string (state),
10391                        reason_to_string (reason),
10392                        old_state,
10393                        state,
10394                        reason,
10395                        priv->firmware_missing ? " (missing firmware)" : "");
10396                 return;
10397         }
10398
10399         _LOGI (LOGD_DEVICE, "state change: %s -> %s (reason '%s') [%d %d %d]",
10400                state_to_string (old_state),
10401                state_to_string (state),
10402                reason_to_string (reason),
10403                old_state,
10404                state,
10405                reason);
10406
10407         priv->in_state_changed = TRUE;
10408
10409         priv->state = state;
10410         priv->state_reason = reason;
10411
10412         /* Clear any queued transitions */
10413         nm_device_queued_state_clear (self);
10414
10415         dispatcher_cleanup (self);
10416         if (priv->deactivating_cancellable)
10417                 g_cancellable_cancel (priv->deactivating_cancellable);
10418
10419         /* Cache the activation request for the dispatcher */
10420         req = priv->act_request ? g_object_ref (priv->act_request) : NULL;
10421
10422         if (state <= NM_DEVICE_STATE_UNAVAILABLE) {
10423                 if (available_connections_del_all (self))
10424                         available_connections_notify (self);
10425                 if (old_state > NM_DEVICE_STATE_UNAVAILABLE)
10426                         _clear_queued_act_request (priv);
10427         }
10428
10429         /* Update the available connections list when a device first becomes available */
10430         if (state >= NM_DEVICE_STATE_DISCONNECTED && old_state < NM_DEVICE_STATE_DISCONNECTED)
10431                 nm_device_recheck_available_connections (self);
10432
10433         /* Handle the new state here; but anything that could trigger
10434          * another state change should be done below.
10435          */
10436         switch (state) {
10437         case NM_DEVICE_STATE_UNMANAGED:
10438                 nm_device_set_firmware_missing (self, FALSE);
10439                 if (old_state > NM_DEVICE_STATE_UNMANAGED) {
10440                         if (reason == NM_DEVICE_STATE_REASON_REMOVED) {
10441                                 nm_device_cleanup (self, reason, CLEANUP_TYPE_REMOVED);
10442                         } else {
10443                                 /* Clean up if the device is now unmanaged but was activated */
10444                                 if (nm_device_get_act_request (self))
10445                                         nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
10446                                 nm_device_take_down (self, TRUE);
10447                                 set_nm_ipv6ll (self, FALSE);
10448                                 restore_ip6_properties (self);
10449                         }
10450                 }
10451                 break;
10452         case NM_DEVICE_STATE_UNAVAILABLE:
10453                 if (old_state == NM_DEVICE_STATE_UNMANAGED) {
10454                         save_ip6_properties (self);
10455                         if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED)
10456                                 ip6_managed_setup (self);
10457                 }
10458
10459                 if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) {
10460                         if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) {
10461                                 if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware)
10462                                         _LOGW (LOGD_HW, "firmware may be missing.");
10463                                 nm_device_set_firmware_missing (self, no_firmware ? TRUE : FALSE);
10464                         }
10465
10466                         /* Ensure the device gets deactivated in response to stuff like
10467                          * carrier changes or rfkill.  But don't deactivate devices that are
10468                          * about to assume a connection since that defeats the purpose of
10469                          * assuming the device's existing connection.
10470                          *
10471                          * Note that we "deactivate" the device even when coming from
10472                          * UNMANAGED, to ensure that it's in a clean state.
10473                          */
10474                         nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
10475                 }
10476                 break;
10477         case NM_DEVICE_STATE_DISCONNECTED:
10478                 if (old_state > NM_DEVICE_STATE_DISCONNECTED) {
10479                         /* Ensure devices that previously assumed a connection now have
10480                          * userspace IPv6LL enabled.
10481                          */
10482                         set_nm_ipv6ll (self, TRUE);
10483
10484                         nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
10485                 } else if (old_state < NM_DEVICE_STATE_DISCONNECTED) {
10486                         if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) {
10487                                 /* Ensure IPv6 is set up as it may not have been done when
10488                                  * entering the UNAVAILABLE state depending on the reason.
10489                                  */
10490                                 ip6_managed_setup (self);
10491                         }
10492                 }
10493                 break;
10494         case NM_DEVICE_STATE_NEED_AUTH:
10495                 if (old_state > NM_DEVICE_STATE_NEED_AUTH) {
10496                         /* Clean up any half-done IP operations if the device's layer2
10497                          * finds out it needs authentication during IP config.
10498                          */
10499                         _cleanup_ip4_pre (self, CLEANUP_TYPE_DECONFIGURE);
10500                         _cleanup_ip6_pre (self, CLEANUP_TYPE_DECONFIGURE);
10501                 }
10502                 break;
10503         default:
10504                 break;
10505         }
10506
10507         /* Reset autoconnect flag when the device is activating or connected. */
10508         if (   state >= NM_DEVICE_STATE_PREPARE
10509             && state <= NM_DEVICE_STATE_ACTIVATED)
10510                 nm_device_set_autoconnect (self, TRUE);
10511
10512         _notify (self, PROP_STATE);
10513         _notify (self, PROP_STATE_REASON);
10514         g_signal_emit_by_name (self, NM_DEVICE_STATE_CHANGED, state, old_state, reason);
10515
10516         /* Post-process the event after internal notification */
10517
10518         switch (state) {
10519         case NM_DEVICE_STATE_UNAVAILABLE:
10520                 /* If the device can activate now (ie, it's got a carrier, the supplicant
10521                  * is active, or whatever) schedule a delayed transition to DISCONNECTED
10522                  * to get things rolling.  The device can't transition immediately because
10523                  * we can't change states again from the state handler for a variety of
10524                  * reasons.
10525                  */
10526                 if (nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) {
10527                         nm_device_queue_recheck_available (self,
10528                                                            NM_DEVICE_STATE_REASON_NONE,
10529                                                            NM_DEVICE_STATE_REASON_NONE);
10530                 } else {
10531                         _LOGD (LOGD_DEVICE, "device not yet available for transition to DISCONNECTED");
10532                 }
10533                 break;
10534         case NM_DEVICE_STATE_DEACTIVATING:
10535                 _cancel_activation (self);
10536
10537                 if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
10538                         /* We cache the ignore_carrier state to not react on config-reloads while the connection
10539                          * is active. But on deactivating, reset the ignore-carrier flag to the current state. */
10540                         priv->ignore_carrier = nm_config_data_get_ignore_carrier (NM_CONFIG_GET_DATA, self);
10541                 }
10542
10543                 if (quitting) {
10544                         nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN,
10545                                                  nm_act_request_get_settings_connection (req),
10546                                                  nm_act_request_get_applied_connection (req),
10547                                                  self);
10548                 } else {
10549                         priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED;
10550                         priv->dispatcher.post_state_reason = reason;
10551                         if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN,
10552                                                  nm_act_request_get_settings_connection (req),
10553                                                  nm_act_request_get_applied_connection (req),
10554                                                  self,
10555                                                  deactivate_dispatcher_complete,
10556                                                  self,
10557                                                  &priv->dispatcher.call_id)) {
10558                                 /* Just proceed on errors */
10559                                 deactivate_dispatcher_complete (0, self);
10560                         }
10561                 }
10562                 break;
10563         case NM_DEVICE_STATE_DISCONNECTED:
10564                 if (   priv->queued_act_request
10565                     && !priv->queued_act_request_is_waiting_for_carrier) {
10566                         NMActRequest *queued_req;
10567                         gboolean success;
10568
10569                         queued_req = priv->queued_act_request;
10570                         priv->queued_act_request = NULL;
10571                         success = _device_activate (self, queued_req);
10572                         g_object_unref (queued_req);
10573                         if (success)
10574                                 break;
10575                         /* fall through */
10576                 }
10577                 break;
10578         case NM_DEVICE_STATE_ACTIVATED:
10579                 _LOGI (LOGD_DEVICE, "Activation: successful, device activated.");
10580                 nm_device_update_metered (self);
10581                 nm_dispatcher_call (DISPATCHER_ACTION_UP,
10582                                     nm_act_request_get_settings_connection (req),
10583                                     nm_act_request_get_applied_connection (req),
10584                                     self, NULL, NULL, NULL);
10585                 break;
10586         case NM_DEVICE_STATE_FAILED:
10587                 /* Usually upon failure the activation chain is interrupted in
10588                  * one of the stages; but in some cases the device fails for
10589                  * external events (as a failure of master connection) while
10590                  * the activation sequence is running and so we need to ensure
10591                  * that the chain is terminated here.
10592                  */
10593                 _cancel_activation (self);
10594
10595                 if (nm_device_uses_assumed_connection (self)) {
10596                         /* Avoid tearing down assumed connection, assume it's connected */
10597                         nm_device_queue_state (self,
10598                                                NM_DEVICE_STATE_ACTIVATED,
10599                                                NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
10600                         break;
10601                 }
10602
10603                 connection = nm_device_get_settings_connection (self);
10604                 _LOGW (LOGD_DEVICE | LOGD_WIFI,
10605                        "Activation: failed for connection '%s'",
10606                        connection ? nm_settings_connection_get_id (connection) : "<unknown>");
10607
10608                 /* Notify any slaves of the unexpected failure */
10609                 nm_device_master_release_slaves (self);
10610
10611                 /* If the connection doesn't yet have a timestamp, set it to zero so that
10612                  * we can distinguish between connections we've tried to activate and have
10613                  * failed (zero timestamp), connections that succeeded (non-zero timestamp),
10614                  * and those we haven't tried yet (no timestamp).
10615                  */
10616                 if (connection && !nm_settings_connection_get_timestamp (connection, NULL))
10617                         nm_settings_connection_update_timestamp (connection, (guint64) 0, TRUE);
10618
10619                 /* Schedule the transition to DISCONNECTED.  The device can't transition
10620                  * immediately because we can't change states again from the state
10621                  * handler for a variety of reasons.
10622                  */
10623                 nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE);
10624                 break;
10625         case NM_DEVICE_STATE_IP_CHECK:
10626                 /* Now that IP config has completed, check if the firewall
10627                  * zone must be set again for the IP interface.
10628                  */
10629                 applied_connection = nm_device_get_applied_connection (self);
10630
10631                 if (   applied_connection
10632                     && priv->ifindex != priv->ip_ifindex
10633                     && !nm_device_uses_assumed_connection (self)) {
10634                         NMSettingConnection *s_con;
10635                         const char *zone;
10636
10637                         s_con = nm_connection_get_setting_connection (applied_connection);
10638                         zone = nm_setting_connection_get_zone (s_con);
10639                         g_assert (!priv->fw_call);
10640                         priv->fw_call = nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
10641                                                                                 nm_device_get_ip_iface (self),
10642                                                                                 zone,
10643                                                                                 FALSE,
10644                                                                                 fw_change_zone_cb_ip_check,
10645                                                                                 self);
10646                 } else
10647                         nm_device_start_ip_check (self);
10648
10649                 /* IP-related properties are only valid when the device has IP configuration;
10650                  * now that it does, ensure their change notifications are emitted.
10651                  */
10652                 notify_ip_properties (self);
10653                 break;
10654         case NM_DEVICE_STATE_SECONDARIES:
10655                 ip_check_gw_ping_cleanup (self);
10656                 _LOGD (LOGD_DEVICE, "device entered SECONDARIES state");
10657                 break;
10658         default:
10659                 break;
10660         }
10661
10662         if (state > NM_DEVICE_STATE_DISCONNECTED)
10663                 delete_on_deactivate_unschedule (self);
10664
10665         if (   (old_state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_DEACTIVATING)
10666             && (state != NM_DEVICE_STATE_DEACTIVATING)) {
10667                 if (quitting) {
10668                         nm_dispatcher_call_sync (DISPATCHER_ACTION_DOWN,
10669                                                  nm_act_request_get_settings_connection (req),
10670                                                  nm_act_request_get_applied_connection (req),
10671                                                  self);
10672                 } else {
10673                         nm_dispatcher_call (DISPATCHER_ACTION_DOWN,
10674                                             nm_act_request_get_settings_connection (req),
10675                                             nm_act_request_get_applied_connection (req),
10676                                             self, NULL, NULL, NULL);
10677                 }
10678         }
10679
10680         /* IP-related properties are only valid when the device has IP configuration.
10681          * If it no longer does, ensure their change notifications are emitted.
10682          */
10683         if (ip_config_valid (old_state) && !ip_config_valid (state))
10684             notify_ip_properties (self);
10685
10686         /* Dispose of the cached activation request */
10687         if (req)
10688                 g_object_unref (req);
10689
10690         priv->in_state_changed = FALSE;
10691
10692         if ((old_state > NM_DEVICE_STATE_UNMANAGED) != (state > NM_DEVICE_STATE_UNMANAGED))
10693                 _notify (self, PROP_MANAGED);
10694 }
10695
10696 void
10697 nm_device_state_changed (NMDevice *self,
10698                          NMDeviceState state,
10699                          NMDeviceStateReason reason)
10700 {
10701         _set_state_full (self, state, reason, FALSE);
10702 }
10703
10704 static gboolean
10705 queued_set_state (gpointer user_data)
10706 {
10707         NMDevice *self = NM_DEVICE (user_data);
10708         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10709         NMDeviceState new_state;
10710         NMDeviceStateReason new_reason;
10711
10712         if (priv->queued_state.id) {
10713                 _LOGD (LOGD_DEVICE, "running queued state change to %s (id %d)",
10714                        state_to_string (priv->queued_state.state),
10715                        priv->queued_state.id);
10716
10717                 /* Clear queued state struct before triggering state change, since
10718                  * the state change may queue another state.
10719                  */
10720                 priv->queued_state.id = 0;
10721                 new_state = priv->queued_state.state;
10722                 new_reason = priv->queued_state.reason;
10723                 nm_device_queued_state_clear (self);
10724
10725                 nm_device_state_changed (self, new_state, new_reason);
10726                 nm_device_remove_pending_action (self, queued_state_to_string (new_state), TRUE);
10727         } else {
10728                 g_warn_if_fail (priv->queued_state.state == NM_DEVICE_STATE_UNKNOWN);
10729                 g_warn_if_fail (priv->queued_state.reason == NM_DEVICE_STATE_REASON_NONE);
10730         }
10731         return FALSE;
10732 }
10733
10734 void
10735 nm_device_queue_state (NMDevice *self,
10736                        NMDeviceState state,
10737                        NMDeviceStateReason reason)
10738 {
10739         NMDevicePrivate *priv;
10740
10741         g_return_if_fail (NM_IS_DEVICE (self));
10742
10743         priv = NM_DEVICE_GET_PRIVATE (self);
10744
10745         if (priv->queued_state.id && priv->queued_state.state == state)
10746                 return;
10747
10748         /* Add pending action for the new state before clearing the queued states, so
10749          * that we don't accidently pop all pending states and reach 'startup complete'  */
10750         nm_device_add_pending_action (self, queued_state_to_string (state), TRUE);
10751
10752         /* We should only ever have one delayed state transition at a time */
10753         if (priv->queued_state.id) {
10754                 _LOGW (LOGD_DEVICE, "overwriting previously queued state change to %s (%s)",
10755                        state_to_string (priv->queued_state.state),
10756                        reason_to_string (priv->queued_state.reason));
10757                 nm_device_queued_state_clear (self);
10758         }
10759
10760         priv->queued_state.state = state;
10761         priv->queued_state.reason = reason;
10762         priv->queued_state.id = g_idle_add (queued_set_state, self);
10763
10764         _LOGD (LOGD_DEVICE, "queued state change to %s due to %s (id %d)",
10765                state_to_string (state), reason_to_string (reason),
10766                priv->queued_state.id);
10767 }
10768
10769 NMDeviceState
10770 nm_device_queued_state_peek (NMDevice *self)
10771 {
10772         NMDevicePrivate *priv;
10773
10774         g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_STATE_UNKNOWN);
10775
10776         priv = NM_DEVICE_GET_PRIVATE (self);
10777
10778         return priv->queued_state.id ? priv->queued_state.state : NM_DEVICE_STATE_UNKNOWN;
10779 }
10780
10781 void
10782 nm_device_queued_state_clear (NMDevice *self)
10783 {
10784         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10785
10786         if (priv->queued_state.id) {
10787                 _LOGD (LOGD_DEVICE, "clearing queued state transition (id %d)",
10788                        priv->queued_state.id);
10789                 nm_clear_g_source (&priv->queued_state.id);
10790                 nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE);
10791         }
10792         memset (&priv->queued_state, 0, sizeof (priv->queued_state));
10793 }
10794
10795 NMDeviceState
10796 nm_device_get_state (NMDevice *self)
10797 {
10798         g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_STATE_UNKNOWN);
10799
10800         return NM_DEVICE_GET_PRIVATE (self)->state;
10801 }
10802
10803 /***********************************************************/
10804 /* NMConfigDevice interface related stuff */
10805
10806 const char *
10807 nm_device_get_hw_address (NMDevice *self)
10808 {
10809         NMDevicePrivate *priv;
10810
10811         g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
10812         priv = NM_DEVICE_GET_PRIVATE (self);
10813
10814         return priv->hw_addr_len ? priv->hw_addr : NULL;
10815 }
10816
10817 void
10818 nm_device_update_hw_address (NMDevice *self)
10819 {
10820         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10821         int ifindex = nm_device_get_ifindex (self);
10822         const guint8 *hwaddr;
10823         gsize hwaddrlen = 0;
10824         static const guint8 zero_hwaddr[ETH_ALEN];
10825
10826         if (ifindex <= 0)
10827                 return;
10828
10829         hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddrlen);
10830
10831         if (   priv->type == NM_DEVICE_TYPE_ETHERNET
10832             && nm_utils_hwaddr_matches (hwaddr, hwaddrlen, zero_hwaddr, sizeof (zero_hwaddr)))
10833                 hwaddrlen = 0;
10834
10835         if (hwaddrlen) {
10836                 priv->hw_addr_len = hwaddrlen;
10837                 if (!priv->hw_addr || !nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) {
10838                         g_free (priv->hw_addr);
10839                         priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen);
10840
10841                         _LOGD (LOGD_HW | LOGD_DEVICE, "hardware address now %s", priv->hw_addr);
10842                         _notify (self, PROP_HW_ADDRESS);
10843                 }
10844         } else {
10845                 /* Invalid or no hardware address */
10846                 if (priv->hw_addr_len != 0) {
10847                         g_clear_pointer (&priv->hw_addr, g_free);
10848                         priv->hw_addr_len = 0;
10849                         _LOGD (LOGD_HW | LOGD_DEVICE,
10850                                "previous hardware address is no longer valid");
10851                         _notify (self, PROP_HW_ADDRESS);
10852                 }
10853         }
10854 }
10855
10856 void
10857 nm_device_update_initial_hw_address (NMDevice *self)
10858 {
10859         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10860
10861         if (priv->hw_addr_len) {
10862                 priv->initial_hw_addr = g_strdup (priv->hw_addr);
10863                 _LOGD (LOGD_DEVICE | LOGD_HW, "read initial MAC address %s", priv->initial_hw_addr);
10864
10865                 if (priv->ifindex > 0) {
10866                         guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
10867                         size_t len = 0;
10868
10869                         if (nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len)) {
10870                                 g_warn_if_fail (len == priv->hw_addr_len);
10871                                 priv->perm_hw_addr = nm_utils_hwaddr_ntoa (buf, priv->hw_addr_len);
10872                                 _LOGD (LOGD_DEVICE | LOGD_HW, "read permanent MAC address %s",
10873                                        priv->perm_hw_addr);
10874                         } else {
10875                                 /* Fall back to current address */
10876                                 _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address");
10877                                 priv->perm_hw_addr = g_strdup (priv->hw_addr);
10878                         }
10879                 }
10880         }
10881 }
10882
10883 gboolean
10884 nm_device_set_hw_addr (NMDevice *self, const char *addr,
10885                        const char *detail, guint64 hw_log_domain)
10886 {
10887         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10888         gboolean success = FALSE;
10889         const char *cur_addr = nm_device_get_hw_address (self);
10890         guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX];
10891
10892         /* Fall back to the permanent address */
10893         if (!addr)
10894                 addr = priv->perm_hw_addr;
10895         if (!addr)
10896                 return FALSE;
10897
10898         /* Do nothing if current MAC is same */
10899         if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
10900                 _LOGD (LOGD_DEVICE | hw_log_domain, "no MAC address change needed");
10901                 return TRUE;
10902         }
10903         if (!nm_utils_hwaddr_aton (addr, addr_bytes, priv->hw_addr_len)) {
10904                 _LOGW (LOGD_DEVICE | hw_log_domain, "invalid MAC address %s", addr);
10905                 return FALSE;
10906         }
10907
10908         /* Can't change MAC address while device is up */
10909         nm_device_take_down (self, FALSE);
10910
10911         success = nm_platform_link_set_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), addr_bytes, priv->hw_addr_len);
10912         if (success) {
10913                 /* MAC address succesfully changed; update the current MAC to match */
10914                 nm_device_update_hw_address (self);
10915                 cur_addr = nm_device_get_hw_address (self);
10916                 if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
10917                         _LOGI (LOGD_DEVICE | hw_log_domain, "%s MAC address to %s",
10918                                detail, addr);
10919                 } else {
10920                         _LOGW (LOGD_DEVICE | hw_log_domain,
10921                                "new MAC address %s not successfully set", addr);
10922                         success = FALSE;
10923                 }
10924         } else {
10925                 _LOGW (LOGD_DEVICE | hw_log_domain, "failed to %s MAC address to %s",
10926                        detail, addr);
10927         }
10928         nm_device_bring_up (self, TRUE, NULL);
10929
10930         return success;
10931 }
10932
10933 const char *
10934 nm_device_get_permanent_hw_address (NMDevice *self)
10935 {
10936         g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
10937
10938         return NM_DEVICE_GET_PRIVATE (self)->perm_hw_addr;
10939 }
10940
10941 const char *
10942 nm_device_get_initial_hw_address (NMDevice *self)
10943 {
10944         g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
10945
10946         return NM_DEVICE_GET_PRIVATE (self)->initial_hw_addr;
10947 }
10948
10949 /**
10950  * nm_device_spec_match_list:
10951  * @self: an #NMDevice
10952  * @specs: (element-type utf8): a list of device specs
10953  *
10954  * Checks if @self matches any of the specifications in @specs. The
10955  * currently-supported spec types are:
10956  *
10957  *     "mac:00:11:22:33:44:55" - matches a device with the given
10958  *     hardware address
10959  *
10960  *     "interface-name:foo0" - matches a device with the given
10961  *     interface name
10962  *
10963  *     "s390-subchannels:00.11.22" - matches a device with the given
10964  *     z/VM / s390 subchannels.
10965  *
10966  *     "*" - matches any device
10967  *
10968  * Returns: #TRUE if @self matches one of the specs in @specs
10969  */
10970 gboolean
10971 nm_device_spec_match_list (NMDevice *self, const GSList *specs)
10972 {
10973         g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
10974
10975         if (!specs)
10976                 return FALSE;
10977
10978         return NM_DEVICE_GET_CLASS (self)->spec_match_list (self, specs) == NM_MATCH_SPEC_MATCH;
10979 }
10980
10981 static NMMatchSpecMatchType
10982 spec_match_list (NMDevice *self, const GSList *specs)
10983 {
10984         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10985         NMMatchSpecMatchType matched = NM_MATCH_SPEC_NO_MATCH, m;
10986         const GSList *iter;
10987
10988         for (iter = specs; iter; iter = g_slist_next (iter)) {
10989                 if (!strcmp ((const char *) iter->data, "*")) {
10990                         matched = NM_MATCH_SPEC_MATCH;
10991                         break;
10992                 }
10993         }
10994         if (priv->hw_addr_len && priv->hw_addr) {
10995                 m = nm_match_spec_hwaddr (specs, priv->hw_addr);
10996                 matched = MAX (matched, m);
10997         }
10998         if (matched != NM_MATCH_SPEC_NEG_MATCH) {
10999                 m = nm_match_spec_interface_name (specs, nm_device_get_iface (self));
11000                 matched = MAX (matched, m);
11001         }
11002         if (matched != NM_MATCH_SPEC_NEG_MATCH) {
11003                 m = nm_match_spec_device_type (specs, nm_device_get_type_description (self));
11004                 matched = MAX (matched, m);
11005         }
11006         return matched;
11007 }
11008
11009 /***********************************************************/
11010
11011 static const char *
11012 _activation_func_to_string (ActivationHandleFunc func)
11013 {
11014 #define FUNC_TO_STRING_CHECK_AND_RETURN(func, f) \
11015         G_STMT_START { \
11016                 if ((func) == (f)) \
11017                         return #f; \
11018         } G_STMT_END
11019         FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage1_device_prepare);
11020         FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage2_device_config);
11021         FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage3_ip_config_start);
11022         FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage4_ip4_config_timeout);
11023         FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage4_ip6_config_timeout);
11024         FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage5_ip4_config_commit);
11025         FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage5_ip6_config_commit);
11026         g_return_val_if_reached ("unknown");
11027 }
11028
11029 /***********************************************************/
11030
11031 static void
11032 nm_device_init (NMDevice *self)
11033 {
11034         NMDevicePrivate *priv;
11035
11036         priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DEVICE, NMDevicePrivate);
11037
11038         self->priv = priv;
11039
11040         priv->type = NM_DEVICE_TYPE_UNKNOWN;
11041         priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED;
11042         priv->state = NM_DEVICE_STATE_UNMANAGED;
11043         priv->state_reason = NM_DEVICE_STATE_REASON_NONE;
11044         priv->dhcp_timeout = 0;
11045         priv->rfkill_type = RFKILL_TYPE_UNKNOWN;
11046         priv->autoconnect = DEFAULT_AUTOCONNECT;
11047         priv->unmanaged_flags = NM_UNMANAGED_PLATFORM_INIT;
11048         priv->unmanaged_mask = priv->unmanaged_flags;
11049         priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
11050         priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
11051
11052         priv->default_route.v4_is_assumed = TRUE;
11053         priv->default_route.v6_is_assumed = TRUE;
11054
11055         priv->v4_commit_first_time = TRUE;
11056         priv->v6_commit_first_time = TRUE;
11057 }
11058
11059 static GObject*
11060 constructor (GType type,
11061              guint n_construct_params,
11062              GObjectConstructParam *construct_params)
11063 {
11064         GObject *object;
11065         GObjectClass *klass;
11066         NMDevice *self;
11067         NMDevicePrivate *priv;
11068         const NMPlatformLink *pllink;
11069
11070         klass = G_OBJECT_CLASS (nm_device_parent_class);
11071         object = klass->constructor (type, n_construct_params, construct_params);
11072         if (!object)
11073                 return NULL;
11074
11075         self = NM_DEVICE (object);
11076         priv = NM_DEVICE_GET_PRIVATE (self);
11077
11078         if (priv->iface) {
11079                 pllink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, priv->iface);
11080
11081                 if (pllink && link_type_compatible (self, pllink->type, NULL, NULL)) {
11082                         priv->ifindex = pllink->ifindex;
11083                         priv->up = NM_FLAGS_HAS (pllink->n_ifi_flags, IFF_UP);
11084                 }
11085         }
11086
11087         return object;
11088 }
11089
11090 static void
11091 constructed (GObject *object)
11092 {
11093         NMDevice *self = NM_DEVICE (object);
11094         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
11095         NMPlatform *platform;
11096
11097         platform = nm_platform_get ();
11098
11099         if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
11100                 priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
11101
11102         /* Watch for external IP config changes */
11103         g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (device_ipx_changed), self);
11104         g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (device_ipx_changed), self);
11105         g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self);
11106         g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self);
11107         g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), self);
11108
11109         priv->con_provider = nm_connection_provider_get ();
11110         g_assert (priv->con_provider);
11111         g_signal_connect (priv->con_provider,
11112                           NM_CP_SIGNAL_CONNECTION_ADDED,
11113                           G_CALLBACK (cp_connection_added_or_updated),
11114                           self);
11115
11116         g_signal_connect (priv->con_provider,
11117                           NM_CP_SIGNAL_CONNECTION_REMOVED,
11118                           G_CALLBACK (cp_connection_removed),
11119                           self);
11120
11121         g_signal_connect (priv->con_provider,
11122                           NM_CP_SIGNAL_CONNECTION_UPDATED,
11123                           G_CALLBACK (cp_connection_added_or_updated),
11124                           self);
11125
11126         G_OBJECT_CLASS (nm_device_parent_class)->constructed (object);
11127
11128         _LOGD (LOGD_DEVICE, "constructed (%s)", G_OBJECT_TYPE_NAME (self));
11129 }
11130
11131 static void
11132 dispose (GObject *object)
11133 {
11134         NMDevice *self = NM_DEVICE (object);
11135         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
11136         NMPlatform *platform;
11137
11138         _LOGD (LOGD_DEVICE, "disposing");
11139
11140         g_slist_free_full (priv->arping.dad_list, (GDestroyNotify) nm_arping_manager_destroy);
11141         priv->arping.dad_list = NULL;
11142
11143         arp_cleanup (self);
11144
11145         g_signal_handlers_disconnect_by_func (nm_config_get (), config_changed_update_ignore_carrier, self);
11146
11147         dispatcher_cleanup (self);
11148
11149         _cleanup_generic_pre (self, CLEANUP_TYPE_KEEP);
11150
11151         g_warn_if_fail (priv->slaves == NULL);
11152         g_assert (priv->master_ready_id == 0);
11153
11154         /* Let the kernel manage IPv6LL again */
11155         set_nm_ipv6ll (self, FALSE);
11156
11157         _cleanup_generic_post (self, CLEANUP_TYPE_KEEP);
11158
11159         g_hash_table_remove_all (priv->ip6_saved_properties);
11160
11161         nm_clear_g_source (&priv->recheck_assume_id);
11162         nm_clear_g_source (&priv->recheck_available.call_id);
11163
11164         nm_clear_g_source (&priv->check_delete_unrealized_id);
11165
11166         link_disconnect_action_cancel (self);
11167
11168         if (priv->con_provider) {
11169                 g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_added_or_updated, self);
11170                 g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_removed, self);
11171                 priv->con_provider = NULL;
11172         }
11173
11174         available_connections_del_all (self);
11175
11176         nm_clear_g_source (&priv->carrier_wait_id);
11177
11178         _clear_queued_act_request (priv);
11179
11180         platform = nm_platform_get ();
11181         g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ipx_changed), self);
11182         g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (link_changed_cb), self);
11183
11184         nm_clear_g_source (&priv->device_link_changed_id);
11185         nm_clear_g_source (&priv->device_ip_link_changed_id);
11186
11187         if (priv->lldp_listener) {
11188                 g_signal_handlers_disconnect_by_func (priv->lldp_listener,
11189                                                       G_CALLBACK (lldp_neighbors_changed),
11190                                                       self);
11191                 nm_lldp_listener_stop (priv->lldp_listener);
11192                 g_clear_object (&priv->lldp_listener);
11193         }
11194
11195         G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
11196
11197         if (nm_clear_g_source (&priv->queued_state.id)) {
11198                 /* FIXME: we'd expect the queud_state to be alredy cleared and this statement
11199                  * not being necessary. Add this check here to hopefully investigate crash
11200                  * rh#1270247. */
11201                 g_return_if_reached ();
11202         }
11203 }
11204
11205 static void
11206 finalize (GObject *object)
11207 {
11208         NMDevice *self = NM_DEVICE (object);
11209         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
11210
11211         _LOGD (LOGD_DEVICE, "finalize(): %s", G_OBJECT_TYPE_NAME (self));
11212
11213         g_free (priv->hw_addr);
11214         g_free (priv->perm_hw_addr);
11215         g_free (priv->initial_hw_addr);
11216         g_slist_free_full (priv->pending_actions, g_free);
11217         g_slist_free_full (priv->dad6_failed_addrs, g_free);
11218         g_clear_pointer (&priv->physical_port_id, g_free);
11219         g_free (priv->udi);
11220         g_free (priv->iface);
11221         g_free (priv->ip_iface);
11222         g_free (priv->driver);
11223         g_free (priv->driver_version);
11224         g_free (priv->firmware_version);
11225         g_free (priv->type_desc);
11226         g_free (priv->type_description);
11227         g_free (priv->dhcp_anycast_address);
11228
11229         g_hash_table_unref (priv->ip6_saved_properties);
11230         g_hash_table_unref (priv->available_connections);
11231
11232         G_OBJECT_CLASS (nm_device_parent_class)->finalize (object);
11233 }
11234
11235 static void
11236 set_property (GObject *object, guint prop_id,
11237               const GValue *value, GParamSpec *pspec)
11238 {
11239         NMDevice *self = NM_DEVICE (object);
11240         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
11241         const char *hw_addr, *p;
11242         guint count;
11243
11244         switch (prop_id) {
11245         case PROP_UDI:
11246                 if (g_value_get_string (value)) {
11247                         g_free (priv->udi);
11248                         priv->udi = g_value_dup_string (value);
11249                 }
11250                 break;
11251         case PROP_IFACE:
11252                 /* construct only */
11253                 g_return_if_fail (!priv->iface);
11254                 priv->iface = g_value_dup_string (value);
11255                 break;
11256         case PROP_DRIVER:
11257                 if (g_value_get_string (value)) {
11258                         g_free (priv->driver);
11259                         priv->driver = g_value_dup_string (value);
11260                 }
11261                 break;
11262         case PROP_DRIVER_VERSION:
11263                 g_free (priv->driver_version);
11264                 priv->driver_version = g_strdup (g_value_get_string (value));
11265                 break;
11266         case PROP_FIRMWARE_VERSION:
11267                 g_free (priv->firmware_version);
11268                 priv->firmware_version = g_strdup (g_value_get_string (value));
11269                 break;
11270         case PROP_MTU:
11271                 priv->mtu = g_value_get_uint (value);
11272                 break;
11273         case PROP_IP4_ADDRESS:
11274                 priv->ip4_address = g_value_get_uint (value);
11275                 break;
11276         case PROP_MANAGED: {
11277                 gboolean managed;
11278                 NMDeviceStateReason reason;
11279
11280                 managed = g_value_get_boolean (value);
11281                 if (managed)
11282                         reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED;
11283                 else
11284                         reason = NM_DEVICE_STATE_REASON_REMOVED;
11285                 nm_device_set_unmanaged_by_flags (self,
11286                                                   NM_UNMANAGED_USER_EXPLICIT,
11287                                                   !managed,
11288                                                   reason);
11289                 break;
11290         }
11291         case PROP_AUTOCONNECT:
11292                 nm_device_set_autoconnect (self, g_value_get_boolean (value));
11293                 break;
11294         case PROP_FIRMWARE_MISSING:
11295                 /* construct only */
11296                 priv->firmware_missing = g_value_get_boolean (value);
11297                 break;
11298         case PROP_NM_PLUGIN_MISSING:
11299                 priv->nm_plugin_missing = g_value_get_boolean (value);
11300                 break;
11301         case PROP_DEVICE_TYPE:
11302                 g_return_if_fail (priv->type == NM_DEVICE_TYPE_UNKNOWN);
11303                 priv->type = g_value_get_uint (value);
11304                 break;
11305         case PROP_LINK_TYPE:
11306                 /* construct only */
11307                 g_return_if_fail (priv->link_type == NM_LINK_TYPE_NONE);
11308                 priv->link_type = g_value_get_uint (value);
11309                 break;
11310         case PROP_TYPE_DESC:
11311                 g_free (priv->type_desc);
11312                 priv->type_desc = g_value_dup_string (value);
11313                 break;
11314         case PROP_RFKILL_TYPE:
11315                 priv->rfkill_type = g_value_get_uint (value);
11316                 break;
11317         case PROP_IS_MASTER:
11318                 priv->is_master = g_value_get_boolean (value);
11319                 break;
11320         case PROP_HW_ADDRESS:
11321                 /* construct only */
11322                 p = hw_addr = g_value_get_string (value);
11323
11324                 /* Hardware address length is the number of ':' plus 1 */
11325                 count = 1;
11326                 while (p && *p) {
11327                         if (*p++ == ':')
11328                                 count++;
11329                 }
11330                 if (count < ETH_ALEN || count > NM_UTILS_HWADDR_LEN_MAX) {
11331                         if (hw_addr && *hw_addr) {
11332                                 _LOGW (LOGD_DEVICE, "ignoring hardware address '%s' with unexpected length %d",
11333                                        hw_addr, count);
11334                         }
11335                         break;
11336                 }
11337
11338                 priv->hw_addr_len = count;
11339                 g_free (priv->hw_addr);
11340                 if (nm_utils_hwaddr_valid (hw_addr, priv->hw_addr_len))
11341                         priv->hw_addr = g_strdup (hw_addr);
11342                 else {
11343                         _LOGW (LOGD_DEVICE, "could not parse hw-address '%s'", hw_addr);
11344                         priv->hw_addr = NULL;
11345                 }
11346                 break;
11347         default:
11348                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
11349                 break;
11350         }
11351 }
11352
11353 static void
11354 get_property (GObject *object, guint prop_id,
11355               GValue *value, GParamSpec *pspec)
11356 {
11357         NMDevice *self = NM_DEVICE (object);
11358         NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
11359         GPtrArray *array;
11360         GHashTableIter iter;
11361         NMConnection *connection;
11362         GVariantBuilder array_builder;
11363
11364         switch (prop_id) {
11365         case PROP_UDI:
11366                 g_value_set_string (value, priv->udi);
11367                 break;
11368         case PROP_IFACE:
11369                 g_value_set_string (value, priv->iface);
11370                 break;
11371         case PROP_IP_IFACE:
11372                 if (ip_config_valid (priv->state))
11373                         g_value_set_string (value, nm_device_get_ip_iface (self));
11374                 else
11375                         g_value_set_string (value, NULL);
11376                 break;
11377         case PROP_IFINDEX:
11378                 g_value_set_int (value, priv->ifindex);
11379                 break;
11380         case PROP_DRIVER:
11381                 g_value_set_string (value, priv->driver);
11382                 break;
11383         case PROP_DRIVER_VERSION:
11384                 g_value_set_string (value, priv->driver_version);
11385                 break;
11386         case PROP_FIRMWARE_VERSION:
11387                 g_value_set_string (value, priv->firmware_version);
11388                 break;
11389         case PROP_CAPABILITIES:
11390                 g_value_set_uint (value, (priv->capabilities & ~NM_DEVICE_CAP_INTERNAL_MASK));
11391                 break;
11392         case PROP_IP4_ADDRESS:
11393                 g_value_set_uint (value, priv->ip4_address);
11394                 break;
11395         case PROP_CARRIER:
11396                 g_value_set_boolean (value, priv->carrier);
11397                 break;
11398         case PROP_MTU:
11399                 g_value_set_uint (value, priv->mtu);
11400                 break;
11401         case PROP_IP4_CONFIG:
11402                 nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip4_config : NULL);
11403                 break;
11404         case PROP_DHCP4_CONFIG:
11405                 nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp4_config : NULL);
11406                 break;
11407         case PROP_IP6_CONFIG:
11408                 nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip6_config : NULL);
11409                 break;
11410         case PROP_DHCP6_CONFIG:
11411                 nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp6_config : NULL);
11412                 break;
11413         case PROP_STATE:
11414                 g_value_set_uint (value, priv->state);
11415                 break;
11416         case PROP_STATE_REASON:
11417                 g_value_take_variant (value,
11418                                       g_variant_new ("(uu)", priv->state, priv->state_reason));
11419                 break;
11420         case PROP_ACTIVE_CONNECTION:
11421                 nm_utils_g_value_set_object_path (value, priv->act_request);
11422                 break;
11423         case PROP_DEVICE_TYPE:
11424                 g_value_set_uint (value, priv->type);
11425                 break;
11426         case PROP_LINK_TYPE:
11427                 g_value_set_uint (value, priv->link_type);
11428                 break;
11429         case PROP_MANAGED:
11430                 /* The managed state exposed on D-Bus only depends on the current device state alone. */
11431                 g_value_set_boolean (value, nm_device_get_state (self) > NM_DEVICE_STATE_UNMANAGED);
11432                 break;
11433         case PROP_AUTOCONNECT:
11434                 g_value_set_boolean (value, priv->autoconnect);
11435                 break;
11436         case PROP_FIRMWARE_MISSING:
11437                 g_value_set_boolean (value, priv->firmware_missing);
11438                 break;
11439         case PROP_NM_PLUGIN_MISSING:
11440                 g_value_set_boolean (value, priv->nm_plugin_missing);
11441                 break;
11442         case PROP_TYPE_DESC:
11443                 g_value_set_string (value, priv->type_desc);
11444                 break;
11445         case PROP_RFKILL_TYPE:
11446                 g_value_set_uint (value, priv->rfkill_type);
11447                 break;
11448         case PROP_AVAILABLE_CONNECTIONS:
11449                 array = g_ptr_array_sized_new (g_hash_table_size (priv->available_connections));
11450                 g_hash_table_iter_init (&iter, priv->available_connections);
11451                 while (g_hash_table_iter_next (&iter, (gpointer) &connection, NULL))
11452                         g_ptr_array_add (array, g_strdup (nm_connection_get_path (connection)));
11453                 g_ptr_array_add (array, NULL);
11454                 g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE));
11455                 break;
11456         case PROP_PHYSICAL_PORT_ID:
11457                 g_value_set_string (value, priv->physical_port_id);
11458                 break;
11459         case PROP_IS_MASTER:
11460                 g_value_set_boolean (value, priv->is_master);
11461                 break;
11462         case PROP_MASTER:
11463                 g_value_set_object (value, nm_device_get_master (self));
11464                 break;
11465         case PROP_HW_ADDRESS:
11466                 g_value_set_string (value, priv->hw_addr);
11467                 break;
11468         case PROP_HAS_PENDING_ACTION:
11469                 g_value_set_boolean (value, nm_device_has_pending_action (self));
11470                 break;
11471         case PROP_METERED:
11472                 g_value_set_uint (value, priv->metered);
11473                 break;
11474         case PROP_LLDP_NEIGHBORS:
11475                 if (priv->lldp_listener)
11476                         g_value_set_variant (value, nm_lldp_listener_get_neighbors (priv->lldp_listener));
11477                 else {
11478                         g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}"));
11479                         g_value_take_variant (value, g_variant_builder_end (&array_builder));
11480                 }
11481                 break;
11482         case PROP_REAL:
11483                 g_value_set_boolean (value, nm_device_is_real (self));
11484                 break;
11485         case PROP_SLAVES: {
11486                 GSList *slave_iter;
11487                 char **slave_list;
11488                 guint i;
11489
11490                 slave_list = g_new (char *, g_slist_length (priv->slaves) + 1);
11491                 for (slave_iter = priv->slaves, i = 0; slave_iter; slave_iter = slave_iter->next) {
11492                         SlaveInfo *info = slave_iter->data;
11493                         const char *path;
11494
11495                         if (!NM_DEVICE_GET_PRIVATE (info->slave)->is_enslaved)
11496                                 continue;
11497                         path = nm_exported_object_get_path ((NMExportedObject *) info->slave);
11498                         if (path)
11499                                 slave_list[i++] = g_strdup (path);
11500                 }
11501                 slave_list[i] = NULL;
11502                 g_value_take_boxed (value, slave_list);
11503                 break;
11504         }
11505         default:
11506                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
11507                 break;
11508         }
11509 }
11510
11511 static void
11512 nm_device_class_init (NMDeviceClass *klass)
11513 {
11514         GObjectClass *object_class = G_OBJECT_CLASS (klass);
11515         NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (klass);
11516
11517         g_type_class_add_private (object_class, sizeof (NMDevicePrivate));
11518
11519         exported_object_class->export_path = NM_DBUS_PATH "/Devices/%u";
11520
11521         /* Virtual methods */
11522         object_class->dispose = dispose;
11523         object_class->finalize = finalize;
11524         object_class->set_property = set_property;
11525         object_class->get_property = get_property;
11526         object_class->constructor = constructor;
11527         object_class->constructed = constructed;
11528
11529         klass->link_changed = link_changed;
11530
11531         klass->is_available = is_available;
11532         klass->act_stage1_prepare = act_stage1_prepare;
11533         klass->act_stage2_config = act_stage2_config;
11534         klass->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
11535         klass->act_stage3_ip6_config_start = act_stage3_ip6_config_start;
11536         klass->act_stage4_ip4_config_timeout = act_stage4_ip4_config_timeout;
11537         klass->act_stage4_ip6_config_timeout = act_stage4_ip6_config_timeout;
11538         klass->have_any_ready_slaves = have_any_ready_slaves;
11539
11540         klass->get_type_description = get_type_description;
11541         klass->spec_match_list = spec_match_list;
11542         klass->can_auto_connect = can_auto_connect;
11543         klass->check_connection_compatible = check_connection_compatible;
11544         klass->check_connection_available = check_connection_available;
11545         klass->can_unmanaged_external_down = can_unmanaged_external_down;
11546         klass->realize_start_notify = realize_start_notify;
11547         klass->unrealize_notify = unrealize_notify;
11548         klass->is_up = is_up;
11549         klass->bring_up = bring_up;
11550         klass->take_down = take_down;
11551         klass->carrier_changed = carrier_changed;
11552         klass->get_ip_iface_identifier = get_ip_iface_identifier;
11553
11554         /* Properties */
11555         obj_properties[PROP_UDI] =
11556             g_param_spec_string (NM_DEVICE_UDI, "", "",
11557                                  NULL,
11558                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
11559                                  G_PARAM_STATIC_STRINGS);
11560         obj_properties[PROP_IFACE] =
11561             g_param_spec_string (NM_DEVICE_IFACE, "", "",
11562                                  NULL,
11563                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11564                                  G_PARAM_STATIC_STRINGS);
11565         obj_properties[PROP_IP_IFACE] =
11566             g_param_spec_string (NM_DEVICE_IP_IFACE, "", "",
11567                                  NULL,
11568                                  G_PARAM_READABLE |
11569                                  G_PARAM_STATIC_STRINGS);
11570         obj_properties[PROP_DRIVER] =
11571             g_param_spec_string (NM_DEVICE_DRIVER, "", "",
11572                                  NULL,
11573                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11574                                  G_PARAM_STATIC_STRINGS);
11575         obj_properties[PROP_DRIVER_VERSION] =
11576             g_param_spec_string (NM_DEVICE_DRIVER_VERSION, "", "",
11577                                  NULL,
11578                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11579                                  G_PARAM_STATIC_STRINGS);
11580         obj_properties[PROP_FIRMWARE_VERSION] =
11581             g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, "", "",
11582                                  NULL,
11583                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11584                                  G_PARAM_STATIC_STRINGS);
11585         obj_properties[PROP_CAPABILITIES] =
11586             g_param_spec_uint (NM_DEVICE_CAPABILITIES, "", "",
11587                                0, G_MAXUINT32, NM_DEVICE_CAP_NONE,
11588                                G_PARAM_READABLE |
11589                                G_PARAM_STATIC_STRINGS);
11590         obj_properties[PROP_CARRIER] =
11591             g_param_spec_boolean (NM_DEVICE_CARRIER, "", "",
11592                                   FALSE,
11593                                   G_PARAM_READABLE |
11594                                   G_PARAM_STATIC_STRINGS);
11595         obj_properties[PROP_MTU] =
11596             g_param_spec_uint (NM_DEVICE_MTU, "", "",
11597                                0, G_MAXUINT32, 1500,
11598                                G_PARAM_READABLE |
11599                                G_PARAM_STATIC_STRINGS);
11600         obj_properties[PROP_IP4_ADDRESS] =
11601             g_param_spec_uint (NM_DEVICE_IP4_ADDRESS, "", "",
11602                                0, G_MAXUINT32, 0, /* FIXME */
11603                                G_PARAM_READWRITE |
11604                                G_PARAM_STATIC_STRINGS);
11605         obj_properties[PROP_IP4_CONFIG] =
11606             g_param_spec_string (NM_DEVICE_IP4_CONFIG, "", "",
11607                                  NULL,
11608                                  G_PARAM_READWRITE |
11609                                  G_PARAM_STATIC_STRINGS);
11610         obj_properties[PROP_DHCP4_CONFIG] =
11611             g_param_spec_string (NM_DEVICE_DHCP4_CONFIG, "", "",
11612                                  NULL,
11613                                  G_PARAM_READWRITE |
11614                                  G_PARAM_STATIC_STRINGS);
11615         obj_properties[PROP_IP6_CONFIG] =
11616             g_param_spec_string (NM_DEVICE_IP6_CONFIG, "", "",
11617                                  NULL,
11618                                  G_PARAM_READWRITE |
11619                                  G_PARAM_STATIC_STRINGS);
11620         obj_properties[PROP_DHCP6_CONFIG] =
11621             g_param_spec_string (NM_DEVICE_DHCP6_CONFIG, "", "",
11622                                  NULL,
11623                                  G_PARAM_READWRITE |
11624                                  G_PARAM_STATIC_STRINGS);
11625         obj_properties[PROP_STATE] =
11626             g_param_spec_uint (NM_DEVICE_STATE, "", "",
11627                                0, G_MAXUINT32, NM_DEVICE_STATE_UNKNOWN,
11628                                G_PARAM_READABLE |
11629                                G_PARAM_STATIC_STRINGS);
11630         obj_properties[PROP_STATE_REASON] =
11631             g_param_spec_variant (NM_DEVICE_STATE_REASON, "", "",
11632                                   G_VARIANT_TYPE ("(uu)"),
11633                                   NULL,
11634                                   G_PARAM_READABLE |
11635                                   G_PARAM_STATIC_STRINGS);
11636         obj_properties[PROP_ACTIVE_CONNECTION] =
11637             g_param_spec_string (NM_DEVICE_ACTIVE_CONNECTION, "", "",
11638                                  NULL,
11639                                  G_PARAM_READABLE |
11640                                  G_PARAM_STATIC_STRINGS);
11641         obj_properties[PROP_DEVICE_TYPE] =
11642             g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, "", "",
11643                                0, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN,
11644                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11645                                G_PARAM_STATIC_STRINGS);
11646         obj_properties[PROP_LINK_TYPE] =
11647             g_param_spec_uint (NM_DEVICE_LINK_TYPE, "", "",
11648                                0, G_MAXUINT32, NM_LINK_TYPE_NONE,
11649                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11650                                G_PARAM_STATIC_STRINGS);
11651         obj_properties[PROP_MANAGED] =
11652             g_param_spec_boolean (NM_DEVICE_MANAGED, "", "",
11653                                   FALSE,
11654                                   G_PARAM_READWRITE |
11655                                   G_PARAM_STATIC_STRINGS);
11656         obj_properties[PROP_AUTOCONNECT] =
11657             g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, "", "",
11658                                   DEFAULT_AUTOCONNECT,
11659                                   G_PARAM_READWRITE |
11660                                   G_PARAM_STATIC_STRINGS);
11661         obj_properties[PROP_FIRMWARE_MISSING] =
11662             g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, "", "",
11663                                   FALSE,
11664                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11665                                   G_PARAM_STATIC_STRINGS);
11666         obj_properties[PROP_NM_PLUGIN_MISSING] =
11667             g_param_spec_boolean (NM_DEVICE_NM_PLUGIN_MISSING, "", "",
11668                                   FALSE,
11669                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11670                                   G_PARAM_STATIC_STRINGS);
11671         obj_properties[PROP_TYPE_DESC] =
11672             g_param_spec_string (NM_DEVICE_TYPE_DESC, "", "",
11673                                  NULL,
11674                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11675                                  G_PARAM_STATIC_STRINGS);
11676         obj_properties[PROP_RFKILL_TYPE] =
11677             g_param_spec_uint (NM_DEVICE_RFKILL_TYPE, "", "",
11678                                RFKILL_TYPE_WLAN,
11679                                RFKILL_TYPE_MAX,
11680                                RFKILL_TYPE_UNKNOWN,
11681                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11682                                G_PARAM_STATIC_STRINGS);
11683         obj_properties[PROP_IFINDEX] =
11684             g_param_spec_int (NM_DEVICE_IFINDEX, "", "",
11685                               0, G_MAXINT, 0,
11686                               G_PARAM_READABLE |
11687                               G_PARAM_STATIC_STRINGS);
11688         obj_properties[PROP_AVAILABLE_CONNECTIONS] =
11689             g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, "", "",
11690                                 G_TYPE_STRV,
11691                                 G_PARAM_READABLE |
11692                                 G_PARAM_STATIC_STRINGS);
11693         obj_properties[PROP_PHYSICAL_PORT_ID] =
11694             g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, "", "",
11695                                  NULL,
11696                                  G_PARAM_READABLE |
11697                                  G_PARAM_STATIC_STRINGS);
11698         obj_properties[PROP_IS_MASTER] =
11699             g_param_spec_boolean (NM_DEVICE_IS_MASTER, "", "",
11700                                   FALSE,
11701                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11702                                   G_PARAM_STATIC_STRINGS);
11703         obj_properties[PROP_MASTER] =
11704             g_param_spec_object (NM_DEVICE_MASTER, "", "",
11705                                  NM_TYPE_DEVICE,
11706                                  G_PARAM_READABLE |
11707                                  G_PARAM_STATIC_STRINGS);
11708         obj_properties[PROP_HW_ADDRESS] =
11709             g_param_spec_string (NM_DEVICE_HW_ADDRESS, "", "",
11710                                  NULL,
11711                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11712                                  G_PARAM_STATIC_STRINGS);
11713         obj_properties[PROP_HAS_PENDING_ACTION] =
11714             g_param_spec_boolean (NM_DEVICE_HAS_PENDING_ACTION, "", "",
11715                                   FALSE,
11716                                   G_PARAM_READABLE |
11717                                   G_PARAM_STATIC_STRINGS);
11718
11719         /**
11720          * NMDevice:metered:
11721          *
11722          * Whether the connection is metered.
11723          *
11724          * Since: 1.2
11725          **/
11726         obj_properties[PROP_METERED] =
11727             g_param_spec_uint (NM_DEVICE_METERED, "", "",
11728                                0, G_MAXUINT32, NM_METERED_UNKNOWN,
11729                                G_PARAM_READABLE |
11730                                G_PARAM_STATIC_STRINGS);
11731         obj_properties[PROP_LLDP_NEIGHBORS] =
11732             g_param_spec_variant (NM_DEVICE_LLDP_NEIGHBORS, "", "",
11733                                   G_VARIANT_TYPE ("aa{sv}"),
11734                                   NULL,
11735                                   G_PARAM_READABLE |
11736                                   G_PARAM_STATIC_STRINGS);
11737         obj_properties[PROP_REAL] =
11738             g_param_spec_boolean (NM_DEVICE_REAL, "", "",
11739                                   FALSE,
11740                                   G_PARAM_READABLE |
11741                                   G_PARAM_STATIC_STRINGS);
11742         obj_properties[PROP_SLAVES] =
11743             g_param_spec_boxed (NM_DEVICE_SLAVES, "", "",
11744                                 G_TYPE_STRV,
11745                                 G_PARAM_READABLE |
11746                                 G_PARAM_STATIC_STRINGS);
11747
11748         g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
11749
11750         /* Signals */
11751         signals[STATE_CHANGED] =
11752             g_signal_new (NM_DEVICE_STATE_CHANGED,
11753                           G_OBJECT_CLASS_TYPE (object_class),
11754                           G_SIGNAL_RUN_LAST,
11755                           G_STRUCT_OFFSET (NMDeviceClass, state_changed),
11756                           NULL, NULL, NULL,
11757                           G_TYPE_NONE, 3,
11758                           G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
11759
11760         signals[AUTOCONNECT_ALLOWED] =
11761             g_signal_new ("autoconnect-allowed",
11762                           G_OBJECT_CLASS_TYPE (object_class),
11763                           G_SIGNAL_RUN_LAST,
11764                           0,
11765                           autoconnect_allowed_accumulator, NULL, NULL,
11766                           G_TYPE_BOOLEAN, 0);
11767
11768         signals[AUTH_REQUEST] =
11769             g_signal_new (NM_DEVICE_AUTH_REQUEST,
11770                           G_OBJECT_CLASS_TYPE (object_class),
11771                           G_SIGNAL_RUN_FIRST,
11772                           0, NULL, NULL, NULL,
11773                           /* context, connection, permission, allow_interaction, callback, user_data */
11774                           G_TYPE_NONE, 6, G_TYPE_DBUS_METHOD_INVOCATION, NM_TYPE_CONNECTION, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER, G_TYPE_POINTER);
11775
11776         signals[IP4_CONFIG_CHANGED] =
11777             g_signal_new (NM_DEVICE_IP4_CONFIG_CHANGED,
11778                           G_OBJECT_CLASS_TYPE (object_class),
11779                           G_SIGNAL_RUN_FIRST,
11780                           0, NULL, NULL, NULL,
11781                           G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT);
11782
11783         signals[IP6_CONFIG_CHANGED] =
11784             g_signal_new (NM_DEVICE_IP6_CONFIG_CHANGED,
11785                           G_OBJECT_CLASS_TYPE (object_class),
11786                           G_SIGNAL_RUN_FIRST,
11787                           0, NULL, NULL, NULL,
11788                           G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT);
11789
11790         signals[REMOVED] =
11791             g_signal_new (NM_DEVICE_REMOVED,
11792                           G_OBJECT_CLASS_TYPE (object_class),
11793                           G_SIGNAL_RUN_FIRST,
11794                           0, NULL, NULL, NULL,
11795                           G_TYPE_NONE, 0);
11796
11797         signals[RECHECK_AUTO_ACTIVATE] =
11798             g_signal_new (NM_DEVICE_RECHECK_AUTO_ACTIVATE,
11799                           G_OBJECT_CLASS_TYPE (object_class),
11800                           G_SIGNAL_RUN_FIRST,
11801                           0, NULL, NULL, NULL,
11802                           G_TYPE_NONE, 0);
11803
11804         signals[RECHECK_ASSUME] =
11805             g_signal_new (NM_DEVICE_RECHECK_ASSUME,
11806                           G_OBJECT_CLASS_TYPE (object_class),
11807                           G_SIGNAL_RUN_FIRST,
11808                           0, NULL, NULL, NULL,
11809                           G_TYPE_NONE, 0);
11810
11811         nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
11812                                                 NMDBUS_TYPE_DEVICE_SKELETON,
11813                                                 "Reapply", impl_device_reapply,
11814                                                 "GetAppliedConnection", impl_device_get_applied_connection,
11815                                                 "Disconnect", impl_device_disconnect,
11816                                                 "Delete", impl_device_delete,
11817                                                 NULL);
11818 }