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