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