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