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