1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* NetworkManager -- Network link manager
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.
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.
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.
18 * Copyright (C) 2005 - 2013 Red Hat, Inc.
19 * Copyright (C) 2006 - 2008 Novell, Inc.
22 #include "nm-default.h"
24 #include <netinet/in.h>
28 #include <sys/ioctl.h>
30 #include <sys/types.h>
32 #include <arpa/inet.h>
34 #include <netlink/route/addr.h>
35 #include <linux/if_addr.h>
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"
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"
68 #include "nm-device-logging.h"
69 _LOG_DECLARE_SELF (NMDevice);
71 #include "nmdbus-device.h"
73 G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_EXPORTED_OBJECT)
75 #define NM_DEVICE_GET_PRIVATE(o) ((o)->priv)
84 RECHECK_AUTO_ACTIVATE,
88 static guint signals[LAST_SIGNAL] = { 0 };
90 NM_GOBJECT_PROPERTIES_DEFINE (NMDevice,
96 PROP_FIRMWARE_VERSION,
107 PROP_ACTIVE_CONNECTION,
112 PROP_FIRMWARE_MISSING,
113 PROP_NM_PLUGIN_MISSING,
117 PROP_AVAILABLE_CONNECTIONS,
118 PROP_PHYSICAL_PORT_ID,
122 PROP_HAS_PENDING_ACTION,
129 #define DEFAULT_AUTOCONNECT TRUE
131 /***********************************************************/
133 #define PENDING_ACTION_DHCP4 "dhcp4"
134 #define PENDING_ACTION_DHCP6 "dhcp6"
135 #define PENDING_ACTION_AUTOCONF6 "autoconf6"
137 typedef void (*ActivationHandleFunc) (NMDevice *self);
140 ActivationHandleFunc func;
142 } ActivationHandleData;
145 CLEANUP_TYPE_DECONFIGURE,
147 CLEANUP_TYPE_REMOVED,
160 NMDeviceStateReason reason;
166 gboolean slave_is_enslaved;
172 NMLogDomain log_domain;
185 } DeleteOnDeactivateData;
187 typedef void (*ArpingCallback) (NMDevice *, NMIP4Config **, gboolean);
190 ArpingCallback callback;
192 NMIP4Config **configs;
195 typedef struct _NMDevicePrivate {
196 gboolean in_state_changed;
198 guint device_link_changed_id;
199 guint device_ip_link_changed_id;
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;
210 char * iface; /* may change, could be renamed by user */
217 char * type_description;
218 NMLinkType link_type;
219 NMDeviceCapabilities capabilities;
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;
230 char * initial_hw_addr;
231 char * physical_port_id;
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) */
239 GCancellable *deactivating_cancellable;
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;
251 NMDeviceStateReason available_reason;
252 NMDeviceStateReason unavailable_reason;
256 NMDeviceState post_state;
257 NMDeviceStateReason post_state_reason;
261 guint link_connected_id;
262 guint link_disconnected_id;
263 guint carrier_defer_id;
265 guint carrier_wait_id;
266 gboolean ignore_carrier;
268 gboolean up; /* IFF_UP */
270 /* Generic DHCP stuff */
271 guint32 dhcp_timeout;
272 char * dhcp_anycast_address;
274 /* IP4 configuration info */
275 NMIP4Config * ip4_config; /* Combined config from VPN, settings, and device */
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 */
284 gboolean v4_is_assumed;
285 NMPlatformIP4Route v4;
287 gboolean v6_is_assumed;
288 NMPlatformIP6Route v6;
291 gboolean v4_commit_first_time;
292 gboolean v6_commit_first_time;
294 /* DHCPv4 tracking */
295 NMDhcpClient * dhcp4_client;
296 gulong dhcp4_state_sigid;
297 NMDhcp4Config * dhcp4_config;
298 guint dhcp4_restart_id;
302 /* dnsmasq stuff for shared connections */
303 NMDnsMasqManager *dnsmasq_manager;
304 gulong dnsmasq_state_id;
308 NMFirewallManagerCallId fw_call;
312 guint ipv4ll_timeout;
317 NMArpingManager * announcing;
320 /* IP6 configuration info */
321 NMIP6Config * ip6_config;
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 */
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;
338 guint linklocal6_timeout_id;
339 guint8 linklocal6_dad_counter;
341 GHashTable * ip6_saved_properties;
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;
353 /* allow autoconnect feature */
354 gboolean autoconnect;
356 /* master interface for bridge/bond/team slave */
358 gboolean is_enslaved;
359 gboolean master_ready_handled;
360 gulong master_ready_id;
362 /* slave management */
364 GSList * slaves; /* list of SlaveInfo */
368 NMConnectionProvider *con_provider;
369 NMLldpListener *lldp_listener;
371 guint check_delete_unrealized_id;
374 static gboolean nm_device_set_ip4_config (NMDevice *self,
376 guint32 default_route_metric,
378 gboolean routes_full_sync,
379 NMDeviceStateReason *reason);
380 static gboolean ip4_config_merge_and_apply (NMDevice *self,
383 NMDeviceStateReason *out_reason);
385 static gboolean nm_device_set_ip6_config (NMDevice *self,
388 gboolean routes_full_sync,
389 NMDeviceStateReason *reason);
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);
395 static gboolean addrconf6_start_with_link_ready (NMDevice *self);
396 static NMActStageReturn linklocal6_start (NMDevice *self);
398 static void _carrier_wait_check_queued_act_request (NMDevice *self);
400 static const char *_activation_func_to_string (ActivationHandleFunc func);
401 static void activation_source_handle_cb (NMDevice *self, int family);
403 static void _set_state_full (NMDevice *self,
405 NMDeviceStateReason reason,
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);
417 /***********************************************************/
419 #define QUEUED_PREFIX "queued state change to "
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",
438 queued_state_to_string (NMDeviceState state)
440 if ((gsize) state < G_N_ELEMENTS (state_table))
441 return state_table[state];
442 return state_table[NM_DEVICE_STATE_UNKNOWN];
446 state_to_string (NMDeviceState state)
448 return queued_state_to_string (state) + strlen (QUEUED_PREFIX);
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"),
518 #define reason_to_string(reason) \
519 NM_UTILS_LOOKUP_STR (_reason_to_string, reason)
521 /***********************************************************/
524 nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value)
526 return nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property), value);
530 nm_device_ipv6_sysctl_get_int32 (NMDevice *self, const char *property, gint32 fallback)
532 return nm_platform_sysctl_get_int32 (NM_PLATFORM_GET, nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property), fallback);
536 nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps)
538 return NM_FLAGS_ANY (NM_DEVICE_GET_PRIVATE (self)->capabilities, caps);
541 /***********************************************************/
544 nm_device_get_udi (NMDevice *self)
546 g_return_val_if_fail (self != NULL, NULL);
548 return NM_DEVICE_GET_PRIVATE (self)->udi;
552 nm_device_get_iface (NMDevice *self)
554 g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
556 return NM_DEVICE_GET_PRIVATE (self)->iface;
560 nm_device_get_ifindex (NMDevice *self)
562 g_return_val_if_fail (NM_IS_DEVICE (self), 0);
564 return NM_DEVICE_GET_PRIVATE (self)->ifindex;
568 * nm_device_is_software:
569 * @self: the #NMDevice
571 * Indicates if the device is a software-based virtual device without
572 * backing hardware, which can be added and removed programmatically.
574 * Returns: %TRUE if the device is a software-based device
577 nm_device_is_software (NMDevice *self)
579 return NM_FLAGS_HAS (NM_DEVICE_GET_PRIVATE (self)->capabilities, NM_DEVICE_CAP_IS_SOFTWARE);
584 * @self: the #NMDevice
586 * Returns: %TRUE if the device exists, %FALSE if the device is a placeholder
589 nm_device_is_real (NMDevice *self)
591 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
593 return NM_DEVICE_GET_PRIVATE (self)->real;
597 nm_device_get_ip_iface (NMDevice *self)
599 NMDevicePrivate *priv;
601 g_return_val_if_fail (self != NULL, NULL);
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;
609 nm_device_get_ip_ifindex (NMDevice *self)
611 NMDevicePrivate *priv;
613 g_return_val_if_fail (self != NULL, 0);
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;
621 nm_device_set_ip_iface (NMDevice *self, const char *iface)
623 NMDevicePrivate *priv;
626 g_return_if_fail (NM_IS_DEVICE (self));
628 priv = NM_DEVICE_GET_PRIVATE (self);
629 if (!g_strcmp0 (iface, priv->ip_iface))
632 old_ip_iface = priv->ip_iface;
633 priv->ip_ifindex = 0;
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);
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);
645 /* Device IP interface must always be a kernel network interface */
646 _LOGW (LOGD_HW, "failed to look up interface index");
650 /* We don't care about any saved values from the old iface */
651 g_hash_table_remove_all (priv->ip6_saved_properties);
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);
660 get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid)
662 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
663 NMLinkType link_type;
664 const guint8 *hwaddr = NULL;
665 size_t hwaddr_len = 0;
669 /* If we get here, we *must* have a kernel netdev, which implies an ifindex */
670 ifindex = nm_device_get_ip_ifindex (self);
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);
676 hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddr_len);
680 success = nm_utils_get_ipv6_interface_identifier (link_type,
686 _LOGW (LOGD_HW, "failed to generate interface identifier "
687 "for link type %u hwaddr_len %zu", link_type, hwaddr_len);
693 nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid)
695 return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid);
699 nm_device_get_driver (NMDevice *self)
701 g_return_val_if_fail (self != NULL, NULL);
703 return NM_DEVICE_GET_PRIVATE (self)->driver;
707 nm_device_get_driver_version (NMDevice *self)
709 g_return_val_if_fail (self != NULL, NULL);
711 return NM_DEVICE_GET_PRIVATE (self)->driver_version;
715 nm_device_get_device_type (NMDevice *self)
717 g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_TYPE_UNKNOWN);
719 return NM_DEVICE_GET_PRIVATE (self)->type;
723 nm_device_get_link_type (NMDevice *self)
725 g_return_val_if_fail (NM_IS_DEVICE (self), NM_LINK_TYPE_UNKNOWN);
727 return NM_DEVICE_GET_PRIVATE (self)->link_type;
731 * nm_device_get_metered:
732 * @setting: the #NMDevice
734 * Returns: the #NMDevice:metered property of the device.
739 nm_device_get_metered (NMDevice *self)
741 g_return_val_if_fail (NM_IS_DEVICE (self), NM_METERED_UNKNOWN);
743 return NM_DEVICE_GET_PRIVATE (self)->metered;
747 * nm_device_get_priority():
748 * @self: the #NMDevice
750 * Returns: the device's routing priority. Lower numbers means a "better"
751 * device, eg higher priority.
754 nm_device_get_priority (NMDevice *self)
756 g_return_val_if_fail (NM_IS_DEVICE (self), 1000);
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.
762 * Currently for both IPv4 and IPv6 we use the same default values.
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".
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).
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:
780 case NM_DEVICE_TYPE_INFINIBAND:
782 case NM_DEVICE_TYPE_ADSL:
784 case NM_DEVICE_TYPE_WIMAX:
786 case NM_DEVICE_TYPE_BOND:
788 case NM_DEVICE_TYPE_TEAM:
790 case NM_DEVICE_TYPE_VLAN:
792 case NM_DEVICE_TYPE_MACVLAN:
794 case NM_DEVICE_TYPE_BRIDGE:
796 case NM_DEVICE_TYPE_TUN:
798 case NM_DEVICE_TYPE_VXLAN:
800 case NM_DEVICE_TYPE_WIFI:
802 case NM_DEVICE_TYPE_OLPC_MESH:
804 case NM_DEVICE_TYPE_IP_TUNNEL:
806 case NM_DEVICE_TYPE_MODEM:
808 case NM_DEVICE_TYPE_BT:
810 case NM_DEVICE_TYPE_GENERIC:
812 case NM_DEVICE_TYPE_UNKNOWN:
814 case NM_DEVICE_TYPE_UNUSED1:
815 case NM_DEVICE_TYPE_UNUSED2:
816 /* omit default: to get compiler warning about missing switch cases */
823 _get_ipx_route_metric (NMDevice *self,
828 NMSettingIPConfig *s_ip;
829 NMConnection *connection;
831 g_return_val_if_fail (NM_IS_DEVICE (self), G_MAXUINT32);
833 connection = nm_device_get_applied_connection (self);
836 ? nm_connection_get_setting_ip4_config (connection)
837 : nm_connection_get_setting_ip6_config (connection);
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.
844 route_metric = nm_setting_ip_config_get_route_metric (s_ip);
845 if (route_metric >= 0)
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);
856 route_metric = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, -1);
859 if (route_metric >= 0)
862 route_metric = nm_device_get_priority (self);
865 route_metric = nm_utils_ip6_route_metric_normalize (route_metric);
870 nm_device_get_ip4_route_metric (NMDevice *self)
872 return _get_ipx_route_metric (self, TRUE);
876 nm_device_get_ip6_route_metric (NMDevice *self)
878 return _get_ipx_route_metric (self, FALSE);
881 const NMPlatformIP4Route *
882 nm_device_get_ip4_default_route (NMDevice *self, gboolean *out_is_assumed)
884 NMDevicePrivate *priv;
886 g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
888 priv = NM_DEVICE_GET_PRIVATE (self);
891 *out_is_assumed = priv->default_route.v4_is_assumed;
893 return priv->default_route.v4_has ? &priv->default_route.v4 : NULL;
896 const NMPlatformIP6Route *
897 nm_device_get_ip6_default_route (NMDevice *self, gboolean *out_is_assumed)
899 NMDevicePrivate *priv;
901 g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
903 priv = NM_DEVICE_GET_PRIVATE (self);
906 *out_is_assumed = priv->default_route.v6_is_assumed;
908 return priv->default_route.v6_has ? &priv->default_route.v6 : NULL;
912 nm_device_get_type_desc (NMDevice *self)
914 g_return_val_if_fail (self != NULL, NULL);
916 return NM_DEVICE_GET_PRIVATE (self)->type_desc;
920 nm_device_get_type_description (NMDevice *self)
922 g_return_val_if_fail (self != NULL, NULL);
924 /* Beware: this function should return the same
925 * value as nm_device_get_type_description() in libnm. */
927 return NM_DEVICE_GET_CLASS (self)->get_type_description (self);
931 get_type_description (NMDevice *self)
933 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
935 if (!priv->type_description) {
936 const char *typename;
938 typename = G_OBJECT_TYPE_NAME (self);
939 if (g_str_has_prefix (typename, "NMDevice"))
941 priv->type_description = g_ascii_strdown (typename, -1);
944 return priv->type_description;
948 nm_device_has_carrier (NMDevice *self)
950 return NM_DEVICE_GET_PRIVATE (self)->carrier;
954 nm_device_get_act_request (NMDevice *self)
956 g_return_val_if_fail (self != NULL, NULL);
958 return NM_DEVICE_GET_PRIVATE (self)->act_request;
961 NMSettingsConnection *
962 nm_device_get_settings_connection (NMDevice *self)
964 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
966 return priv->act_request ? nm_act_request_get_settings_connection (priv->act_request) : NULL;
970 nm_device_get_applied_connection (NMDevice *self)
972 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
974 return priv->act_request ? nm_act_request_get_applied_connection (priv->act_request) : NULL;
978 nm_device_has_unmodified_applied_connection (NMDevice *self, NMSettingCompareFlags compare_flags)
980 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
982 if (!priv->act_request)
985 return nm_active_connection_has_unmodified_applied_connection ((NMActiveConnection *) priv->act_request, compare_flags);
989 nm_device_get_applied_setting (NMDevice *device, GType setting_type)
992 NMSetting *setting = NULL;
994 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
996 req = nm_device_get_act_request (device);
998 NMConnection *connection;
1000 connection = nm_act_request_get_applied_connection (req);
1002 setting = nm_connection_get_setting (connection, setting_type);
1009 nm_device_get_rfkill_type (NMDevice *self)
1011 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
1013 return NM_DEVICE_GET_PRIVATE (self)->rfkill_type;
1017 nm_device_get_physical_port_id (NMDevice *self)
1019 return NM_DEVICE_GET_PRIVATE (self)->physical_port_id;
1022 /***********************************************************/
1025 nm_device_uses_generated_assumed_connection (NMDevice *self)
1027 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1028 NMSettingsConnection *connection;
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);
1034 && nm_settings_connection_get_nm_generated_assumed (connection))
1041 nm_device_uses_assumed_connection (NMDevice *self)
1043 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1045 if ( priv->act_request
1046 && nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (priv->act_request)))
1052 find_slave_info (NMDevice *self, NMDevice *slave)
1054 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1058 for (iter = priv->slaves; iter; iter = g_slist_next (iter)) {
1060 if (info->slave == slave)
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
1072 * If @self is capable of enslaving other devices (ie it's a bridge, bond, team,
1073 * etc) then this function enslaves @slave.
1075 * Returns: %TRUE on success, %FALSE on failure or if this device cannot enslave
1079 nm_device_master_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *connection)
1082 gboolean success = FALSE;
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);
1089 info = find_slave_info (self, slave);
1093 if (info->slave_is_enslaved)
1096 configure = (info->configure && connection != NULL);
1098 g_return_val_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE);
1100 success = NM_DEVICE_GET_CLASS (self)->enslave_slave (self, slave, connection, configure);
1101 info->slave_is_enslaved = success;
1104 nm_device_slave_notify_enslave (info->slave, success);
1106 /* Ensure the device's hardware address is up-to-date; it often changes
1107 * when slaves change.
1109 nm_device_update_hw_address (self);
1111 /* Restart IP configuration if we're waiting for slaves. Do this
1112 * after updating the hardware address as IP config may need the
1116 if (NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT)
1117 nm_device_activate_stage3_ip4_start (self);
1119 if (NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT)
1120 nm_device_activate_stage3_ip6_start (self);
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
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.
1138 nm_device_master_release_one_slave (NMDevice *self, NMDevice *slave, gboolean configure, NMDeviceStateReason reason)
1140 NMDevicePrivate *priv;
1141 NMDevicePrivate *slave_priv;
1143 gs_unref_object NMDevice *self_free = NULL;
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);
1149 info = find_slave_info (self, slave);
1151 _LOGt (LOGD_CORE, "master: release one slave %p/%s%s", slave, nm_device_get_iface (slave),
1152 !info ? " (not registered)" : "");
1155 g_return_if_reached ();
1157 priv = NM_DEVICE_GET_PRIVATE (self);
1158 slave_priv = NM_DEVICE_GET_PRIVATE (slave);
1160 g_return_if_fail (self == slave_priv->master);
1161 nm_assert (slave == info->slave);
1163 /* first, let subclasses handle the release ... */
1164 if (info->slave_is_enslaved)
1165 NM_DEVICE_GET_CLASS (self)->release_slave (self, slave, configure);
1167 /* raise notifications about the release, including clearing is_enslaved. */
1168 nm_device_slave_notify_release (slave, reason);
1170 /* keep both alive until the end of the function.
1171 * Transfers ownership from slave_priv->master. */
1174 priv->slaves = g_slist_remove (priv->slaves, info);
1175 slave_priv->master = NULL;
1177 g_signal_handler_disconnect (slave, info->watch_id);
1178 g_object_unref (slave);
1179 g_slice_free (SlaveInfo, info);
1181 /* Ensure the device's hardware address is up-to-date; it often changes
1182 * when slaves change.
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);
1189 * can_unmanaged_external_down:
1192 * Check whether the device should stay NM_UNMANAGED_EXTERNAL_DOWN unless
1193 * IFF_UP-ed externally.
1196 can_unmanaged_external_down (NMDevice *self)
1198 return !NM_DEVICE_GET_PRIVATE (self)->is_nm_owned
1199 && nm_device_is_software (self);
1202 static NMUnmanFlagOp
1203 is_unmanaged_external_down (NMDevice *self, gboolean consider_can)
1205 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1208 && !NM_DEVICE_GET_CLASS (self)->can_unmanaged_external_down (self))
1209 return NM_UNMAN_FLAG_OP_FORGET;
1211 /* Manage externally-created software interfaces only when they are IFF_UP */
1212 if ( priv->ifindex <= 0
1214 return NM_UNMAN_FLAG_OP_SET_UNMANAGED;
1216 return NM_UNMAN_FLAG_OP_SET_MANAGED;
1220 set_unmanaged_external_down (NMDevice *self)
1222 NMUnmanFlagOp ext_flags;
1224 if (!nm_device_get_unmanaged_mask (self, NM_UNMANAGED_EXTERNAL_DOWN))
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.
1232 nm_device_queue_recheck_assume (self);
1235 nm_device_set_unmanaged_by_flags (self,
1236 NM_UNMANAGED_EXTERNAL_DOWN,
1238 NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
1242 nm_device_update_dynamic_ip_setup (NMDevice *self)
1244 NMDevicePrivate *priv;
1249 g_return_if_fail (NM_IS_DEVICE (self));
1251 priv = NM_DEVICE_GET_PRIVATE (self);
1253 g_hash_table_remove_all (priv->ip6_saved_properties);
1255 if (priv->dhcp4_client) {
1256 if (!nm_device_dhcp4_renew (self, FALSE)) {
1257 nm_device_state_changed (self,
1258 NM_DEVICE_STATE_FAILED,
1259 NM_DEVICE_STATE_REASON_DHCP_FAILED);
1263 if (priv->dhcp6_client) {
1264 if (!nm_device_dhcp6_renew (self, FALSE)) {
1265 nm_device_state_changed (self,
1266 NM_DEVICE_STATE_FAILED,
1267 NM_DEVICE_STATE_REASON_DHCP_FAILED);
1274 if (priv->dnsmasq_manager) {
1278 if (priv->lldp_listener && nm_lldp_listener_is_running (priv->lldp_listener)) {
1279 nm_lldp_listener_stop (priv->lldp_listener);
1280 addr = nm_platform_link_get_address (NM_PLATFORM_GET, priv->ifindex, &addr_length);
1282 if (!nm_lldp_listener_start (priv->lldp_listener, nm_device_get_ifindex (self), &error)) {
1283 _LOGD (LOGD_DEVICE, "LLDP listener %p could not be restarted: %s",
1284 priv->lldp_listener, error->message);
1285 g_clear_error (&error);
1291 carrier_changed (NMDevice *self, gboolean carrier)
1293 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1295 if (priv->state <= NM_DEVICE_STATE_UNMANAGED)
1298 nm_device_recheck_available_connections (self);
1300 /* ignore-carrier devices ignore all carrier-down events */
1301 if (priv->ignore_carrier && !carrier)
1304 if (priv->is_master) {
1305 /* Bridge/bond/team carrier does not affect its own activation,
1306 * but when carrier comes on, if there are slaves waiting,
1307 * it will restart them.
1312 if (nm_device_activate_ip4_state_in_wait (self))
1313 nm_device_activate_stage3_ip4_start (self);
1314 if (nm_device_activate_ip6_state_in_wait (self))
1315 nm_device_activate_stage3_ip6_start (self);
1318 } else if (nm_device_get_enslaved (self) && !carrier) {
1319 /* Slaves don't deactivate when they lose carrier; for
1320 * bonds/teams in particular that would be actively
1321 * counterproductive.
1327 if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) {
1328 nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED,
1329 NM_DEVICE_STATE_REASON_CARRIER);
1330 } else if (priv->state == NM_DEVICE_STATE_DISCONNECTED) {
1331 /* If the device is already in DISCONNECTED state without a carrier
1332 * (probably because it is tagged for carrier ignore) ensure that
1333 * when the carrier appears, auto connections are rechecked for
1336 nm_device_emit_recheck_auto_activate (self);
1337 } else if (priv->state == NM_DEVICE_STATE_ACTIVATED) {
1338 /* If the device is active without a carrier (probably because it is
1339 * tagged for carrier ignore) ensure that when the carrier appears we
1340 * renew DHCP leases and such.
1342 nm_device_update_dynamic_ip_setup (self);
1345 if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) {
1346 if (nm_device_queued_state_peek (self) >= NM_DEVICE_STATE_DISCONNECTED)
1347 nm_device_queued_state_clear (self);
1349 nm_device_queue_state (self, NM_DEVICE_STATE_UNAVAILABLE,
1350 NM_DEVICE_STATE_REASON_CARRIER);
1355 #define LINK_DISCONNECT_DELAY 4
1358 link_disconnect_action_cb (gpointer user_data)
1360 NMDevice *self = NM_DEVICE (user_data);
1361 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1363 _LOGD (LOGD_DEVICE, "link disconnected (calling deferred action) (id=%u)", priv->carrier_defer_id);
1365 priv->carrier_defer_id = 0;
1367 _LOGI (LOGD_DEVICE, "link disconnected (calling deferred action)");
1369 NM_DEVICE_GET_CLASS (self)->carrier_changed (self, FALSE);
1375 link_disconnect_action_cancel (NMDevice *self)
1377 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1379 if (priv->carrier_defer_id) {
1380 g_source_remove (priv->carrier_defer_id);
1381 _LOGD (LOGD_DEVICE, "link disconnected (canceling deferred action) (id=%u)", priv->carrier_defer_id);
1382 priv->carrier_defer_id = 0;
1387 nm_device_set_carrier (NMDevice *self, gboolean carrier)
1389 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1390 NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
1391 NMDeviceState state = nm_device_get_state (self);
1393 if (priv->carrier == carrier)
1396 priv->carrier = carrier;
1397 _notify (self, PROP_CARRIER);
1399 if (priv->carrier) {
1400 _LOGI (LOGD_DEVICE, "link connected");
1401 link_disconnect_action_cancel (self);
1402 klass->carrier_changed (self, TRUE);
1404 if (nm_clear_g_source (&priv->carrier_wait_id)) {
1405 nm_device_remove_pending_action (self, "carrier wait", TRUE);
1406 _carrier_wait_check_queued_act_request (self);
1408 } else if (state <= NM_DEVICE_STATE_DISCONNECTED) {
1409 _LOGI (LOGD_DEVICE, "link disconnected");
1410 klass->carrier_changed (self, FALSE);
1412 _LOGI (LOGD_DEVICE, "link disconnected (deferring action for %d seconds)", LINK_DISCONNECT_DELAY);
1413 priv->carrier_defer_id = g_timeout_add_seconds (LINK_DISCONNECT_DELAY,
1414 link_disconnect_action_cb, self);
1415 _LOGD (LOGD_DEVICE, "link disconnected (deferring action for %d seconds) (id=%u)",
1416 LINK_DISCONNECT_DELAY, priv->carrier_defer_id);
1421 device_recheck_slave_status (NMDevice *self, const NMPlatformLink *plink)
1423 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1425 g_return_if_fail (plink);
1427 if (plink->master <= 0)
1431 if ( plink->master > 0
1432 && plink->master == nm_device_get_ifindex (priv->master)) {
1433 /* call add-slave again. We expect @self already to be added to
1434 * the master, but this also triggers a recheck-assume. */
1435 nm_device_master_add_slave (priv->master, self, FALSE);
1439 nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
1441 if (plink->master > 0) {
1444 master = nm_manager_get_device_by_ifindex (nm_manager_get (), plink->master);
1445 if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave)
1446 nm_device_master_add_slave (master, self, FALSE);
1448 _LOGI (LOGD_DEVICE, "enslaved to non-master-type device %s; ignoring",
1449 nm_device_get_iface (master));
1451 _LOGW (LOGD_DEVICE, "enslaved to unknown device %d %s",
1453 nm_platform_link_get_name (NM_PLATFORM_GET, plink->master));
1459 device_link_changed (NMDevice *self)
1461 NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
1462 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1463 NMUtilsIPv6IfaceId token_iid;
1464 gboolean ip_ifname_changed = FALSE;
1466 NMPlatformLink info;
1467 const NMPlatformLink *pllink;
1470 priv->device_link_changed_id = 0;
1472 ifindex = nm_device_get_ifindex (self);
1473 pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex);
1475 return G_SOURCE_REMOVE;
1479 udi = nm_platform_link_get_udi (NM_PLATFORM_GET, info.ifindex);
1480 if (udi && g_strcmp0 (udi, priv->udi)) {
1481 /* Update UDI to what udev gives us */
1483 priv->udi = g_strdup (udi);
1484 _notify (self, PROP_UDI);
1487 if (g_strcmp0 (info.driver, priv->driver)) {
1488 /* Update driver to what udev gives us */
1489 g_free (priv->driver);
1490 priv->driver = g_strdup (info.driver);
1491 _notify (self, PROP_DRIVER);
1494 /* Update MTU if it has changed. */
1495 if (priv->mtu != info.mtu) {
1496 priv->mtu = info.mtu;
1497 _notify (self, PROP_MTU);
1500 if (info.driver && g_strcmp0 (priv->driver, info.driver) != 0) {
1501 g_free (priv->driver);
1502 priv->driver = g_strdup (info.driver);
1503 _notify (self, PROP_DRIVER);
1506 if (info.name[0] && strcmp (priv->iface, info.name) != 0) {
1507 _LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'",
1508 priv->ifindex, priv->iface, info.name);
1509 g_free (priv->iface);
1510 priv->iface = g_strdup (info.name);
1512 /* If the device has no explicit ip_iface, then changing iface changes ip_iface too. */
1513 ip_ifname_changed = !priv->ip_iface;
1515 _notify (self, PROP_IFACE);
1516 if (ip_ifname_changed)
1517 _notify (self, PROP_IP_IFACE);
1519 /* Re-match available connections against the new interface name */
1520 nm_device_recheck_available_connections (self);
1522 /* Let any connections that use the new interface name have a chance
1523 * to auto-activate on the device.
1525 nm_device_emit_recheck_auto_activate (self);
1528 if (priv->rdisc && nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &token_iid)) {
1529 _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
1530 if (nm_rdisc_set_iid (priv->rdisc, token_iid))
1531 nm_rdisc_start (priv->rdisc);
1534 if (klass->link_changed)
1535 klass->link_changed (self, &info);
1537 /* Update DHCP, etc, if needed */
1538 if (ip_ifname_changed)
1539 nm_device_update_dynamic_ip_setup (self);
1541 priv->up = NM_FLAGS_HAS (info.n_ifi_flags, IFF_UP);
1543 if ( info.initialized
1544 && nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
1545 NMDeviceStateReason reason;
1547 nm_device_set_unmanaged_by_user_udev (self);
1549 /* If the device is a external-down candidated but no longer has external
1550 * down set, we must clear the platform-unmanaged flag with reason
1552 if ( nm_device_get_unmanaged_mask (self, NM_UNMANAGED_EXTERNAL_DOWN)
1553 && !nm_device_get_unmanaged_flags (self, NM_UNMANAGED_EXTERNAL_DOWN)) {
1554 /* Ensure the assume check is queued before any queued state changes
1555 * from the transition to UNAVAILABLE.
1557 nm_device_queue_recheck_assume (self);
1558 reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED;
1560 reason = NM_DEVICE_STATE_REASON_NOW_MANAGED;
1562 nm_device_set_unmanaged_by_flags (self, NM_UNMANAGED_PLATFORM_INIT, FALSE, reason);
1565 set_unmanaged_external_down (self);
1567 device_recheck_slave_status (self, &info);
1568 return G_SOURCE_REMOVE;
1572 device_ip_link_changed (NMDevice *self)
1574 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1575 const NMPlatformLink *pllink;
1577 priv->device_ip_link_changed_id = 0;
1579 if (!priv->ip_ifindex)
1580 return G_SOURCE_REMOVE;
1582 pllink = nm_platform_link_get (NM_PLATFORM_GET, priv->ip_ifindex);
1584 return G_SOURCE_REMOVE;
1586 if (pllink->name[0] && g_strcmp0 (priv->ip_iface, pllink->name)) {
1587 _LOGI (LOGD_DEVICE, "interface index %d renamed ip_iface (%d) from '%s' to '%s'",
1588 priv->ifindex, nm_device_get_ip_ifindex (self),
1589 priv->ip_iface, pllink->name);
1590 g_free (priv->ip_iface);
1591 priv->ip_iface = g_strdup (pllink->name);
1593 _notify (self, PROP_IP_IFACE);
1594 nm_device_update_dynamic_ip_setup (self);
1596 return G_SOURCE_REMOVE;
1600 link_changed_cb (NMPlatform *platform,
1601 NMPObjectType obj_type,
1603 NMPlatformLink *info,
1604 NMPlatformSignalChangeType change_type,
1607 NMDevicePrivate *priv;
1609 if (change_type != NM_PLATFORM_SIGNAL_CHANGED)
1612 priv = NM_DEVICE_GET_PRIVATE (self);
1614 if (ifindex == nm_device_get_ifindex (self)) {
1615 if (!priv->device_link_changed_id) {
1616 priv->device_link_changed_id = g_idle_add ((GSourceFunc) device_link_changed, self);
1617 _LOGD (LOGD_DEVICE, "queued link change for ifindex %d", ifindex);
1619 } else if (ifindex == nm_device_get_ip_ifindex (self)) {
1620 if (!priv->device_ip_link_changed_id) {
1621 priv->device_ip_link_changed_id = g_idle_add ((GSourceFunc) device_ip_link_changed, self);
1622 _LOGD (LOGD_DEVICE, "queued link change for ip-ifindex %d", ifindex);
1628 link_changed (NMDevice *self, NMPlatformLink *info)
1630 /* Update carrier from link event if applicable. */
1631 if ( nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)
1632 && !nm_device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER))
1633 nm_device_set_carrier (self, info->connected);
1637 link_type_compatible (NMDevice *self,
1638 NMLinkType link_type,
1639 gboolean *out_compatible,
1642 NMDeviceClass *klass;
1643 NMLinkType device_type;
1646 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
1648 klass = NM_DEVICE_GET_CLASS (self);
1650 if (!klass->link_types) {
1651 NM_SET_OUT (out_compatible, FALSE);
1652 g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
1653 "Device does not support platform links");
1657 device_type = self->priv->link_type;
1658 if (device_type > NM_LINK_TYPE_UNKNOWN && device_type != link_type) {
1659 g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
1660 "Needed link type 0x%x does not match the platform link type 0x%X",
1661 device_type, link_type);
1665 for (i = 0; klass->link_types[i] > NM_LINK_TYPE_UNKNOWN; i++) {
1666 if (klass->link_types[i] == link_type)
1668 if (klass->link_types[i] == NM_LINK_TYPE_ANY)
1672 NM_SET_OUT (out_compatible, FALSE);
1673 g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
1674 "Device does not support platform link type 0x%X",
1680 * nm_device_realize_start():
1681 * @self: the #NMDevice
1682 * @plink: an existing platform link or %NULL
1683 * @out_compatible: %TRUE on return if @self is compatible with @plink
1684 * @error: location to store error, or %NULL
1686 * Initializes and sets up the device using existing backing resources. Before
1687 * the device is ready for use nm_device_realize_finish() must be called.
1688 * @out_compatible will only be set if @plink is not %NULL, and
1690 * Important: if nm_device_realize_start() returns %TRUE, the caller MUST
1691 * also call nm_device_realize_finish() to balance g_object_freeze_notify().
1693 * Returns: %TRUE on success, %FALSE on error
1696 nm_device_realize_start (NMDevice *self,
1697 const NMPlatformLink *plink,
1698 gboolean *out_compatible,
1701 NM_SET_OUT (out_compatible, TRUE);
1704 if (g_strcmp0 (nm_device_get_iface (self), plink->name) != 0) {
1705 NM_SET_OUT (out_compatible, FALSE);
1706 g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
1707 "Device interface name does not match platform link");
1711 if (!link_type_compatible (self, plink->type, out_compatible, error))
1715 realize_start_setup (self, plink);
1721 * nm_device_create_and_realize():
1722 * @self: the #NMDevice
1723 * @connection: the #NMConnection being activated
1724 * @parent: the parent #NMDevice if any
1725 * @error: location to store error, or %NULL
1727 * Creates any backing resources needed to realize the device to proceed
1728 * with activating @connection.
1730 * Returns: %TRUE on success, %FALSE on error
1733 nm_device_create_and_realize (NMDevice *self,
1734 NMConnection *connection,
1738 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1739 NMPlatformLink plink_copy;
1740 const NMPlatformLink *plink = NULL;
1742 /* Must be set before device is realized */
1743 priv->is_nm_owned = !nm_platform_link_get_by_ifname (NM_PLATFORM_GET, priv->iface);
1745 _LOGD (LOGD_DEVICE, "create (is %snm-owned)", priv->is_nm_owned ? "" : "not ");
1747 /* Create any resources the device needs */
1748 if (NM_DEVICE_GET_CLASS (self)->create_and_realize) {
1749 if (!NM_DEVICE_GET_CLASS (self)->create_and_realize (self, connection, parent, &plink, error))
1751 plink_copy = *plink;
1752 plink = &plink_copy;
1755 realize_start_setup (self, plink);
1756 nm_device_realize_finish (self, plink);
1758 if (nm_device_get_managed (self, FALSE)) {
1759 nm_device_state_changed (self,
1760 NM_DEVICE_STATE_UNAVAILABLE,
1761 NM_DEVICE_STATE_REASON_NOW_MANAGED);
1767 update_device_from_platform_link (NMDevice *self, const NMPlatformLink *plink)
1769 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1772 g_return_if_fail (plink != NULL);
1774 udi = nm_platform_link_get_udi (NM_PLATFORM_GET, plink->ifindex);
1775 if (udi && !g_strcmp0 (udi, priv->udi)) {
1777 priv->udi = g_strdup (udi);
1778 _notify (self, PROP_UDI);
1781 if (!g_strcmp0 (plink->name, priv->iface)) {
1782 g_free (priv->iface);
1783 priv->iface = g_strdup (plink->name);
1784 _notify (self, PROP_IFACE);
1787 priv->ifindex = plink->ifindex;
1788 _notify (self, PROP_IFINDEX);
1790 priv->up = NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP);
1791 if (plink->driver && g_strcmp0 (plink->driver, priv->driver) != 0) {
1792 g_free (priv->driver);
1793 priv->driver = g_strdup (plink->driver);
1794 _notify (self, PROP_DRIVER);
1799 config_changed_update_ignore_carrier (NMConfig *config,
1800 NMConfigData *config_data,
1801 NMConfigChangeFlags changes,
1802 NMConfigData *old_data,
1805 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
1807 if ( priv->state <= NM_DEVICE_STATE_DISCONNECTED
1808 || priv->state > NM_DEVICE_STATE_ACTIVATED)
1809 priv->ignore_carrier = nm_config_data_get_ignore_carrier (config_data, self);
1813 check_carrier (NMDevice *self)
1815 int ifindex = nm_device_get_ip_ifindex (self);
1817 if (!nm_device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER))
1818 nm_device_set_carrier (self, nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex));
1822 realize_start_notify (NMDevice *self, const NMPlatformLink *plink)
1824 /* Stub implementation for realize_start_notify(). It does nothing,
1825 * but allows derived classes to uniformly invoke the parent
1826 * implementation. */
1830 * realize_start_setup():
1831 * @self: the #NMDevice
1832 * @plink: the #NMPlatformLink if backed by a kernel netdevice
1834 * Update the device from backing resource properties (like hardware
1835 * addresses, carrier states, driver/firmware info, etc). This function
1836 * should only change properties for this device, and should not perform
1837 * any tasks that affect other interfaces (like master/slave or parent/child
1841 realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
1843 NMDevicePrivate *priv;
1844 NMDeviceClass *klass;
1845 static guint32 id = 0;
1847 g_return_if_fail (NM_IS_DEVICE (self));
1849 priv = NM_DEVICE_GET_PRIVATE (self);
1851 /* The device should not be realized */
1852 g_return_if_fail (!priv->real);
1853 g_return_if_fail (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT));
1854 g_return_if_fail (priv->ip_ifindex <= 0);
1855 g_return_if_fail (priv->ip_iface == NULL);
1857 _LOGD (LOGD_DEVICE, "start setup of %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), plink ? plink->ifindex : 0);
1859 klass = NM_DEVICE_GET_CLASS (self);
1861 /* Balanced by a thaw in nm_device_realize_finish() */
1862 g_object_freeze_notify (G_OBJECT (self));
1865 g_return_if_fail (link_type_compatible (self, plink->type, NULL, NULL));
1866 update_device_from_platform_link (self, plink);
1869 if (priv->ifindex > 0) {
1870 priv->physical_port_id = nm_platform_link_get_physical_port_id (NM_PLATFORM_GET, priv->ifindex);
1871 _notify (self, PROP_PHYSICAL_PORT_ID);
1873 priv->dev_id = nm_platform_link_get_dev_id (NM_PLATFORM_GET, priv->ifindex);
1875 if (nm_platform_link_is_software (NM_PLATFORM_GET, priv->ifindex))
1876 priv->capabilities |= NM_DEVICE_CAP_IS_SOFTWARE;
1878 priv->mtu = nm_platform_link_get_mtu (NM_PLATFORM_GET, priv->ifindex);
1879 _notify (self, PROP_MTU);
1881 nm_platform_link_get_driver_info (NM_PLATFORM_GET,
1884 &priv->driver_version,
1885 &priv->firmware_version);
1886 if (priv->driver_version)
1887 _notify (self, PROP_DRIVER_VERSION);
1888 if (priv->firmware_version)
1889 _notify (self, PROP_FIRMWARE_VERSION);
1891 if (nm_platform_check_support_user_ipv6ll (NM_PLATFORM_GET))
1892 priv->nm_ipv6ll = nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, priv->ifindex);
1895 if (klass->get_generic_capabilities)
1896 priv->capabilities |= klass->get_generic_capabilities (self);
1899 /* Use a placeholder UDI until we get a real one */
1900 priv->udi = g_strdup_printf ("/virtual/device/placeholder/%d", id++);
1901 _notify (self, PROP_UDI);
1904 /* trigger initial ip config change to initialize ip-config */
1905 priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
1906 priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
1908 nm_device_update_hw_address (self);
1909 nm_device_update_initial_hw_address (self);
1911 /* Note: initial hardware address must be read before calling get_ignore_carrier() */
1912 if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
1913 NMConfig *config = nm_config_get ();
1915 priv->ignore_carrier = nm_config_data_get_ignore_carrier (nm_config_get_data (config), self);
1916 g_signal_connect (G_OBJECT (config),
1917 NM_CONFIG_SIGNAL_CONFIG_CHANGED,
1918 G_CALLBACK (config_changed_update_ignore_carrier),
1921 check_carrier (self);
1924 priv->carrier ? "ON" : "OFF",
1925 priv->ignore_carrier ? " (but ignored)" : "");
1927 /* Fake online link when carrier detection is not available. */
1928 priv->carrier = TRUE;
1931 _notify (self, PROP_CAPABILITIES);
1933 klass->realize_start_notify (self, plink);
1935 /* Do not manage externally created software devices until they are IFF_UP
1936 * or have IP addressing */
1937 nm_device_set_unmanaged_flags (self,
1938 NM_UNMANAGED_EXTERNAL_DOWN,
1939 is_unmanaged_external_down (self, TRUE));
1941 /* Unmanaged the loopback device with an explicit NM_UNMANAGED_LOOPBACK flag.
1942 * Later we might want to manage 'lo' too. Currently that doesn't work because
1943 * NetworkManager might down the interface or remove the 127.0.0.1 address. */
1944 nm_device_set_unmanaged_flags (self, NM_UNMANAGED_LOOPBACK, priv->ifindex == 1);
1946 nm_device_set_unmanaged_by_user_udev (self);
1948 nm_device_set_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT,
1949 plink && !plink->initialized);
1953 * nm_device_realize_finish():
1954 * @self: the #NMDevice
1955 * @plink: the #NMPlatformLink if backed by a kernel netdevice
1957 * Update the device's master/slave or parent/child relationships from
1958 * backing resource properties. After this function finishes, the device
1959 * is ready for network connectivity.
1962 nm_device_realize_finish (NMDevice *self, const NMPlatformLink *plink)
1964 NMDevicePrivate *priv;
1966 g_return_if_fail (NM_IS_DEVICE (self));
1967 g_return_if_fail (!plink || link_type_compatible (self, plink->type, NULL, NULL));
1969 priv = NM_DEVICE_GET_PRIVATE (self);
1971 g_return_if_fail (!priv->real);
1974 device_recheck_slave_status (self, plink);
1977 _notify (self, PROP_REAL);
1979 nm_device_recheck_available_connections (self);
1981 /* Balanced by a freeze in realize_start_setup(). */
1982 g_object_thaw_notify (G_OBJECT (self));
1986 unrealize_notify (NMDevice *self)
1988 /* Stub implementation for unrealize_notify(). It does nothing,
1989 * but allows derived classes to uniformly invoke the parent
1990 * implementation. */
1994 available_connections_check_delete_unrealized_on_idle (gpointer user_data)
1996 NMDevice *self = user_data;
1997 NMDevicePrivate *priv;
1999 g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE);
2001 priv = NM_DEVICE_GET_PRIVATE (self);
2003 priv->check_delete_unrealized_id = 0;
2005 if ( g_hash_table_size (priv->available_connections) == 0
2006 && !nm_device_is_real (self))
2007 g_signal_emit (self, signals[REMOVED], 0);
2009 return G_SOURCE_REMOVE;
2013 available_connections_check_delete_unrealized (NMDevice *self)
2015 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2017 /* always rescheadule the remove signal. */
2018 nm_clear_g_source (&priv->check_delete_unrealized_id);
2020 if ( g_hash_table_size (priv->available_connections) == 0
2021 && !nm_device_is_real (self))
2022 priv->check_delete_unrealized_id = g_idle_add (available_connections_check_delete_unrealized_on_idle, self);
2026 * nm_device_unrealize():
2027 * @self: the #NMDevice
2028 * @remove_resources: if %TRUE, remove backing resources
2029 * @error: location to store error, or %NULL
2031 * Clears any properties that depend on backing resources (kernel devices,
2032 * etc) and removes those resources if @remove_resources is %TRUE.
2034 * Returns: %TRUE on success, %FALSE on error
2037 nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
2039 NMDevicePrivate *priv;
2042 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
2044 if (!nm_device_is_software (self) || !nm_device_is_real (self)) {
2045 g_set_error_literal (error,
2047 NM_DEVICE_ERROR_NOT_SOFTWARE,
2048 "This device is not a software device or is not realized");
2052 priv = NM_DEVICE_GET_PRIVATE (self);
2054 g_return_val_if_fail (priv->iface != NULL, FALSE);
2055 g_return_val_if_fail (priv->real, FALSE);
2057 g_object_freeze_notify (G_OBJECT (self));
2059 ifindex = nm_device_get_ifindex (self);
2061 _LOGD (LOGD_DEVICE, "unrealize (ifindex %d)", ifindex > 0 ? ifindex : 0);
2063 if (remove_resources) {
2065 nm_platform_link_delete (NM_PLATFORM_GET, ifindex);
2068 NM_DEVICE_GET_CLASS (self)->unrealize_notify (self);
2070 if (priv->ifindex > 0) {
2072 _notify (self, PROP_IFINDEX);
2074 priv->ip_ifindex = 0;
2075 if (priv->ip_iface) {
2076 g_clear_pointer (&priv->ip_iface, g_free);
2077 _notify (self, PROP_IP_IFACE);
2079 if (priv->driver_version) {
2080 g_clear_pointer (&priv->driver_version, g_free);
2081 _notify (self, PROP_DRIVER_VERSION);
2083 if (priv->firmware_version) {
2084 g_clear_pointer (&priv->firmware_version, g_free);
2085 _notify (self, PROP_FIRMWARE_VERSION);
2088 g_clear_pointer (&priv->udi, g_free);
2089 _notify (self, PROP_UDI);
2091 if (priv->hw_addr) {
2092 g_clear_pointer (&priv->hw_addr, g_free);
2093 _notify (self, PROP_HW_ADDRESS);
2095 if (priv->physical_port_id) {
2096 g_clear_pointer (&priv->physical_port_id, g_free);
2097 _notify (self, PROP_PHYSICAL_PORT_ID);
2100 g_clear_pointer (&priv->perm_hw_addr, g_free);
2101 g_clear_pointer (&priv->initial_hw_addr, g_free);
2103 priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED;
2104 if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
2105 priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
2106 _notify (self, PROP_CAPABILITIES);
2109 _notify (self, PROP_REAL);
2111 nm_device_set_autoconnect (self, DEFAULT_AUTOCONNECT);
2113 g_object_thaw_notify (G_OBJECT (self));
2115 nm_device_set_unmanaged_flags (self,
2116 NM_UNMANAGED_PLATFORM_INIT,
2119 nm_device_set_unmanaged_flags (self,
2120 NM_UNMANAGED_PARENT |
2121 NM_UNMANAGED_LOOPBACK |
2122 NM_UNMANAGED_USER_UDEV |
2123 NM_UNMANAGED_EXTERNAL_DOWN |
2124 NM_UNMANAGED_IS_SLAVE,
2125 NM_UNMAN_FLAG_OP_FORGET);
2127 nm_device_state_changed (self,
2128 NM_DEVICE_STATE_UNMANAGED,
2130 NM_DEVICE_STATE_REASON_USER_REQUESTED : NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
2132 /* Garbage-collect unneeded unrealized devices. */
2133 nm_device_recheck_available_connections (self);
2139 * nm_device_notify_new_device_added():
2140 * @self: the #NMDevice
2141 * @device: the newly added device
2143 * Called by the manager to notify the device that a new device has
2144 * been found and added.
2147 nm_device_notify_new_device_added (NMDevice *self, NMDevice *device)
2149 NMDeviceClass *klass;
2151 g_return_if_fail (NM_IS_DEVICE (self));
2152 g_return_if_fail (NM_IS_DEVICE (device));
2154 klass = NM_DEVICE_GET_CLASS (self);
2155 if (klass->notify_new_device_added)
2156 klass->notify_new_device_added (self, device);
2160 * nm_device_notify_component_added():
2161 * @self: the #NMDevice
2162 * @component: the component being added by a plugin
2164 * Called by the manager to notify the device that a new component has
2165 * been found. The device implementation should return %TRUE if it
2166 * wishes to claim the component, or %FALSE if it cannot.
2168 * Returns: %TRUE to claim the component, %FALSE if the component cannot be
2172 nm_device_notify_component_added (NMDevice *self, GObject *component)
2174 NMDeviceClass *klass;
2176 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
2177 g_return_val_if_fail (G_IS_OBJECT (component), FALSE);
2179 klass = NM_DEVICE_GET_CLASS (self);
2180 if (klass->component_added)
2181 return klass->component_added (self, component);
2186 * nm_device_owns_iface():
2187 * @self: the #NMDevice
2188 * @iface: an interface name
2190 * Called by the manager to ask if the device or any of its components owns
2191 * @iface. For example, a WWAN implementation would return %TRUE for an
2192 * ethernet interface name that was owned by the WWAN device's modem component,
2193 * because that ethernet interface is controlled by the WWAN device and cannot
2194 * be used independently of the WWAN device.
2196 * Returns: %TRUE if @self or it's components owns the interface name,
2200 nm_device_owns_iface (NMDevice *self, const char *iface)
2202 if (NM_DEVICE_GET_CLASS (self)->owns_iface)
2203 return NM_DEVICE_GET_CLASS (self)->owns_iface (self, iface);
2208 nm_device_new_default_connection (NMDevice *self)
2210 if (NM_DEVICE_GET_CLASS (self)->new_default_connection)
2211 return NM_DEVICE_GET_CLASS (self)->new_default_connection (self);
2216 slave_state_changed (NMDevice *slave,
2217 NMDeviceState slave_new_state,
2218 NMDeviceState slave_old_state,
2219 NMDeviceStateReason reason,
2222 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2223 gboolean release = FALSE;
2225 _LOGD (LOGD_DEVICE, "slave %s state change %d (%s) -> %d (%s)",
2226 nm_device_get_iface (slave),
2228 state_to_string (slave_old_state),
2230 state_to_string (slave_new_state));
2232 /* Don't try to enslave slaves until the master is ready */
2233 if (priv->state < NM_DEVICE_STATE_CONFIG)
2236 if (slave_new_state == NM_DEVICE_STATE_IP_CONFIG)
2237 nm_device_master_enslave_slave (self, slave, nm_device_get_applied_connection (slave));
2238 else if (slave_new_state > NM_DEVICE_STATE_ACTIVATED)
2240 else if ( slave_new_state <= NM_DEVICE_STATE_DISCONNECTED
2241 && slave_old_state > NM_DEVICE_STATE_DISCONNECTED) {
2242 /* Catch failures due to unavailable or unmanaged */
2247 nm_device_master_release_one_slave (self, slave, TRUE, reason);
2248 /* Bridge/bond/team interfaces are left up until manually deactivated */
2249 if (priv->slaves == NULL && priv->state == NM_DEVICE_STATE_ACTIVATED)
2250 _LOGD (LOGD_DEVICE, "last slave removed; remaining activated");
2255 * nm_device_master_add_slave:
2256 * @self: the master device
2257 * @slave: the slave device to enslave
2258 * @configure: pass %TRUE if the slave should be configured by the master, or
2259 * %FALSE if it is already configured outside NetworkManager
2261 * If @self is capable of enslaving other devices (ie it's a bridge, bond, team,
2262 * etc) then this function adds @slave to the slave list for later enslavement.
2265 nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure)
2267 NMDevicePrivate *priv;
2268 NMDevicePrivate *slave_priv;
2271 g_return_if_fail (NM_IS_DEVICE (self));
2272 g_return_if_fail (NM_IS_DEVICE (slave));
2273 g_return_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL);
2275 priv = NM_DEVICE_GET_PRIVATE (self);
2276 slave_priv = NM_DEVICE_GET_PRIVATE (slave);
2278 info = find_slave_info (self, slave);
2280 _LOGt (LOGD_CORE, "master: add one slave %p/%s%s", slave, nm_device_get_iface (slave),
2281 info ? " (already registered)" : "");
2284 g_return_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED);
2287 g_return_if_fail (!slave_priv->master);
2288 g_return_if_fail (!slave_priv->is_enslaved);
2290 info = g_slice_new0 (SlaveInfo);
2291 info->slave = g_object_ref (slave);
2292 info->configure = configure;
2293 info->watch_id = g_signal_connect (slave,
2294 NM_DEVICE_STATE_CHANGED,
2295 G_CALLBACK (slave_state_changed), self);
2296 priv->slaves = g_slist_append (priv->slaves, info);
2297 slave_priv->master = g_object_ref (self);
2301 * _notify (slave, PROP_MASTER);
2303 * because slave_priv->is_enslaved is not true, thus the value
2304 * didn't change yet. */
2306 g_warn_if_fail (!NM_FLAGS_HAS (slave_priv->unmanaged_mask, NM_UNMANAGED_IS_SLAVE));
2307 nm_device_set_unmanaged_by_flags (slave, NM_UNMANAGED_IS_SLAVE, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
2309 g_return_if_fail (slave_priv->master == self);
2311 nm_device_queue_recheck_assume (self);
2312 nm_device_queue_recheck_assume (slave);
2317 * nm_device_master_get_slaves:
2318 * @self: the master device
2320 * Returns: any slaves of which @self is the master. Caller owns returned list.
2323 nm_device_master_get_slaves (NMDevice *self)
2325 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2326 GSList *slaves = NULL, *iter;
2328 for (iter = priv->slaves; iter; iter = g_slist_next (iter))
2329 slaves = g_slist_prepend (slaves, ((SlaveInfo *) iter->data)->slave);
2335 * nm_device_master_get_slave_by_ifindex:
2336 * @self: the master device
2337 * @ifindex: the slave's interface index
2339 * Returns: the slave with the given @ifindex of which @self is the master,
2340 * or %NULL if no device with @ifindex is a slave of @self.
2343 nm_device_master_get_slave_by_ifindex (NMDevice *self, int ifindex)
2347 for (iter = NM_DEVICE_GET_PRIVATE (self)->slaves; iter; iter = g_slist_next (iter)) {
2348 SlaveInfo *info = iter->data;
2350 if (nm_device_get_ip_ifindex (info->slave) == ifindex)
2357 * nm_device_master_check_slave_physical_port:
2358 * @self: the master device
2359 * @slave: a slave device
2360 * @log_domain: domain to log a warning in
2362 * Checks if @self already has a slave with the same #NMDevice:physical-port-id
2363 * as @slave, and logs a warning if so.
2366 nm_device_master_check_slave_physical_port (NMDevice *self, NMDevice *slave,
2367 NMLogDomain log_domain)
2369 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2370 const char *slave_physical_port_id, *existing_physical_port_id;
2374 slave_physical_port_id = nm_device_get_physical_port_id (slave);
2375 if (!slave_physical_port_id)
2378 for (iter = priv->slaves; iter; iter = iter->next) {
2380 if (info->slave == slave)
2383 existing_physical_port_id = nm_device_get_physical_port_id (info->slave);
2384 if (!g_strcmp0 (slave_physical_port_id, existing_physical_port_id)) {
2385 _LOGW (log_domain, "slave %s shares a physical port with existing slave %s",
2386 nm_device_get_ip_iface (slave),
2387 nm_device_get_ip_iface (info->slave));
2388 /* Since this function will get called for every slave, we only have
2389 * to warn about the first match we find; if there are other matches
2390 * later in the list, we will have already warned about them matching
2391 * @existing earlier.
2398 /* release all slaves */
2400 nm_device_master_release_slaves (NMDevice *self)
2402 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2403 NMDeviceStateReason reason;
2404 gboolean configure = TRUE;
2406 /* Don't release the slaves if this connection doesn't belong to NM. */
2407 if (nm_device_uses_generated_assumed_connection (self))
2410 reason = priv->state_reason;
2411 if (priv->state == NM_DEVICE_STATE_FAILED)
2412 reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED;
2414 if (!nm_platform_link_get (NM_PLATFORM_GET, priv->ifindex))
2417 while (priv->slaves) {
2418 SlaveInfo *info = priv->slaves->data;
2420 nm_device_master_release_one_slave (self, info->slave, configure, reason);
2425 * nm_device_is_master:
2428 * Returns: %TRUE if the device can have slaves
2431 nm_device_is_master (NMDevice *self)
2433 return NM_DEVICE_GET_PRIVATE (self)->is_master;
2437 * nm_device_get_master:
2440 * If @self has been enslaved by another device, this returns that
2441 * device. Otherwise it returns %NULL. (In particular, note that if
2442 * @self is in the process of activating as a slave, but has not yet
2443 * been enslaved by its master, this will return %NULL.)
2445 * Returns: (transfer none): @self's master, or %NULL
2448 nm_device_get_master (NMDevice *self)
2450 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2452 if (priv->is_enslaved) {
2453 g_return_val_if_fail (priv->master, NULL);
2454 return priv->master;
2460 * nm_device_slave_notify_enslave:
2461 * @self: the slave device
2462 * @success: whether the enslaving operation succeeded
2464 * Notifies a slave that either it has been enslaved, or else its master tried
2465 * to enslave it and failed.
2468 nm_device_slave_notify_enslave (NMDevice *self, gboolean success)
2470 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2471 NMConnection *connection = nm_device_get_applied_connection (self);
2472 gboolean activating = (priv->state == NM_DEVICE_STATE_IP_CONFIG);
2474 g_return_if_fail (priv->master);
2476 if (!priv->is_enslaved) {
2479 _LOGI (LOGD_DEVICE, "Activation: connection '%s' enslaved, continuing activation",
2480 nm_connection_get_id (connection));
2482 _LOGI (LOGD_DEVICE, "enslaved to %s", nm_device_get_iface (priv->master));
2484 priv->is_enslaved = TRUE;
2485 _notify (self, PROP_MASTER);
2486 _notify (priv->master, PROP_SLAVES);
2487 } else if (activating) {
2488 _LOGW (LOGD_DEVICE, "Activation: connection '%s' could not be enslaved",
2489 nm_connection_get_id (connection));
2494 priv->ip4_state = IP_DONE;
2495 priv->ip6_state = IP_DONE;
2497 nm_device_queue_state (self, NM_DEVICE_STATE_SECONDARIES, NM_DEVICE_STATE_REASON_NONE);
2499 nm_device_queue_state (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN);
2501 nm_device_queue_recheck_assume (self);
2505 * nm_device_slave_notify_release:
2506 * @self: the slave device
2507 * @reason: the reason associated with the state change
2509 * Notifies a slave that it has been released, and why.
2512 nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason)
2514 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2515 NMConnection *connection = nm_device_get_applied_connection (self);
2516 NMDeviceState new_state;
2517 const char *master_status;
2519 g_return_if_fail (priv->master);
2521 if ( priv->state > NM_DEVICE_STATE_DISCONNECTED
2522 && priv->state <= NM_DEVICE_STATE_ACTIVATED) {
2523 if (reason == NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED) {
2524 new_state = NM_DEVICE_STATE_FAILED;
2525 master_status = "failed";
2526 } else if (reason == NM_DEVICE_STATE_REASON_USER_REQUESTED) {
2527 new_state = NM_DEVICE_STATE_DEACTIVATING;
2528 master_status = "deactivated by user request";
2530 new_state = NM_DEVICE_STATE_DISCONNECTED;
2531 master_status = "deactivated";
2534 _LOGD (LOGD_DEVICE, "Activation: connection '%s' master %s",
2535 nm_connection_get_id (connection),
2538 nm_device_queue_state (self, new_state, reason);
2540 _LOGI (LOGD_DEVICE, "released from master device %s", nm_device_get_iface (priv->master));
2542 if (priv->is_enslaved) {
2543 priv->is_enslaved = FALSE;
2544 _notify (self, PROP_MASTER);
2545 _notify (priv->master, PROP_SLAVES);
2550 * nm_device_get_enslaved:
2551 * @self: the #NMDevice
2553 * Returns: %TRUE if the device is enslaved to a master device (eg bridge or
2554 * bond or team), %FALSE if not
2557 nm_device_get_enslaved (NMDevice *self)
2559 return NM_DEVICE_GET_PRIVATE (self)->is_enslaved;
2563 * nm_device_removed:
2564 * @self: the #NMDevice
2566 * Called by the manager when the device was removed. Releases the device from
2567 * the master in case it's enslaved.
2570 nm_device_removed (NMDevice *self)
2572 NMDevicePrivate *priv;
2574 g_return_if_fail (NM_IS_DEVICE (self));
2576 priv = NM_DEVICE_GET_PRIVATE (self);
2578 /* this is called when something externally messes with the slave or during shut-down.
2579 * Release the slave from master, but don't touch the device. */
2580 nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
2585 is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags)
2587 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2589 if (priv->carrier || priv->ignore_carrier)
2592 if (NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER))
2599 * nm_device_is_available:
2600 * @self: the #NMDevice
2601 * @flags: additional flags to influence the check. Flags have the
2602 * meaning to increase the availability of a device.
2604 * Checks if @self would currently be capable of activating a
2605 * connection. In particular, it checks that the device is ready (eg,
2606 * is not missing firmware), that it has carrier (if necessary), and
2607 * that any necessary external software (eg, ModemManager,
2608 * wpa_supplicant) is available.
2610 * @self can only be in a state higher than
2611 * %NM_DEVICE_STATE_UNAVAILABLE when nm_device_is_available() returns
2612 * %TRUE. (But note that it can still be %NM_DEVICE_STATE_UNMANAGED
2613 * when it is available.)
2615 * Returns: %TRUE or %FALSE
2618 nm_device_is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags)
2620 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2622 if (priv->firmware_missing)
2625 return NM_DEVICE_GET_CLASS (self)->is_available (self, flags);
2629 nm_device_get_enabled (NMDevice *self)
2631 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
2633 if (NM_DEVICE_GET_CLASS (self)->get_enabled)
2634 return NM_DEVICE_GET_CLASS (self)->get_enabled (self);
2639 nm_device_set_enabled (NMDevice *self, gboolean enabled)
2641 g_return_if_fail (NM_IS_DEVICE (self));
2643 if (NM_DEVICE_GET_CLASS (self)->set_enabled)
2644 NM_DEVICE_GET_CLASS (self)->set_enabled (self, enabled);
2648 * nm_device_get_autoconnect:
2649 * @self: the #NMDevice
2651 * Returns: %TRUE if the device allows autoconnect connections, or %FALSE if the
2652 * device is explicitly blocking all autoconnect connections. Does not take
2653 * into account transient conditions like companion devices that may wish to
2657 nm_device_get_autoconnect (NMDevice *self)
2659 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
2661 return NM_DEVICE_GET_PRIVATE (self)->autoconnect;
2665 nm_device_set_autoconnect (NMDevice *self, gboolean autoconnect)
2667 NMDevicePrivate *priv;
2669 g_return_if_fail (NM_IS_DEVICE (self));
2671 autoconnect = !!autoconnect;
2673 priv = NM_DEVICE_GET_PRIVATE (self);
2674 if (priv->autoconnect != autoconnect) {
2675 priv->autoconnect = autoconnect;
2676 _notify (self, PROP_AUTOCONNECT);
2681 autoconnect_allowed_accumulator (GSignalInvocationHint *ihint,
2682 GValue *return_accu,
2683 const GValue *handler_return, gpointer data)
2685 if (!g_value_get_boolean (handler_return))
2686 g_value_set_boolean (return_accu, FALSE);
2691 * nm_device_autoconnect_allowed:
2692 * @self: the #NMDevice
2694 * Returns: %TRUE if the device can be auto-connected immediately, taking
2695 * transient conditions into account (like companion devices that may wish to
2696 * block autoconnect for a time).
2699 nm_device_autoconnect_allowed (NMDevice *self)
2701 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2702 GValue instance = G_VALUE_INIT;
2703 GValue retval = G_VALUE_INIT;
2705 if (!priv->autoconnect)
2708 /* Unrealized devices can always autoconnect. */
2709 if (nm_device_is_real (self) && priv->state < NM_DEVICE_STATE_DISCONNECTED)
2712 /* The 'autoconnect-allowed' signal is emitted on a device to allow
2713 * other listeners to block autoconnect on the device if they wish.
2714 * This is mainly used by the OLPC Mesh devices to block autoconnect
2715 * on their companion WiFi device as they share radio resources and
2716 * cannot be connected at the same time.
2719 g_value_init (&instance, G_TYPE_OBJECT);
2720 g_value_set_object (&instance, self);
2722 g_value_init (&retval, G_TYPE_BOOLEAN);
2723 g_value_set_boolean (&retval, TRUE);
2725 /* Use g_signal_emitv() rather than g_signal_emit() to avoid the return
2726 * value being changed if no handlers are connected */
2727 g_signal_emitv (&instance, signals[AUTOCONNECT_ALLOWED], 0, &retval);
2728 g_value_unset (&instance);
2730 return g_value_get_boolean (&retval);
2734 can_auto_connect (NMDevice *self,
2735 NMConnection *connection,
2736 char **specific_object)
2738 NMSettingConnection *s_con;
2740 s_con = nm_connection_get_setting_connection (connection);
2741 if (!nm_setting_connection_get_autoconnect (s_con))
2744 return nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, NULL);
2748 * nm_device_can_auto_connect:
2749 * @self: an #NMDevice
2750 * @connection: a #NMConnection
2751 * @specific_object: (out) (transfer full): on output, the path of an
2752 * object associated with the returned connection, to be passed to
2753 * nm_manager_activate_connection(), or %NULL.
2755 * Checks if @connection can be auto-activated on @self right now.
2756 * This requires, at a minimum, that the connection be compatible with
2757 * @self, and that it have the #NMSettingConnection:autoconnect property
2758 * set, and that the device allow auto connections. Some devices impose
2759 * additional requirements. (Eg, a Wi-Fi connection can only be activated
2760 * if its SSID was seen in the last scan.)
2762 * Returns: %TRUE, if the @connection can be auto-activated.
2765 nm_device_can_auto_connect (NMDevice *self,
2766 NMConnection *connection,
2767 char **specific_object)
2769 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
2770 g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
2771 g_return_val_if_fail (specific_object && !*specific_object, FALSE);
2773 if (nm_device_autoconnect_allowed (self))
2774 return NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object);
2779 device_has_config (NMDevice *self)
2781 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2783 /* Check for IP configuration. */
2784 if (priv->ip4_config && nm_ip4_config_get_num_addresses (priv->ip4_config))
2786 if (priv->ip6_config && nm_ip6_config_get_num_addresses (priv->ip6_config))
2789 /* The existence of a software device is good enough. */
2790 if (nm_device_is_software (self) && nm_device_is_real (self))
2793 /* Slaves are also configured by definition */
2794 if (nm_platform_link_get_master (NM_PLATFORM_GET, priv->ifindex) > 0)
2801 * nm_device_master_update_slave_connection:
2802 * @self: the master #NMDevice
2803 * @slave: the slave #NMDevice
2804 * @connection: the #NMConnection to update with the slave settings
2805 * @GError: (out): error description
2807 * Reads the slave configuration for @slave and updates @connection with those
2808 * properties. This invokes a virtual function on the master device @self.
2810 * Returns: %TRUE if the configuration was read and @connection updated,
2811 * %FALSE on failure.
2814 nm_device_master_update_slave_connection (NMDevice *self,
2816 NMConnection *connection,
2819 NMDeviceClass *klass;
2822 g_return_val_if_fail (self, FALSE);
2823 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
2824 g_return_val_if_fail (slave, FALSE);
2825 g_return_val_if_fail (connection, FALSE);
2826 g_return_val_if_fail (!error || !*error, FALSE);
2827 g_return_val_if_fail (nm_connection_get_setting_connection (connection), FALSE);
2829 g_return_val_if_fail (nm_device_get_iface (self), FALSE);
2831 klass = NM_DEVICE_GET_CLASS (self);
2832 if (klass->master_update_slave_connection) {
2833 success = klass->master_update_slave_connection (self, slave, connection, error);
2835 g_return_val_if_fail (!error || (success && !*error) || *error, success);
2841 NM_DEVICE_ERROR_FAILED,
2842 "master device '%s' cannot update a slave connection for slave device '%s' (master type not supported?)",
2843 nm_device_get_iface (self), nm_device_get_iface (slave));
2848 nm_device_generate_connection (NMDevice *self, NMDevice *master)
2850 NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
2851 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
2852 const char *ifname = nm_device_get_iface (self);
2853 NMConnection *connection;
2857 gs_free char *uuid = NULL;
2858 const char *ip4_method, *ip6_method;
2859 GError *error = NULL;
2861 /* If update_connection() is not implemented, just fail. */
2862 if (!klass->update_connection)
2865 /* Return NULL if device is unconfigured. */
2866 if (!device_has_config (self)) {
2867 _LOGD (LOGD_DEVICE, "device has no existing configuration");
2871 connection = nm_simple_connection_new ();
2872 s_con = nm_setting_connection_new ();
2873 uuid = nm_utils_uuid_generate ();
2875 g_object_set (s_con,
2876 NM_SETTING_CONNECTION_UUID, uuid,
2877 NM_SETTING_CONNECTION_ID, ifname,
2878 NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
2879 NM_SETTING_CONNECTION_INTERFACE_NAME, ifname,
2880 NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL),
2882 if (klass->connection_type)
2883 g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, klass->connection_type, NULL);
2884 nm_connection_add_setting (connection, s_con);
2886 /* If the device is a slave, update various slave settings */
2888 if (!nm_device_master_update_slave_connection (master,
2893 _LOGE (LOGD_DEVICE, "master device '%s' failed to update slave connection: %s",
2894 nm_device_get_iface (master), error->message);
2895 g_error_free (error);
2896 g_object_unref (connection);
2900 /* Only regular and master devices get IP configuration; slaves do not */
2901 s_ip4 = nm_ip4_config_create_setting (priv->ip4_config);
2902 nm_connection_add_setting (connection, s_ip4);
2904 s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
2905 nm_connection_add_setting (connection, s_ip6);
2908 klass->update_connection (self, connection);
2910 /* Check the connection in case of update_connection() bug. */
2911 if (!nm_connection_verify (connection, &error)) {
2912 _LOGE (LOGD_DEVICE, "Generated connection does not verify: %s", error->message);
2913 g_clear_error (&error);
2914 g_object_unref (connection);
2918 /* Ignore the connection if it has no IP configuration,
2919 * no slave configuration, and is not a master interface.
2921 ip4_method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
2922 ip6_method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
2923 if ( g_strcmp0 (ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0
2924 && g_strcmp0 (ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0
2925 && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con))
2927 _LOGD (LOGD_DEVICE, "ignoring generated connection (no IP and not in master-slave relationship)");
2928 g_object_unref (connection);
2932 /* Ignore any IPv6LL-only, not master connections without slaves,
2933 * unless they are in the assume-ipv6ll-only list.
2936 && g_strcmp0 (ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0
2937 && g_strcmp0 (ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0
2938 && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con))
2940 && !nm_config_data_get_assume_ipv6ll_only (NM_CONFIG_GET_DATA, self)) {
2941 _LOGD (LOGD_DEVICE, "ignoring generated connection (IPv6LL-only and not in master-slave relationship)");
2942 g_object_unref (connection);
2950 nm_device_complete_connection (NMDevice *self,
2951 NMConnection *connection,
2952 const char *specific_object,
2953 const GSList *existing_connections,
2956 gboolean success = FALSE;
2958 g_return_val_if_fail (self != NULL, FALSE);
2959 g_return_val_if_fail (connection != NULL, FALSE);
2961 if (!NM_DEVICE_GET_CLASS (self)->complete_connection) {
2962 g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION,
2963 "Device class %s had no complete_connection method",
2964 G_OBJECT_TYPE_NAME (self));
2968 success = NM_DEVICE_GET_CLASS (self)->complete_connection (self,
2971 existing_connections,
2974 success = nm_connection_verify (connection, error);
2980 check_connection_compatible (NMDevice *self, NMConnection *connection)
2982 const char *device_iface = nm_device_get_iface (self);
2983 gs_free char *conn_iface = nm_manager_get_connection_iface (nm_manager_get (),
2987 /* We always need a interface name for virtual devices, but for
2988 * physical ones a connection without interface name is fine for
2991 return !nm_connection_is_virtual (connection);
2993 if (strcmp (conn_iface, device_iface) != 0)
3000 * nm_device_check_connection_compatible:
3001 * @self: an #NMDevice
3002 * @connection: an #NMConnection
3004 * Checks if @connection could potentially be activated on @self.
3005 * This means only that @self has the proper capabilities, and that
3006 * @connection is not locked to some other device. It does not
3007 * necessarily mean that @connection could be activated on @self
3008 * right now. (Eg, it might refer to a Wi-Fi network that is not
3009 * currently available.)
3011 * Returns: #TRUE if @connection could potentially be activated on
3015 nm_device_check_connection_compatible (NMDevice *self, NMConnection *connection)
3017 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
3018 g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
3020 return NM_DEVICE_GET_CLASS (self)->check_connection_compatible (self, connection);
3024 nm_device_check_slave_connection_compatible (NMDevice *self, NMConnection *slave)
3026 NMDevicePrivate *priv;
3027 NMSettingConnection *s_con;
3028 const char *connection_type, *slave_type;
3030 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
3031 g_return_val_if_fail (NM_IS_CONNECTION (slave), FALSE);
3033 priv = NM_DEVICE_GET_PRIVATE (self);
3035 if (!priv->is_master)
3038 /* All masters should have connection type set */
3039 connection_type = NM_DEVICE_GET_CLASS (self)->connection_type;
3040 g_return_val_if_fail (connection_type, FALSE);
3042 s_con = nm_connection_get_setting_connection (slave);
3044 slave_type = nm_setting_connection_get_slave_type (s_con);
3048 return strcmp (connection_type, slave_type) == 0;
3052 * nm_device_can_assume_connections:
3053 * @self: #NMDevice instance
3055 * This is a convenience function to determine whether connection assumption
3056 * is available for this device.
3058 * Returns: %TRUE if the device is capable of assuming connections, %FALSE if not
3061 nm_device_can_assume_connections (NMDevice *self)
3063 return !!NM_DEVICE_GET_CLASS (self)->update_connection
3064 && !NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
3068 * nm_device_can_assume_active_connection:
3069 * @self: #NMDevice instance
3071 * This is a convenience function to determine whether the device's active
3072 * connection can be assumed if NetworkManager restarts. This method returns
3073 * %TRUE if and only if the device can assume connections, and the device has
3074 * an active connection, and that active connection can be assumed.
3076 * Returns: %TRUE if the device's active connection can be assumed, or %FALSE
3077 * if there is no active connection or the active connection cannot be
3081 nm_device_can_assume_active_connection (NMDevice *self)
3083 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3084 NMConnection *connection;
3086 const char *assumable_ip6_methods[] = {
3087 NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
3088 NM_SETTING_IP6_CONFIG_METHOD_AUTO,
3089 NM_SETTING_IP6_CONFIG_METHOD_DHCP,
3090 NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
3091 NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
3094 const char *assumable_ip4_methods[] = {
3095 NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
3096 NM_SETTING_IP6_CONFIG_METHOD_AUTO,
3097 NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
3101 if (!nm_device_can_assume_connections (self))
3104 connection = nm_device_get_applied_connection (self);
3108 /* Can't assume connections that aren't yet configured
3109 * FIXME: what about bridges/bonds waiting for slaves?
3111 if (priv->state < NM_DEVICE_STATE_IP_CONFIG)
3113 if (priv->ip4_state != IP_DONE && priv->ip6_state != IP_DONE)
3116 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
3117 if (!_nm_utils_string_in_list (method, assumable_ip6_methods))
3120 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
3121 if (!_nm_utils_string_in_list (method, assumable_ip4_methods))
3128 nm_device_emit_recheck_assume (gpointer user_data)
3130 NMDevice *self = user_data;
3131 NMDevicePrivate *priv;
3133 g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE);
3135 priv = NM_DEVICE_GET_PRIVATE (self);
3137 priv->recheck_assume_id = 0;
3138 if (!nm_device_get_act_request (self)) {
3139 _LOGD (LOGD_DEVICE, "emit RECHECK_ASSUME signal");
3140 g_signal_emit (self, signals[RECHECK_ASSUME], 0);
3142 return G_SOURCE_REMOVE;
3146 nm_device_queue_recheck_assume (NMDevice *self)
3148 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3150 if ( !priv->recheck_assume_id
3151 && nm_device_can_assume_connections (self))
3152 priv->recheck_assume_id = g_idle_add (nm_device_emit_recheck_assume, self);
3156 recheck_available (gpointer user_data)
3158 NMDevice *self = NM_DEVICE (user_data);
3159 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3160 gboolean now_available = nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
3161 NMDeviceState state = nm_device_get_state (self);
3162 NMDeviceState new_state = NM_DEVICE_STATE_UNKNOWN;
3164 priv->recheck_available.call_id = 0;
3166 if (state == NM_DEVICE_STATE_UNAVAILABLE && now_available) {
3167 new_state = NM_DEVICE_STATE_DISCONNECTED;
3168 nm_device_queue_state (self, new_state, priv->recheck_available.available_reason);
3169 } else if (state >= NM_DEVICE_STATE_DISCONNECTED && !now_available) {
3170 new_state = NM_DEVICE_STATE_UNAVAILABLE;
3171 nm_device_queue_state (self, new_state, priv->recheck_available.unavailable_reason);
3174 if (new_state > NM_DEVICE_STATE_UNKNOWN) {
3175 _LOGD (LOGD_DEVICE, "is %savailable, %s %s",
3176 now_available ? "" : "not ",
3177 new_state == NM_DEVICE_STATE_UNAVAILABLE ? "no change required for" : "will transition to",
3178 state_to_string (new_state == NM_DEVICE_STATE_UNAVAILABLE ? state : new_state));
3180 priv->recheck_available.available_reason = NM_DEVICE_STATE_REASON_NONE;
3181 priv->recheck_available.unavailable_reason = NM_DEVICE_STATE_REASON_NONE;
3184 return G_SOURCE_REMOVE;
3188 nm_device_queue_recheck_available (NMDevice *self,
3189 NMDeviceStateReason available_reason,
3190 NMDeviceStateReason unavailable_reason)
3192 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3194 priv->recheck_available.available_reason = available_reason;
3195 priv->recheck_available.unavailable_reason = unavailable_reason;
3196 if (!priv->recheck_available.call_id)
3197 priv->recheck_available.call_id = g_idle_add (recheck_available, self);
3201 nm_device_emit_recheck_auto_activate (NMDevice *self)
3203 g_signal_emit (self, signals[RECHECK_AUTO_ACTIVATE], 0);
3207 dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer user_data)
3209 NMDevice *self = NM_DEVICE (user_data);
3212 case NM_DNSMASQ_STATUS_DEAD:
3213 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
3220 /*****************************************************************************/
3223 activation_source_handle_cb4 (gpointer user_data)
3225 activation_source_handle_cb (user_data, AF_INET);
3226 return G_SOURCE_REMOVE;
3230 activation_source_handle_cb6 (gpointer user_data)
3232 activation_source_handle_cb (user_data, AF_INET6);
3233 return G_SOURCE_REMOVE;
3236 static ActivationHandleData *
3237 activation_source_get_by_family (NMDevice *self,
3239 GSourceFunc *out_idle_func)
3241 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3243 if (family == AF_INET6) {
3244 NM_SET_OUT (out_idle_func, activation_source_handle_cb6);
3245 return &priv->act_handle6;
3247 NM_SET_OUT (out_idle_func, activation_source_handle_cb4);
3248 g_return_val_if_fail (family == AF_INET, &priv->act_handle4);
3249 return &priv->act_handle4;
3254 activation_source_clear (NMDevice *self, int family)
3256 ActivationHandleData *act_data;
3258 act_data = activation_source_get_by_family (self, family, NULL);
3261 _LOGD (LOGD_DEVICE, "activation-stage: clear %s,%d (id %u)",
3262 _activation_func_to_string (act_data->func), family, act_data->id);
3263 nm_clear_g_source (&act_data->id);
3264 act_data->func = NULL;
3269 activation_source_handle_cb (NMDevice *self, int family)
3271 ActivationHandleData *act_data, a;
3273 g_return_if_fail (NM_IS_DEVICE (self));
3275 act_data = activation_source_get_by_family (self, family, NULL);
3277 g_return_if_fail (act_data->id);
3278 g_return_if_fail (act_data->func);
3282 act_data->func = NULL;
3285 _LOGD (LOGD_DEVICE, "activation-stage: invoke %s,%d (id %u)",
3286 _activation_func_to_string (a.func), family, a.id);
3290 _LOGD (LOGD_DEVICE, "activation-stage: complete %s,%d (id %u)",
3291 _activation_func_to_string (a.func), family, a.id);
3295 activation_source_schedule (NMDevice *self, ActivationHandleFunc func, int family)
3297 ActivationHandleData *act_data;
3298 GSourceFunc source_func;
3301 act_data = activation_source_get_by_family (self, family, &source_func);
3303 if (act_data->id && act_data->func != func) {
3304 /* Don't bother rescheduling the same function that's about to
3305 * run anyway. Fixes issues with crappy wireless drivers sending
3306 * streams of associate events before NM has had a chance to process
3309 _LOGD (LOGD_DEVICE, "activation-stage: already scheduled %s,%d (id %u)",
3310 _activation_func_to_string (func), family, act_data->id);
3314 new_id = g_idle_add (source_func, self);
3317 _LOGW (LOGD_DEVICE, "activation-stage: schedule %s,%d which replaces %s,%d (id %u -> %u)",
3318 _activation_func_to_string (func), family,
3319 _activation_func_to_string (act_data->func), family,
3320 act_data->id, new_id);
3321 nm_clear_g_source (&act_data->id);
3323 _LOGD (LOGD_DEVICE, "activation-stage: schedule %s,%d (id %u)",
3324 _activation_func_to_string (func), family, new_id);
3327 act_data->func = func;
3328 act_data->id = new_id;
3331 /*****************************************************************************/
3334 get_ip_config_may_fail (NMDevice *self, int family)
3336 NMConnection *connection;
3337 NMSettingIPConfig *s_ip = NULL;
3339 g_return_val_if_fail (self != NULL, TRUE);
3341 connection = nm_device_get_applied_connection (self);
3342 g_assert (connection);
3344 /* Fail the connection if the failed IP method is required to complete */
3347 s_ip = nm_connection_get_setting_ip4_config (connection);
3350 s_ip = nm_connection_get_setting_ip6_config (connection);
3353 g_assert_not_reached ();
3356 return nm_setting_ip_config_get_may_fail (s_ip);
3360 master_ready (NMDevice *self,
3361 NMActiveConnection *active)
3363 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3364 NMActiveConnection *master_connection;
3367 g_return_if_fail (priv->state == NM_DEVICE_STATE_PREPARE);
3368 g_return_if_fail (!priv->master_ready_handled);
3370 /* Notify a master device that it has a new slave */
3371 g_return_if_fail (nm_active_connection_get_master_ready (active));
3372 master_connection = nm_active_connection_get_master (active);
3374 priv->master_ready_handled = TRUE;
3375 nm_clear_g_signal_handler (active, &priv->master_ready_id);
3377 master = nm_active_connection_get_device (master_connection);
3379 _LOGD (LOGD_DEVICE, "master connection ready; master device %s",
3380 nm_device_get_iface (master));
3382 if (priv->master && priv->master != master)
3383 nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
3385 /* If the master didn't change, add-slave only rechecks whether to assume a connection. */
3386 nm_device_master_add_slave (master,
3388 nm_active_connection_get_assumed (active) ? FALSE : TRUE);
3392 master_ready_cb (NMActiveConnection *active,
3396 master_ready (self, active);
3397 nm_device_activate_schedule_stage2_device_config (self);
3401 lldp_neighbors_changed (NMLldpListener *lldp_listener, GParamSpec *pspec,
3404 NMDevice *self = NM_DEVICE (user_data);
3406 _notify (self, PROP_LLDP_NEIGHBORS);
3410 lldp_rx_enabled (NMDevice *self)
3412 NMConnection *connection;
3413 NMSettingConnection *s_con;
3414 NMSettingConnectionLldp lldp = NM_SETTING_CONNECTION_LLDP_DEFAULT;
3416 connection = nm_device_get_applied_connection (self);
3417 g_return_val_if_fail (connection, FALSE);
3419 s_con = nm_connection_get_setting_connection (connection);
3420 g_return_val_if_fail (s_con, FALSE);
3422 lldp = nm_setting_connection_get_lldp (s_con);
3423 if (lldp == NM_SETTING_CONNECTION_LLDP_DEFAULT) {
3424 gs_free char *value = NULL;
3426 value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
3429 lldp = _nm_utils_ascii_str_to_int64 (value, 10,
3430 NM_SETTING_CONNECTION_LLDP_DEFAULT,
3431 NM_SETTING_CONNECTION_LLDP_ENABLE_RX,
3432 NM_SETTING_CONNECTION_LLDP_DEFAULT);
3433 if (lldp == NM_SETTING_CONNECTION_LLDP_DEFAULT)
3434 lldp = NM_SETTING_CONNECTION_LLDP_DISABLE;
3436 return lldp == NM_SETTING_CONNECTION_LLDP_ENABLE_RX;
3439 static NMActStageReturn
3440 act_stage1_prepare (NMDevice *self, NMDeviceStateReason *reason)
3442 return NM_ACT_STAGE_RETURN_SUCCESS;
3446 * activate_stage1_device_prepare
3448 * Prepare for device activation
3452 activate_stage1_device_prepare (NMDevice *self)
3454 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3455 NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
3456 NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
3457 NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
3459 priv->ip4_state = priv->ip6_state = IP_NONE;
3461 /* Notify the new ActiveConnection along with the state change */
3462 _notify (self, PROP_ACTIVE_CONNECTION);
3464 nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE);
3466 /* Assumed connections were already set up outside NetworkManager */
3467 if (!nm_active_connection_get_assumed (active)) {
3468 ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, &reason);
3469 if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
3471 } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
3472 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
3475 g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
3478 nm_device_activate_schedule_stage2_device_config (self);
3483 * nm_device_activate_schedule_stage1_device_prepare
3485 * Prepare a device for activation
3489 nm_device_activate_schedule_stage1_device_prepare (NMDevice *self)
3491 NMDevicePrivate *priv;
3493 g_return_if_fail (NM_IS_DEVICE (self));
3495 priv = NM_DEVICE_GET_PRIVATE (self);
3496 g_return_if_fail (priv->act_request);
3498 activation_source_schedule (self, activate_stage1_device_prepare, AF_INET);
3501 static NMActStageReturn
3502 act_stage2_config (NMDevice *self, NMDeviceStateReason *reason)
3505 return NM_ACT_STAGE_RETURN_SUCCESS;
3509 * activate_stage2_device_config
3511 * Determine device parameters and set those on the device, ie
3512 * for wireless devices, set SSID, keys, etc.
3516 activate_stage2_device_config (NMDevice *self)
3518 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3519 NMActStageReturn ret;
3520 NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
3521 gboolean no_firmware = FALSE;
3522 NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
3525 nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE);
3527 /* Assumed connections were already set up outside NetworkManager */
3528 if (!nm_active_connection_get_assumed (active)) {
3529 if (!nm_device_bring_up (self, FALSE, &no_firmware)) {
3531 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_FIRMWARE_MISSING);
3533 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
3537 ret = NM_DEVICE_GET_CLASS (self)->act_stage2_config (self, &reason);
3538 if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
3540 else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
3541 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
3544 g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
3547 /* If we have slaves that aren't yet enslaved, do that now */
3548 for (iter = priv->slaves; iter; iter = g_slist_next (iter)) {
3549 SlaveInfo *info = iter->data;
3550 NMDeviceState slave_state = nm_device_get_state (info->slave);
3552 if (slave_state == NM_DEVICE_STATE_IP_CONFIG)
3553 nm_device_master_enslave_slave (self, info->slave, nm_device_get_applied_connection (info->slave));
3554 else if ( nm_device_uses_generated_assumed_connection (self)
3555 && slave_state <= NM_DEVICE_STATE_DISCONNECTED)
3556 nm_device_queue_recheck_assume (info->slave);
3559 if (lldp_rx_enabled (self)) {
3560 gs_free_error GError *error = NULL;
3564 if (priv->lldp_listener)
3565 nm_lldp_listener_stop (priv->lldp_listener);
3567 priv->lldp_listener = nm_lldp_listener_new ();
3568 g_signal_connect (priv->lldp_listener,
3569 "notify::" NM_LLDP_LISTENER_NEIGHBORS,
3570 G_CALLBACK (lldp_neighbors_changed),
3574 addr = nm_platform_link_get_address (NM_PLATFORM_GET, priv->ifindex, &addr_length);
3576 if (nm_lldp_listener_start (priv->lldp_listener, nm_device_get_ifindex (self), &error))
3577 _LOGD (LOGD_DEVICE, "LLDP listener %p started", priv->lldp_listener);
3579 _LOGD (LOGD_DEVICE, "LLDP listener %p could not be started: %s",
3580 priv->lldp_listener, error->message);
3584 nm_device_activate_schedule_stage3_ip_config_start (self);
3589 * nm_device_activate_schedule_stage2_device_config
3591 * Schedule setup of the hardware device
3595 nm_device_activate_schedule_stage2_device_config (NMDevice *self)
3597 NMDevicePrivate *priv;
3599 g_return_if_fail (NM_IS_DEVICE (self));
3601 priv = NM_DEVICE_GET_PRIVATE (self);
3602 g_return_if_fail (priv->act_request);
3604 if (!priv->master_ready_handled) {
3605 NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
3607 if (!nm_active_connection_get_master (active)) {
3608 g_warn_if_fail (!priv->master_ready_id);
3609 priv->master_ready_handled = TRUE;
3611 /* If the master connection is ready for slaves, attach ourselves */
3612 if (nm_active_connection_get_master_ready (active))
3613 master_ready (self, active);
3615 _LOGD (LOGD_DEVICE, "waiting for master connection to become ready");
3617 if (priv->master_ready_id == 0) {
3618 priv->master_ready_id = g_signal_connect (active,
3619 "notify::" NM_ACTIVE_CONNECTION_INT_MASTER_READY,
3620 (GCallback) master_ready_cb,
3629 activation_source_schedule (self, activate_stage2_device_config, AF_INET);
3635 * Progress the device to appropriate state if both IPv4 and IPv6 failed
3638 check_ip_failed (NMDevice *self, gboolean may_fail)
3640 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3641 NMDeviceState state;
3643 if ( priv->ip4_state != IP_FAIL
3644 || priv->ip6_state != IP_FAIL)
3647 if (nm_device_uses_assumed_connection (self)) {
3648 /* We have assumed configuration, but couldn't
3649 * redo it. No problem, move to check state. */
3650 priv->ip4_state = priv->ip6_state = IP_DONE;
3651 state = NM_DEVICE_STATE_IP_CHECK;
3652 } else if ( may_fail
3653 && get_ip_config_may_fail (self, AF_INET)
3654 && get_ip_config_may_fail (self, AF_INET6)) {
3655 /* Couldn't start either IPv6 and IPv4 autoconfiguration,
3656 * but both are allowed to fail. */
3657 state = NM_DEVICE_STATE_SECONDARIES;
3659 /* Autoconfiguration attempted without success. */
3660 state = NM_DEVICE_STATE_FAILED;
3663 nm_device_state_changed (self,
3665 NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
3671 * Progress the device to ip connectivity check state if IPv4 or IPv6 succeeded
3674 check_ip_done (NMDevice *self)
3676 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3678 if (nm_device_get_state (self) != NM_DEVICE_STATE_IP_CONFIG)
3681 if (priv->ip4_state != IP_DONE && !get_ip_config_may_fail (self, AF_INET))
3684 if (priv->ip6_state != IP_DONE && !get_ip_config_may_fail (self, AF_INET6))
3687 nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
3690 /*********************************************/
3691 /* IPv4 DAD stuff */
3694 get_ipv4_dad_timeout (NMDevice *self)
3696 NMConnection *connection;
3697 NMSettingIPConfig *s_ip4 = NULL;
3698 gs_free char *value = NULL;
3701 connection = nm_device_get_applied_connection (self);
3703 s_ip4 = nm_connection_get_setting_ip4_config (connection);
3706 ret = nm_setting_ip_config_get_dad_timeout (s_ip4);
3709 value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
3710 "ipv4.dad-timeout", self);
3711 ret = _nm_utils_ascii_str_to_int64 (value, 10, -1,
3712 NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX,
3714 ret = ret < 0 ? 0 : ret;
3722 arping_data_destroy (gpointer ptr, GClosure *closure)
3724 ArpingData *data = ptr;
3728 for (i = 0; data->configs && data->configs[i]; i++)
3729 g_object_unref (data->configs[i]);
3730 g_free (data->configs);
3731 g_slice_free (ArpingData, data);
3736 ipv4_manual_method_apply (NMDevice *self, NMIP4Config **configs, gboolean success)
3741 empty = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
3742 nm_device_activate_schedule_ip4_config_result (self, empty);
3743 g_object_unref (empty);
3745 nm_device_queue_state (self, NM_DEVICE_STATE_FAILED,
3746 NM_DEVICE_STATE_REASON_CONFIG_FAILED);
3751 arping_manager_probe_terminated (NMArpingManager *arping_manager, ArpingData *data)
3754 NMDevicePrivate *priv;
3755 const NMPlatformIP4Address *address;
3756 gboolean result, success = TRUE;
3760 self = data->device;
3761 priv = NM_DEVICE_GET_PRIVATE (self);
3763 for (i = 0; data->configs && data->configs[i]; i++) {
3764 for (j = 0; j < nm_ip4_config_get_num_addresses (data->configs[i]); j++) {
3765 address = nm_ip4_config_get_address (data->configs[i], j);
3766 result = nm_arping_manager_check_address (arping_manager, address->address);
3769 _NMLOG (result ? LOGL_DEBUG : LOGL_WARN,
3771 "IPv4 DAD result: address %s is %s",
3772 nm_utils_inet4_ntop (address->address, NULL),
3773 result ? "unique" : "duplicate");
3777 data->callback (self, data->configs, success);
3779 priv->arping.dad_list = g_slist_remove (priv->arping.dad_list, arping_manager);
3780 nm_arping_manager_destroy (arping_manager);
3785 * @self: device instance
3786 * @configs: NULL-terminated array of IPv4 configurations
3787 * @cb: callback function
3789 * Start IPv4 DAD on device @self, check addresses in @configs and call @cb
3790 * when the procedure ends. @cb will be called in any case, even if DAD can't
3791 * be started. @configs will be unreferenced after @cb has been called.
3794 ipv4_dad_start (NMDevice *self, NMIP4Config **configs, ArpingCallback cb)
3796 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3797 NMArpingManager *arping_manager;
3798 const NMPlatformIP4Address *address;
3801 gboolean ret, addr_found;
3802 const guint8 *hw_addr;
3803 size_t hw_addr_len = 0;
3804 GError *error = NULL;
3807 g_return_if_fail (NM_IS_DEVICE (self));
3808 g_return_if_fail (configs);
3809 g_return_if_fail (cb);
3811 for (i = 0, addr_found = FALSE; configs[i]; i++) {
3812 if (nm_ip4_config_get_num_addresses (configs[i]) > 0) {
3818 timeout = get_ipv4_dad_timeout (self);
3819 hw_addr = nm_platform_link_get_address (NM_PLATFORM_GET,
3820 nm_device_get_ip_ifindex (self),
3827 || nm_device_uses_assumed_connection (self)) {
3829 /* DAD not needed, signal success */
3830 cb (self, configs, TRUE);
3832 for (i = 0; configs[i]; i++)
3833 g_object_unref (configs[i]);
3839 /* don't take additional references of @arping_manager that outlive @self.
3840 * Otherwise, the callback can be invoked on a dangling pointer as we don't
3841 * disconnect the handler. */
3842 arping_manager = nm_arping_manager_new (nm_device_get_ip_ifindex (self));
3843 priv->arping.dad_list = g_slist_append (priv->arping.dad_list, arping_manager);
3845 data = g_slice_new0 (ArpingData);
3846 data->configs = configs;
3847 data->callback = cb;
3848 data->device = self;
3850 for (i = 0; configs[i]; i++) {
3851 for (j = 0; j < nm_ip4_config_get_num_addresses (configs[i]); j++) {
3852 address = nm_ip4_config_get_address (configs[i], j);
3853 nm_arping_manager_add_address (arping_manager, address->address);
3857 g_signal_connect_data (arping_manager, NM_ARPING_MANAGER_PROBE_TERMINATED,
3858 G_CALLBACK (arping_manager_probe_terminated), data,
3859 arping_data_destroy, 0);
3861 ret = nm_arping_manager_start_probe (arping_manager, timeout, &error);
3864 _LOGW (LOGD_DEVICE, "arping probe failed: %s", error->message);
3866 /* DAD could not be started, signal success */
3867 cb (self, configs, TRUE);
3869 priv->arping.dad_list = g_slist_remove (priv->arping.dad_list, arping_manager);
3870 nm_arping_manager_destroy (arping_manager);
3874 /*********************************************/
3878 ipv4ll_cleanup (NMDevice *self)
3880 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3883 sd_ipv4ll_set_callback (priv->ipv4ll, NULL, NULL);
3884 sd_ipv4ll_stop (priv->ipv4ll);
3885 priv->ipv4ll = sd_ipv4ll_unref (priv->ipv4ll);
3888 nm_clear_g_source (&priv->ipv4ll_timeout);
3891 static NMIP4Config *
3892 ipv4ll_get_ip4_config (NMDevice *self, guint32 lla)
3894 NMIP4Config *config = NULL;
3895 NMPlatformIP4Address address;
3896 NMPlatformIP4Route route;
3898 config = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
3901 memset (&address, 0, sizeof (address));
3902 nm_platform_ip4_address_set_addr (&address, lla, 16);
3903 address.source = NM_IP_CONFIG_SOURCE_IP4LL;
3904 nm_ip4_config_add_address (config, &address);
3906 /* Add a multicast route for link-local connections: destination= 224.0.0.0, netmask=240.0.0.0 */
3907 memset (&route, 0, sizeof (route));
3908 route.network = htonl (0xE0000000L);
3910 route.source = NM_IP_CONFIG_SOURCE_IP4LL;
3911 route.metric = nm_device_get_ip4_route_metric (self);
3912 nm_ip4_config_add_route (config, &route);
3917 #define IPV4LL_NETWORK (htonl (0xA9FE0000L))
3918 #define IPV4LL_NETMASK (htonl (0xFFFF0000L))
3921 nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data)
3923 NMDevice *self = data;
3924 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3925 NMConnection *connection = NULL;
3927 struct in_addr address;
3928 NMIP4Config *config;
3931 if (priv->act_request == NULL)
3934 connection = nm_act_request_get_applied_connection (priv->act_request);
3935 g_assert (connection);
3937 /* Ignore if the connection isn't an AutoIP connection */
3938 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
3939 if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) != 0)
3943 case SD_IPV4LL_EVENT_BIND:
3944 r = sd_ipv4ll_get_address (ll, &address);
3946 _LOGE (LOGD_AUTOIP4, "invalid IPv4 link-local address received, error %d.", r);
3947 priv->ip4_state = IP_FAIL;
3948 check_ip_failed (self, FALSE);
3952 if ((address.s_addr & IPV4LL_NETMASK) != IPV4LL_NETWORK) {
3953 _LOGE (LOGD_AUTOIP4, "invalid address %08x received (not link-local).", address.s_addr);
3954 priv->ip4_state = IP_FAIL;
3955 check_ip_failed (self, FALSE);
3959 config = ipv4ll_get_ip4_config (self, address.s_addr);
3960 if (config == NULL) {
3961 _LOGE (LOGD_AUTOIP4, "failed to get IPv4LL config");
3962 priv->ip4_state = IP_FAIL;
3963 check_ip_failed (self, FALSE);
3967 if (priv->ip4_state == IP_CONF) {
3968 nm_clear_g_source (&priv->ipv4ll_timeout);
3969 nm_device_activate_schedule_ip4_config_result (self, config);
3970 } else if (priv->ip4_state == IP_DONE) {
3971 if (!ip4_config_merge_and_apply (self, config, TRUE, NULL)) {
3972 _LOGE (LOGD_AUTOIP4, "failed to update IP4 config for autoip change.");
3973 priv->ip4_state = IP_FAIL;
3974 check_ip_failed (self, FALSE);
3977 g_assert_not_reached ();
3979 g_object_unref (config);
3982 _LOGW (LOGD_AUTOIP4, "IPv4LL address no longer valid after event %d.", event);
3983 priv->ip4_state = IP_FAIL;
3984 check_ip_failed (self, FALSE);
3989 ipv4ll_timeout_cb (gpointer user_data)
3991 NMDevice *self = NM_DEVICE (user_data);
3992 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
3994 if (priv->ipv4ll_timeout) {
3995 _LOGI (LOGD_AUTOIP4, "IPv4LL configuration timed out.");
3996 priv->ipv4ll_timeout = 0;
3997 ipv4ll_cleanup (self);
3999 if (priv->ip4_state == IP_CONF)
4000 nm_device_activate_schedule_ip4_config_timeout (self);
4006 static NMActStageReturn
4007 ipv4ll_start (NMDevice *self, NMDeviceStateReason *reason)
4009 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4010 const struct ether_addr *addr;
4014 ipv4ll_cleanup (self);
4016 r = sd_ipv4ll_new (&priv->ipv4ll);
4018 _LOGE (LOGD_AUTOIP4, "IPv4LL: new() failed with error %d", r);
4022 r = sd_ipv4ll_attach_event (priv->ipv4ll, NULL, 0);
4024 _LOGE (LOGD_AUTOIP4, "IPv4LL: attach_event() failed with error %d", r);
4028 ifindex = nm_device_get_ip_ifindex (self);
4029 addr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &addr_len);
4030 if (!addr || addr_len != ETH_ALEN) {
4031 _LOGE (LOGD_AUTOIP4, "IPv4LL: can't retrieve hardware address");
4035 r = sd_ipv4ll_set_mac (priv->ipv4ll, addr);
4037 _LOGE (LOGD_AUTOIP4, "IPv4LL: set_mac() failed with error %d", r);
4041 r = sd_ipv4ll_set_index (priv->ipv4ll, ifindex);
4043 _LOGE (LOGD_AUTOIP4, "IPv4LL: set_index() failed with error %d", r);
4047 r = sd_ipv4ll_set_callback (priv->ipv4ll, nm_device_handle_ipv4ll_event, self);
4049 _LOGE (LOGD_AUTOIP4, "IPv4LL: set_callback() failed with error %d", r);
4053 r = sd_ipv4ll_start (priv->ipv4ll);
4055 _LOGE (LOGD_AUTOIP4, "IPv4LL: start() failed with error %d", r);
4059 _LOGI (LOGD_DEVICE | LOGD_AUTOIP4, "IPv4LL: started");
4061 /* Start a timeout to bound the address attempt */
4062 priv->ipv4ll_timeout = g_timeout_add_seconds (20, ipv4ll_timeout_cb, self);
4064 return NM_ACT_STAGE_RETURN_POSTPONE;
4066 *reason = NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED;
4067 return NM_ACT_STAGE_RETURN_FAILURE;
4070 /*********************************************/
4073 _device_get_default_route_from_platform (NMDevice *self, int addr_family, NMPlatformIPRoute *out_route)
4075 gboolean success = FALSE;
4076 int ifindex = nm_device_get_ip_ifindex (self);
4079 if (addr_family == AF_INET)
4080 routes = nm_platform_ip4_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT);
4082 routes = nm_platform_ip6_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT);
4085 guint route_metric = G_MAXUINT32, m;
4086 const NMPlatformIPRoute *route = NULL, *r;
4089 /* if there are several default routes, find the one with the best metric */
4090 for (i = 0; i < routes->len; i++) {
4091 if (addr_family == AF_INET) {
4092 r = (const NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP4Route, i);
4095 r = (const NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP6Route, i);
4096 m = nm_utils_ip6_route_metric_normalize (r->metric);
4098 if (!route || m < route_metric) {
4105 if (addr_family == AF_INET)
4106 *((NMPlatformIP4Route *) out_route) = *((NMPlatformIP4Route *) route);
4108 *((NMPlatformIP6Route *) out_route) = *((NMPlatformIP6Route *) route);
4111 g_array_free (routes, TRUE);
4116 /*********************************************/
4119 ensure_con_ip4_config (NMDevice *self)
4121 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4122 int ip_ifindex = nm_device_get_ip_ifindex (self);
4123 NMConnection *connection;
4125 if (priv->con_ip4_config)
4128 connection = nm_device_get_applied_connection (self);
4132 priv->con_ip4_config = nm_ip4_config_new (ip_ifindex);
4133 nm_ip4_config_merge_setting (priv->con_ip4_config,
4134 nm_connection_get_setting_ip4_config (connection),
4135 nm_device_get_ip4_route_metric (self));
4137 if (nm_device_uses_assumed_connection (self)) {
4138 /* For assumed connections ignore all addresses and routes. */
4139 nm_ip4_config_reset_addresses (priv->con_ip4_config);
4140 nm_ip4_config_reset_routes (priv->con_ip4_config);
4145 ensure_con_ip6_config (NMDevice *self)
4147 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4148 int ip_ifindex = nm_device_get_ip_ifindex (self);
4149 NMConnection *connection;
4151 if (priv->con_ip6_config)
4154 connection = nm_device_get_applied_connection (self);
4158 priv->con_ip6_config = nm_ip6_config_new (ip_ifindex);
4159 nm_ip6_config_merge_setting (priv->con_ip6_config,
4160 nm_connection_get_setting_ip6_config (connection),
4161 nm_device_get_ip6_route_metric (self));
4163 if (nm_device_uses_assumed_connection (self)) {
4164 /* For assumed connections ignore all addresses and routes. */
4165 nm_ip6_config_reset_addresses (priv->con_ip6_config);
4166 nm_ip6_config_reset_routes (priv->con_ip6_config);
4170 /*********************************************/
4174 dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release)
4176 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4178 nm_clear_g_source (&priv->dhcp4_restart_id);
4180 if (priv->dhcp4_client) {
4181 /* Stop any ongoing DHCP transaction on this device */
4182 nm_clear_g_signal_handler (priv->dhcp4_client, &priv->dhcp4_state_sigid);
4184 nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
4186 if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE
4187 || cleanup_type == CLEANUP_TYPE_REMOVED)
4188 nm_dhcp_client_stop (priv->dhcp4_client, release);
4190 g_clear_object (&priv->dhcp4_client);
4193 if (priv->dhcp4_config) {
4194 nm_exported_object_clear_and_unexport (&priv->dhcp4_config);
4195 _notify (self, PROP_DHCP4_CONFIG);
4200 _ip4_config_merge_default (gpointer value, gpointer user_data)
4202 NMIP4Config *src = (NMIP4Config *) value;
4203 NMIP4Config *dst = (NMIP4Config *) user_data;
4205 nm_ip4_config_merge (dst, src, NM_IP_CONFIG_MERGE_DEFAULT);
4209 ip4_config_merge_and_apply (NMDevice *self,
4210 NMIP4Config *config,
4212 NMDeviceStateReason *out_reason)
4214 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4215 NMConnection *connection;
4217 NMIP4Config *composite;
4218 gboolean has_direct_route;
4219 const guint32 default_route_metric = nm_device_get_ip4_route_metric (self);
4221 gboolean connection_has_default_route, connection_is_never_default;
4222 gboolean routes_full_sync;
4223 gboolean ignore_auto_routes = FALSE;
4224 gboolean ignore_auto_dns = FALSE;
4226 /* Merge all the configs into the composite config */
4228 g_clear_object (&priv->dev_ip4_config);
4229 priv->dev_ip4_config = g_object_ref (config);
4232 /* Apply ignore-auto-routes and ignore-auto-dns settings */
4233 connection = nm_device_get_applied_connection (self);
4235 NMSettingIPConfig *s_ip4 = nm_connection_get_setting_ip4_config (connection);
4238 ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip4);
4239 ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip4);
4243 composite = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
4246 ensure_con_ip4_config (self);
4248 if (priv->dev_ip4_config) {
4249 nm_ip4_config_merge (composite, priv->dev_ip4_config,
4250 (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
4251 | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
4254 g_slist_foreach (priv->vpn4_configs, _ip4_config_merge_default, composite);
4256 if (priv->ext_ip4_config)
4257 nm_ip4_config_merge (composite, priv->ext_ip4_config, NM_IP_CONFIG_MERGE_DEFAULT);
4259 /* Merge WWAN config *last* to ensure modem-given settings overwrite
4260 * any external stuff set by pppd or other scripts.
4262 if (priv->wwan_ip4_config) {
4263 nm_ip4_config_merge (composite, priv->wwan_ip4_config,
4264 (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
4265 | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
4268 /* Merge user overrides into the composite config. For assumed connections,
4269 * con_ip4_config is empty. */
4270 if (priv->con_ip4_config)
4271 nm_ip4_config_merge (composite, priv->con_ip4_config, NM_IP_CONFIG_MERGE_DEFAULT);
4273 /* Add the default route.
4275 * We keep track of the default route of a device in a private field.
4276 * NMDevice needs to know the default route at this point, because the gateway
4277 * might require a direct route (see below).
4279 * But also, we don't want to add the default route to priv->ip4_config,
4280 * because the default route from the setting might not be the same that
4281 * NMDefaultRouteManager eventually configures (because the it might
4282 * tweak the effective metric).
4285 /* unless we come to a different conclusion below, we have no default route and
4286 * the route is assumed. */
4287 priv->default_route.v4_has = FALSE;
4288 priv->default_route.v4_is_assumed = TRUE;
4291 /* during a non-commit event, we always pickup whatever is configured. */
4292 goto END_ADD_DEFAULT_ROUTE;
4295 if (nm_device_uses_generated_assumed_connection (self)) {
4296 /* a generate-assumed-connection always detects the default route from platform */
4297 goto END_ADD_DEFAULT_ROUTE;
4300 /* At this point, we treat assumed and non-assumed connections alike.
4301 * For assumed connections we do that because we still manage RA and DHCP
4302 * leases for them, so we must extend/update the default route on commits.
4305 connection_has_default_route
4306 = nm_default_route_manager_ip4_connection_has_default_route (nm_default_route_manager_get (),
4307 connection, &connection_is_never_default);
4309 if ( !priv->v4_commit_first_time
4310 && connection_is_never_default) {
4311 /* If the connection is explicitly configured as never-default, we enforce the (absence of the)
4312 * default-route only once. That allows the user to configure a connection as never-default,
4313 * but he can add default routes externally (via a dispatcher script) and NM will not interfere. */
4314 goto END_ADD_DEFAULT_ROUTE;
4317 /* we are about to commit (for a non-assumed connection). Enforce whatever we have
4319 priv->default_route.v4_is_assumed = FALSE;
4321 if (!connection_has_default_route)
4322 goto END_ADD_DEFAULT_ROUTE;
4324 if (!nm_ip4_config_get_num_addresses (composite)) {
4325 /* without addresses we can have no default route. */
4326 goto END_ADD_DEFAULT_ROUTE;
4329 gateway = nm_ip4_config_get_gateway (composite);
4330 if ( !nm_ip4_config_has_gateway (composite)
4331 && nm_device_get_device_type (self) != NM_DEVICE_TYPE_MODEM)
4332 goto END_ADD_DEFAULT_ROUTE;
4334 has_direct_route = ( gateway == 0
4335 || nm_ip4_config_destination_is_direct (composite, gateway, 32)
4336 || nm_ip4_config_get_direct_route_for_host (composite, gateway));
4338 priv->default_route.v4_has = TRUE;
4339 memset (&priv->default_route.v4, 0, sizeof (priv->default_route.v4));
4340 priv->default_route.v4.source = NM_IP_CONFIG_SOURCE_USER;
4341 priv->default_route.v4.gateway = gateway;
4342 priv->default_route.v4.metric = default_route_metric;
4343 priv->default_route.v4.mss = nm_ip4_config_get_mss (composite);
4345 if (!has_direct_route) {
4346 NMPlatformIP4Route r = priv->default_route.v4;
4348 /* add a direct route to the gateway */
4349 r.network = gateway;
4352 nm_ip4_config_add_route (composite, &r);
4355 END_ADD_DEFAULT_ROUTE:
4357 if (priv->default_route.v4_is_assumed) {
4358 /* If above does not explicitly assign a default route, we always pick up the
4359 * default route based on what is currently configured.
4360 * That means that even managed connections with never-default, can
4361 * get a default route (if configured externally).
4363 priv->default_route.v4_has = _device_get_default_route_from_platform (self, AF_INET, (NMPlatformIPRoute *) &priv->default_route.v4);
4366 nm_ip4_config_addresses_sort (composite);
4368 /* Allow setting MTU etc */
4370 if (NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit)
4371 NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, composite);
4374 routes_full_sync = commit
4375 && priv->v4_commit_first_time
4376 && !nm_device_uses_assumed_connection (self);
4378 success = nm_device_set_ip4_config (self, composite, default_route_metric, commit, routes_full_sync, out_reason);
4379 g_object_unref (composite);
4382 priv->v4_commit_first_time = FALSE;
4387 dhcp4_lease_change (NMDevice *self, NMIP4Config *config)
4389 NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
4391 g_return_if_fail (config != NULL);
4393 if (!ip4_config_merge_and_apply (self, config, TRUE, &reason)) {
4394 _LOGW (LOGD_DHCP4, "failed to update IPv4 config for DHCP change.");
4395 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
4397 /* Notify dispatcher scripts of new DHCP4 config */
4398 nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE,
4399 nm_device_get_settings_connection (self),
4400 nm_device_get_applied_connection (self),
4409 dhcp4_restart_cb (gpointer user_data)
4411 NMDevice *self = user_data;
4412 NMDevicePrivate *priv;
4413 NMDeviceStateReason reason;
4414 NMConnection *connection;
4416 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
4418 priv = NM_DEVICE_GET_PRIVATE (self);
4419 priv->dhcp4_restart_id = 0;
4420 connection = nm_device_get_applied_connection (self);
4422 if (dhcp4_start (self, connection, &reason) == NM_ACT_STAGE_RETURN_FAILURE)
4423 priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self);
4429 dhcp4_fail (NMDevice *self, gboolean timeout)
4431 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4433 dhcp4_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE);
4435 /* Don't fail if there are static addresses configured on
4436 * the device, instead retry after some time.
4438 if ( priv->ip4_state == IP_DONE
4439 && priv->con_ip4_config
4440 && nm_ip4_config_get_num_addresses (priv->con_ip4_config) > 0) {
4441 _LOGI (LOGD_DHCP4, "Scheduling DHCPv4 restart because device has IP addresses");
4442 priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self);
4446 /* Instead of letting an assumed connection fail (which means that the
4447 * device will transition to the ACTIVATED state without IP configuration),
4450 if (nm_device_uses_assumed_connection (self)) {
4451 _LOGI (LOGD_DHCP4, "Scheduling DHCPv4 restart because the connection is assumed");
4452 priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self);
4456 if (timeout || (priv->ip4_state == IP_CONF))
4457 nm_device_activate_schedule_ip4_config_timeout (self);
4458 else if (priv->ip4_state == IP_DONE)
4459 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
4461 g_warn_if_reached ();
4465 dhcp4_dad_cb (NMDevice *self, NMIP4Config **configs, gboolean success)
4468 nm_device_activate_schedule_ip4_config_result (self, configs[1]);
4470 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED,
4471 NM_DEVICE_STATE_REASON_CONFIG_FAILED);
4476 dhcp4_state_changed (NMDhcpClient *client,
4478 NMIP4Config *ip4_config,
4479 GHashTable *options,
4480 const char *event_id,
4483 NMDevice *self = NM_DEVICE (user_data);
4484 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4485 NMIP4Config *manual, **configs;
4486 NMConnection *connection;
4488 g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == FALSE);
4489 g_return_if_fail (!ip4_config || NM_IS_IP4_CONFIG (ip4_config));
4491 _LOGD (LOGD_DHCP4, "new DHCPv4 client state %d", state);
4494 case NM_DHCP_STATE_BOUND:
4496 _LOGW (LOGD_DHCP4, "failed to get IPv4 config in response to DHCP event.");
4497 nm_device_state_changed (self,
4498 NM_DEVICE_STATE_FAILED,
4499 NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
4503 nm_dhcp4_config_set_options (priv->dhcp4_config, options);
4504 _notify (self, PROP_DHCP4_CONFIG);
4506 if (priv->ip4_state == IP_CONF) {
4507 connection = nm_device_get_applied_connection (self);
4508 g_assert (connection);
4510 manual = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
4511 nm_ip4_config_merge_setting (manual,
4512 nm_connection_get_setting_ip4_config (connection),
4513 nm_device_get_ip4_route_metric (self));
4515 configs = g_new0 (NMIP4Config *, 3);
4516 configs[0] = manual;
4517 configs[1] = g_object_ref (ip4_config);
4519 ipv4_dad_start (self, configs, dhcp4_dad_cb);
4520 } else if (priv->ip4_state == IP_DONE) {
4521 dhcp4_lease_change (self, ip4_config);
4522 nm_device_update_metered (self);
4525 case NM_DHCP_STATE_TIMEOUT:
4526 dhcp4_fail (self, TRUE);
4528 case NM_DHCP_STATE_EXPIRE:
4529 /* Ignore expiry before we even have a lease (NAK, old lease, etc) */
4530 if (priv->ip4_state == IP_CONF)
4533 case NM_DHCP_STATE_DONE:
4534 case NM_DHCP_STATE_FAIL:
4535 dhcp4_fail (self, FALSE);
4543 dhcp4_get_timeout (NMDevice *self, NMSettingIP4Config *s_ip4)
4545 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4546 gs_free char *value = NULL;
4549 timeout = nm_setting_ip_config_get_dhcp_timeout (NM_SETTING_IP_CONFIG (s_ip4));
4553 value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
4554 "ipv4.dhcp-timeout",
4556 timeout = _nm_utils_ascii_str_to_int64 (value, 10,
4561 return priv->dhcp_timeout;
4564 static NMActStageReturn
4565 dhcp4_start (NMDevice *self,
4566 NMConnection *connection,
4567 NMDeviceStateReason *reason)
4569 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4570 NMSettingIPConfig *s_ip4;
4571 const guint8 *hw_addr;
4572 size_t hw_addr_len = 0;
4573 GByteArray *tmp = NULL;
4575 s_ip4 = nm_connection_get_setting_ip4_config (connection);
4577 /* Clear old exported DHCP options */
4578 nm_exported_object_clear_and_unexport (&priv->dhcp4_config);
4579 priv->dhcp4_config = nm_dhcp4_config_new ();
4581 hw_addr = nm_platform_link_get_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), &hw_addr_len);
4583 tmp = g_byte_array_sized_new (hw_addr_len);
4584 g_byte_array_append (tmp, hw_addr, hw_addr_len);
4587 /* Begin DHCP on the interface */
4588 g_warn_if_fail (priv->dhcp4_client == NULL);
4589 priv->dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (),
4590 nm_device_get_ip_iface (self),
4591 nm_device_get_ip_ifindex (self),
4593 nm_connection_get_uuid (connection),
4594 nm_device_get_ip4_route_metric (self),
4595 nm_setting_ip_config_get_dhcp_send_hostname (s_ip4),
4596 nm_setting_ip_config_get_dhcp_hostname (s_ip4),
4597 nm_setting_ip4_config_get_dhcp_fqdn (NM_SETTING_IP4_CONFIG (s_ip4)),
4598 nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4)),
4599 dhcp4_get_timeout (self, NM_SETTING_IP4_CONFIG (s_ip4)),
4600 priv->dhcp_anycast_address,
4604 g_byte_array_free (tmp, TRUE);
4606 if (!priv->dhcp4_client) {
4607 *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED;
4608 return NM_ACT_STAGE_RETURN_FAILURE;
4611 priv->dhcp4_state_sigid = g_signal_connect (priv->dhcp4_client,
4612 NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
4613 G_CALLBACK (dhcp4_state_changed),
4616 nm_device_add_pending_action (self, PENDING_ACTION_DHCP4, TRUE);
4618 /* DHCP devices will be notified by the DHCP manager when stuff happens */
4619 return NM_ACT_STAGE_RETURN_POSTPONE;
4623 nm_device_dhcp4_renew (NMDevice *self, gboolean release)
4625 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4626 NMActStageReturn ret;
4627 NMDeviceStateReason reason;
4628 NMConnection *connection;
4630 g_return_val_if_fail (priv->dhcp4_client != NULL, FALSE);
4632 _LOGI (LOGD_DHCP4, "DHCPv4 lease renewal requested");
4634 /* Terminate old DHCP instance and release the old lease */
4635 dhcp4_cleanup (self, CLEANUP_TYPE_DECONFIGURE, release);
4637 connection = nm_device_get_applied_connection (self);
4638 g_assert (connection);
4640 /* Start DHCP again on the interface */
4641 ret = dhcp4_start (self, connection, &reason);
4643 return (ret != NM_ACT_STAGE_RETURN_FAILURE);
4646 /*********************************************/
4648 static GHashTable *shared_ips = NULL;
4651 release_shared_ip (gpointer data)
4653 g_hash_table_remove (shared_ips, data);
4657 reserve_shared_ip (NMDevice *self, NMSettingIPConfig *s_ip4, NMPlatformIP4Address *address)
4659 if (G_UNLIKELY (shared_ips == NULL))
4660 shared_ips = g_hash_table_new (g_direct_hash, g_direct_equal);
4662 memset (address, 0, sizeof (*address));
4664 if (s_ip4 && nm_setting_ip_config_get_num_addresses (s_ip4)) {
4665 /* Use the first user-supplied address */
4666 NMIPAddress *user = nm_setting_ip_config_get_address (s_ip4, 0);
4670 nm_ip_address_get_address_binary (user, &a);
4671 nm_platform_ip4_address_set_addr (address, a, nm_ip_address_get_prefix (user));
4673 /* Find an unused address in the 10.42.x.x range */
4674 guint32 start = (guint32) ntohl (0x0a2a0001); /* 10.42.0.1 */
4677 while (g_hash_table_lookup (shared_ips, GUINT_TO_POINTER (start + count))) {
4678 count += ntohl (0x100);
4679 if (count > ntohl (0xFE00)) {
4680 _LOGE (LOGD_SHARING, "ran out of shared IP addresses!");
4684 nm_platform_ip4_address_set_addr (address, start + count, 24);
4685 g_hash_table_add (shared_ips, GUINT_TO_POINTER (address->address));
4691 static NMIP4Config *
4692 shared4_new_config (NMDevice *self, NMConnection *connection, NMDeviceStateReason *reason)
4694 NMIP4Config *config = NULL;
4695 NMPlatformIP4Address address;
4697 g_return_val_if_fail (self != NULL, NULL);
4699 if (!reserve_shared_ip (self, nm_connection_get_setting_ip4_config (connection), &address)) {
4700 *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
4704 config = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
4705 address.source = NM_IP_CONFIG_SOURCE_SHARED;
4706 nm_ip4_config_add_address (config, &address);
4708 /* Remove the address lock when the object gets disposed */
4709 g_object_set_data_full (G_OBJECT (config), "shared-ip",
4710 GUINT_TO_POINTER (address.address),
4716 /*********************************************/
4719 connection_ip4_method_requires_carrier (NMConnection *connection,
4720 gboolean *out_ip4_enabled)
4722 const char *method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
4723 static const char *ip4_carrier_methods[] = {
4724 NM_SETTING_IP4_CONFIG_METHOD_AUTO,
4725 NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
4729 if (out_ip4_enabled)
4730 *out_ip4_enabled = !!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED);
4731 return _nm_utils_string_in_list (method, ip4_carrier_methods);
4735 connection_ip6_method_requires_carrier (NMConnection *connection,
4736 gboolean *out_ip6_enabled)
4738 const char *method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
4739 static const char *ip6_carrier_methods[] = {
4740 NM_SETTING_IP6_CONFIG_METHOD_AUTO,
4741 NM_SETTING_IP6_CONFIG_METHOD_DHCP,
4742 NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
4746 if (out_ip6_enabled)
4747 *out_ip6_enabled = !!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE);
4748 return _nm_utils_string_in_list (method, ip6_carrier_methods);
4752 connection_requires_carrier (NMConnection *connection)
4754 NMSettingIPConfig *s_ip4, *s_ip6;
4755 gboolean ip4_carrier_wanted, ip6_carrier_wanted;
4756 gboolean ip4_used = FALSE, ip6_used = FALSE;
4758 ip4_carrier_wanted = connection_ip4_method_requires_carrier (connection, &ip4_used);
4759 if (ip4_carrier_wanted) {
4760 /* If IPv4 wants a carrier and cannot fail, the whole connection
4761 * requires a carrier regardless of the IPv6 method.
4763 s_ip4 = nm_connection_get_setting_ip4_config (connection);
4764 if (s_ip4 && !nm_setting_ip_config_get_may_fail (s_ip4))
4768 ip6_carrier_wanted = connection_ip6_method_requires_carrier (connection, &ip6_used);
4769 if (ip6_carrier_wanted) {
4770 /* If IPv6 wants a carrier and cannot fail, the whole connection
4771 * requires a carrier regardless of the IPv4 method.
4773 s_ip6 = nm_connection_get_setting_ip6_config (connection);
4774 if (s_ip6 && !nm_setting_ip_config_get_may_fail (s_ip6))
4778 /* If an IP version wants a carrier and and the other IP version isn't
4779 * used, the connection requires carrier since it will just fail without one.
4781 if (ip4_carrier_wanted && !ip6_used)
4783 if (ip6_carrier_wanted && !ip4_used)
4786 /* If both want a carrier, the whole connection wants a carrier */
4787 return ip4_carrier_wanted && ip6_carrier_wanted;
4791 have_any_ready_slaves (NMDevice *self, const GSList *slaves)
4795 /* Any enslaved slave is "ready" in the generic case as it's
4796 * at least >= NM_DEVCIE_STATE_IP_CONFIG and has had Layer 2
4797 * properties set up.
4799 for (iter = slaves; iter; iter = g_slist_next (iter)) {
4800 if (nm_device_get_enslaved (iter->data))
4807 ip4_requires_slaves (NMConnection *connection)
4811 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
4812 return strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0;
4815 static NMActStageReturn
4816 act_stage3_ip4_config_start (NMDevice *self,
4817 NMIP4Config **out_config,
4818 NMDeviceStateReason *reason)
4820 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4821 NMConnection *connection;
4822 NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
4825 gboolean ready_slaves;
4827 g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
4829 connection = nm_device_get_applied_connection (self);
4830 g_assert (connection);
4832 if ( connection_ip4_method_requires_carrier (connection, NULL)
4834 && !priv->carrier) {
4835 _LOGI (LOGD_IP4 | LOGD_DEVICE,
4836 "IPv4 config waiting until carrier is on");
4837 return NM_ACT_STAGE_RETURN_WAIT;
4840 if (priv->is_master && ip4_requires_slaves (connection)) {
4841 /* If the master has no ready slaves, and depends on slaves for
4842 * a successful IPv4 attempt, then postpone IPv4 addressing.
4844 slaves = nm_device_master_get_slaves (self);
4845 ready_slaves = NM_DEVICE_GET_CLASS (self)->have_any_ready_slaves (self, slaves);
4846 g_slist_free (slaves);
4848 if (ready_slaves == FALSE) {
4849 _LOGI (LOGD_DEVICE | LOGD_IP4,
4850 "IPv4 config waiting until slaves are ready");
4851 return NM_ACT_STAGE_RETURN_WAIT;
4855 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
4857 /* Start IPv4 addressing based on the method requested */
4858 if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0)
4859 ret = dhcp4_start (self, connection, reason);
4860 else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) == 0)
4861 ret = ipv4ll_start (self, reason);
4862 else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0) {
4863 NMIP4Config **configs, *config;
4865 config = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
4866 nm_ip4_config_merge_setting (config,
4867 nm_connection_get_setting_ip4_config (connection),
4868 nm_device_get_ip4_route_metric (self));
4870 configs = g_new0 (NMIP4Config *, 2);
4871 configs[0] = config;
4872 ipv4_dad_start (self, configs, ipv4_manual_method_apply);
4873 ret = NM_ACT_STAGE_RETURN_POSTPONE;
4874 } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) {
4875 *out_config = shared4_new_config (self, connection, reason);
4877 priv->dnsmasq_manager = nm_dnsmasq_manager_new (nm_device_get_ip_iface (self));
4878 ret = NM_ACT_STAGE_RETURN_SUCCESS;
4880 ret = NM_ACT_STAGE_RETURN_FAILURE;
4881 } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) {
4882 /* Nothing to do... */
4883 ret = NM_ACT_STAGE_RETURN_STOP;
4885 _LOGW (LOGD_IP4, "unhandled IPv4 config method '%s'; will fail", method);
4890 /*********************************************/
4894 dhcp6_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release)
4896 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4898 priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE;
4899 g_clear_object (&priv->dhcp6_ip6_config);
4900 g_clear_pointer (&priv->dhcp6_event_id, g_free);
4901 nm_clear_g_source (&priv->dhcp6_restart_id);
4903 if (priv->dhcp6_client) {
4904 nm_clear_g_signal_handler (priv->dhcp6_client, &priv->dhcp6_state_sigid);
4906 if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE
4907 || cleanup_type == CLEANUP_TYPE_REMOVED)
4908 nm_dhcp_client_stop (priv->dhcp6_client, release);
4910 g_clear_object (&priv->dhcp6_client);
4913 nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
4915 if (priv->dhcp6_config) {
4916 nm_exported_object_clear_and_unexport (&priv->dhcp6_config);
4917 _notify (self, PROP_DHCP6_CONFIG);
4922 _ip6_config_merge_default (gpointer value, gpointer user_data)
4924 NMIP6Config *src = (NMIP6Config *) value;
4925 NMIP6Config *dst = (NMIP6Config *) user_data;
4927 nm_ip6_config_merge (dst, src, NM_IP_CONFIG_MERGE_DEFAULT);
4931 ip6_config_merge_and_apply (NMDevice *self,
4933 NMDeviceStateReason *out_reason)
4935 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
4936 NMConnection *connection;
4938 NMIP6Config *composite;
4939 gboolean has_direct_route;
4940 const struct in6_addr *gateway;
4941 gboolean connection_has_default_route, connection_is_never_default;
4942 gboolean routes_full_sync;
4943 gboolean ignore_auto_routes = FALSE;
4944 gboolean ignore_auto_dns = FALSE;
4946 /* Apply ignore-auto-routes and ignore-auto-dns settings */
4947 connection = nm_device_get_applied_connection (self);
4949 NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection);
4952 ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip6);
4953 ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip6);
4957 /* If no config was passed in, create a new one */
4958 composite = nm_ip6_config_new (nm_device_get_ip_ifindex (self));
4961 ensure_con_ip6_config (self);
4962 g_assert (composite);
4964 /* Merge all the IP configs into the composite config */
4965 if (priv->ac_ip6_config) {
4966 nm_ip6_config_merge (composite, priv->ac_ip6_config,
4967 (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
4968 | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
4970 if (priv->dhcp6_ip6_config) {
4971 nm_ip6_config_merge (composite, priv->dhcp6_ip6_config,
4972 (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
4973 | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
4976 g_slist_foreach (priv->vpn6_configs, _ip6_config_merge_default, composite);
4978 if (priv->ext_ip6_config)
4979 nm_ip6_config_merge (composite, priv->ext_ip6_config, NM_IP_CONFIG_MERGE_DEFAULT);
4981 /* Merge WWAN config *last* to ensure modem-given settings overwrite
4982 * any external stuff set by pppd or other scripts.
4984 if (priv->wwan_ip6_config) {
4985 nm_ip6_config_merge (composite, priv->wwan_ip6_config,
4986 (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
4987 | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
4990 /* Merge user overrides into the composite config. For assumed connections,
4991 * con_ip6_config is empty. */
4992 if (priv->con_ip6_config)
4993 nm_ip6_config_merge (composite, priv->con_ip6_config, NM_IP_CONFIG_MERGE_DEFAULT);
4995 /* Add the default route.
4997 * We keep track of the default route of a device in a private field.
4998 * NMDevice needs to know the default route at this point, because the gateway
4999 * might require a direct route (see below).
5001 * But also, we don't want to add the default route to priv->ip6_config,
5002 * because the default route from the setting might not be the same that
5003 * NMDefaultRouteManager eventually configures (because the it might
5004 * tweak the effective metric).
5007 /* unless we come to a different conclusion below, we have no default route and
5008 * the route is assumed. */
5009 priv->default_route.v6_has = FALSE;
5010 priv->default_route.v6_is_assumed = TRUE;
5013 /* during a non-commit event, we always pickup whatever is configured. */
5014 goto END_ADD_DEFAULT_ROUTE;
5017 if (nm_device_uses_generated_assumed_connection (self)) {
5018 /* a generate-assumed-connection always detects the default route from platform */
5019 goto END_ADD_DEFAULT_ROUTE;
5022 /* At this point, we treat assumed and non-assumed connections alike.
5023 * For assumed connections we do that because we still manage RA and DHCP
5024 * leases for them, so we must extend/update the default route on commits.
5027 connection_has_default_route
5028 = nm_default_route_manager_ip6_connection_has_default_route (nm_default_route_manager_get (),
5029 connection, &connection_is_never_default);
5031 if ( !priv->v6_commit_first_time
5032 && connection_is_never_default) {
5033 /* If the connection is explicitly configured as never-default, we enforce the (absence of the)
5034 * default-route only once. That allows the user to configure a connection as never-default,
5035 * but he can add default routes externally (via a dispatcher script) and NM will not interfere. */
5036 goto END_ADD_DEFAULT_ROUTE;
5039 /* we are about to commit (for a non-assumed connection). Enforce whatever we have
5041 priv->default_route.v6_is_assumed = FALSE;
5043 if (!connection_has_default_route)
5044 goto END_ADD_DEFAULT_ROUTE;
5046 if (!nm_ip6_config_get_num_addresses (composite)) {
5047 /* without addresses we can have no default route. */
5048 goto END_ADD_DEFAULT_ROUTE;
5051 gateway = nm_ip6_config_get_gateway (composite);
5053 goto END_ADD_DEFAULT_ROUTE;
5056 has_direct_route = nm_ip6_config_get_direct_route_for_host (composite, gateway) != NULL;
5060 priv->default_route.v6_has = TRUE;
5061 memset (&priv->default_route.v6, 0, sizeof (priv->default_route.v6));
5062 priv->default_route.v6.source = NM_IP_CONFIG_SOURCE_USER;
5063 priv->default_route.v6.gateway = *gateway;
5064 priv->default_route.v6.metric = nm_device_get_ip6_route_metric (self);
5065 priv->default_route.v6.mss = nm_ip6_config_get_mss (composite);
5067 if (!has_direct_route) {
5068 NMPlatformIP6Route r = priv->default_route.v6;
5070 /* add a direct route to the gateway */
5071 r.network = *gateway;
5073 r.gateway = in6addr_any;
5074 nm_ip6_config_add_route (composite, &r);
5077 END_ADD_DEFAULT_ROUTE:
5079 if (priv->default_route.v6_is_assumed) {
5080 /* If above does not explicitly assign a default route, we always pick up the
5081 * default route based on what is currently configured.
5082 * That means that even managed connections with never-default, can
5083 * get a default route (if configured externally).
5085 priv->default_route.v6_has = _device_get_default_route_from_platform (self, AF_INET6, (NMPlatformIPRoute *) &priv->default_route.v6);
5088 nm_ip6_config_addresses_sort (composite,
5089 priv->rdisc ? priv->rdisc_use_tempaddr : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
5091 /* Allow setting MTU etc */
5093 if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit)
5094 NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self, composite);
5097 routes_full_sync = commit
5098 && priv->v6_commit_first_time
5099 && !nm_device_uses_assumed_connection (self);
5101 success = nm_device_set_ip6_config (self, composite, commit, routes_full_sync, out_reason);
5102 g_object_unref (composite);
5104 priv->v6_commit_first_time = FALSE;
5109 dhcp6_lease_change (NMDevice *self)
5111 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5112 NMSettingsConnection *settings_connection;
5113 NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
5115 if (priv->dhcp6_ip6_config == NULL) {
5116 _LOGW (LOGD_DHCP6, "failed to get DHCPv6 config for rebind");
5117 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
5121 g_assert (priv->dhcp6_client); /* sanity check */
5123 settings_connection = nm_device_get_settings_connection (self);
5124 g_assert (settings_connection);
5126 /* Apply the updated config */
5127 if (ip6_config_merge_and_apply (self, TRUE, &reason) == FALSE) {
5128 _LOGW (LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event.");
5129 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
5131 /* Notify dispatcher scripts of new DHCPv6 config */
5132 nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE,
5133 settings_connection,
5134 nm_device_get_applied_connection (self),
5135 self, NULL, NULL, NULL);
5140 dhcp6_restart_cb (gpointer user_data)
5142 NMDevice *self = user_data;
5143 NMDevicePrivate *priv;
5144 NMDeviceStateReason reason;
5146 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
5148 priv = NM_DEVICE_GET_PRIVATE (self);
5149 priv->dhcp6_restart_id = 0;
5151 if (!dhcp6_start (self, FALSE, &reason))
5152 priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self);
5158 dhcp6_fail (NMDevice *self, gboolean timeout)
5160 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5162 dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE);
5164 if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) {
5165 /* Don't fail if there are static addresses configured on
5166 * the device, instead retry after some time.
5168 if ( priv->ip6_state == IP_DONE
5169 && priv->con_ip6_config
5170 && nm_ip6_config_get_num_addresses (priv->con_ip6_config)) {
5171 _LOGI (LOGD_DHCP6, "Scheduling DHCPv6 restart because device has IP addresses");
5172 priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self);
5176 /* Instead of letting an assumed connection fail (which means that the
5177 * device will transition to the ACTIVATED state without IP configuration),
5180 if (nm_device_uses_assumed_connection (self)) {
5181 _LOGI (LOGD_DHCP6, "Scheduling DHCPv6 restart because the connection is assumed");
5182 priv->dhcp6_restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self);
5186 if (timeout || (priv->ip6_state == IP_CONF))
5187 nm_device_activate_schedule_ip6_config_timeout (self);
5188 else if (priv->ip6_state == IP_DONE)
5189 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
5191 g_warn_if_reached ();
5193 /* not a hard failure; just live with the RA info */
5194 if (priv->ip6_state == IP_CONF)
5195 nm_device_activate_schedule_ip6_config_result (self);
5200 dhcp6_timeout (NMDevice *self, NMDhcpClient *client)
5202 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5204 if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED)
5205 dhcp6_fail (self, TRUE);
5207 /* not a hard failure; just live with the RA info */
5208 dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE);
5209 if (priv->ip6_state == IP_CONF)
5210 nm_device_activate_schedule_ip6_config_result (self);
5215 dhcp6_state_changed (NMDhcpClient *client,
5217 NMIP6Config *ip6_config,
5218 GHashTable *options,
5219 const char *event_id,
5222 NMDevice *self = NM_DEVICE (user_data);
5223 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5226 g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == TRUE);
5227 g_return_if_fail (!ip6_config || NM_IS_IP6_CONFIG (ip6_config));
5229 _LOGD (LOGD_DHCP6, "new DHCPv6 client state %d", state);
5232 case NM_DHCP_STATE_BOUND:
5233 /* If the server sends multiple IPv6 addresses, we receive a state
5234 * changed event for each of them. Use the event ID to merge IPv6
5235 * addresses from the same transaction into a single configuration.
5239 && priv->dhcp6_event_id
5240 && !strcmp (event_id, priv->dhcp6_event_id)) {
5241 for (i = 0; i < nm_ip6_config_get_num_addresses (ip6_config); i++) {
5242 nm_ip6_config_add_address (priv->dhcp6_ip6_config,
5243 nm_ip6_config_get_address (ip6_config, i));
5246 g_clear_object (&priv->dhcp6_ip6_config);
5247 g_clear_pointer (&priv->dhcp6_event_id, g_free);
5249 priv->dhcp6_ip6_config = g_object_ref (ip6_config);
5250 priv->dhcp6_event_id = g_strdup (event_id);
5251 nm_dhcp6_config_set_options (priv->dhcp6_config, options);
5252 _notify (self, PROP_DHCP6_CONFIG);
5256 if (priv->ip6_state == IP_CONF) {
5257 if (priv->dhcp6_ip6_config == NULL) {
5258 /* FIXME: Initial DHCP failed; should we fail IPv6 entirely then? */
5259 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED);
5262 nm_device_activate_schedule_ip6_config_result (self);
5263 } else if (priv->ip6_state == IP_DONE)
5264 dhcp6_lease_change (self);
5266 case NM_DHCP_STATE_TIMEOUT:
5267 dhcp6_timeout (self, client);
5269 case NM_DHCP_STATE_EXPIRE:
5270 /* Ignore expiry before we even have a lease (NAK, old lease, etc) */
5271 if (priv->ip6_state != IP_CONF)
5272 dhcp6_fail (self, FALSE);
5274 case NM_DHCP_STATE_DONE:
5275 /* In IPv6 info-only mode, the client doesn't handle leases so it
5276 * may exit right after getting a response from the server. That's
5277 * normal. In that case we just ignore the exit.
5279 if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF)
5281 /* Otherwise, fall through */
5282 case NM_DHCP_STATE_FAIL:
5283 dhcp6_fail (self, FALSE);
5291 dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection)
5293 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5294 NMSettingIPConfig *s_ip6;
5295 GByteArray *tmp = NULL;
5296 const guint8 *hw_addr;
5297 size_t hw_addr_len = 0;
5298 const NMPlatformIP6Address *ll_addr = NULL;
5300 g_assert (connection);
5301 s_ip6 = nm_connection_get_setting_ip6_config (connection);
5304 hw_addr = nm_platform_link_get_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), &hw_addr_len);
5306 tmp = g_byte_array_sized_new (hw_addr_len);
5307 g_byte_array_append (tmp, hw_addr, hw_addr_len);
5310 if (priv->ext_ip6_config_captured)
5311 ll_addr = nm_ip6_config_get_address_first_nontentative (priv->ext_ip6_config_captured, TRUE);
5313 g_return_val_if_fail (ll_addr, FALSE);
5315 priv->dhcp6_client = nm_dhcp_manager_start_ip6 (nm_dhcp_manager_get (),
5316 nm_device_get_ip_iface (self),
5317 nm_device_get_ip_ifindex (self),
5320 nm_connection_get_uuid (connection),
5321 nm_device_get_ip6_route_metric (self),
5322 nm_setting_ip_config_get_dhcp_send_hostname (s_ip6),
5323 nm_setting_ip_config_get_dhcp_hostname (s_ip6),
5325 priv->dhcp_anycast_address,
5326 (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE,
5327 nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)));
5329 g_byte_array_free (tmp, TRUE);
5331 if (priv->dhcp6_client) {
5332 priv->dhcp6_state_sigid = g_signal_connect (priv->dhcp6_client,
5333 NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
5334 G_CALLBACK (dhcp6_state_changed),
5338 return !!priv->dhcp6_client;
5342 dhcp6_start (NMDevice *self, gboolean wait_for_ll, NMDeviceStateReason *reason)
5344 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5345 NMConnection *connection;
5346 NMSettingIPConfig *s_ip6;
5348 nm_exported_object_clear_and_unexport (&priv->dhcp6_config);
5349 priv->dhcp6_config = nm_dhcp6_config_new ();
5351 g_warn_if_fail (priv->dhcp6_ip6_config == NULL);
5352 g_clear_object (&priv->dhcp6_ip6_config);
5353 g_clear_pointer (&priv->dhcp6_event_id, g_free);
5355 connection = nm_device_get_applied_connection (self);
5356 g_assert (connection);
5357 s_ip6 = nm_connection_get_setting_ip6_config (connection);
5358 if (!nm_setting_ip_config_get_may_fail (s_ip6) ||
5359 !strcmp (nm_setting_ip_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_DHCP))
5360 nm_device_add_pending_action (self, PENDING_ACTION_DHCP6, TRUE);
5363 NMActStageReturn ret;
5365 /* ensure link local is ready... */
5366 ret = linklocal6_start (self);
5367 if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
5368 /* success; wait for the LL address to show up */
5372 /* success; already have the LL address; kick off DHCP */
5373 g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS || ret == NM_ACT_STAGE_RETURN_FINISH);
5376 if (!dhcp6_start_with_link_ready (self, connection)) {
5377 *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED;
5385 nm_device_dhcp6_renew (NMDevice *self, gboolean release)
5387 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5389 g_return_val_if_fail (priv->dhcp6_client != NULL, FALSE);
5391 _LOGI (LOGD_DHCP6, "DHCPv6 lease renewal requested");
5393 /* Terminate old DHCP instance and release the old lease */
5394 dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, release);
5396 /* Start DHCP again on the interface */
5397 return dhcp6_start (self, FALSE, NULL);
5400 /******************************************/
5403 linklocal6_cleanup (NMDevice *self)
5405 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5407 nm_clear_g_source (&priv->linklocal6_timeout_id);
5411 linklocal6_failed (NMDevice *self)
5413 linklocal6_cleanup (self);
5414 nm_device_activate_schedule_ip6_config_timeout (self);
5418 linklocal6_timeout_cb (gpointer user_data)
5420 NMDevice *self = user_data;
5422 _LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses failed due to timeout");
5423 linklocal6_failed (self);
5424 return G_SOURCE_REMOVE;
5428 linklocal6_complete (NMDevice *self)
5430 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5431 NMConnection *connection;
5434 g_assert (priv->linklocal6_timeout_id);
5435 g_assert (nm_ip6_config_get_address_first_nontentative (priv->ip6_config, TRUE));
5437 linklocal6_cleanup (self);
5439 connection = nm_device_get_applied_connection (self);
5440 g_assert (connection);
5442 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
5444 _LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses successful, continue with method %s", method);
5446 if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
5447 if (!addrconf6_start_with_link_ready (self)) {
5448 /* Time out IPv6 instead of failing the entire activation */
5449 nm_device_activate_schedule_ip6_config_timeout (self);
5451 } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) {
5452 if (!dhcp6_start_with_link_ready (self, connection)) {
5453 /* Time out IPv6 instead of failing the entire activation */
5454 nm_device_activate_schedule_ip6_config_timeout (self);
5456 } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0)
5457 nm_device_activate_schedule_ip6_config_result (self);
5459 g_return_if_fail (FALSE);
5463 check_and_add_ipv6ll_addr (NMDevice *self)
5465 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5466 int ip_ifindex = nm_device_get_ip_ifindex (self);
5467 struct in6_addr lladdr;
5469 NMConnection *connection;
5470 NMSettingIP6Config *s_ip6 = NULL;
5471 GError *error = NULL;
5473 if (priv->nm_ipv6ll == FALSE)
5476 if (priv->ip6_config) {
5477 n = nm_ip6_config_get_num_addresses (priv->ip6_config);
5478 for (i = 0; i < n; i++) {
5479 const NMPlatformIP6Address *addr;
5481 addr = nm_ip6_config_get_address (priv->ip6_config, i);
5482 if ( IN6_IS_ADDR_LINKLOCAL (&addr->address)
5483 && !(addr->n_ifa_flags & IFA_F_DADFAILED)) {
5484 /* Already have an LL address, nothing to do */
5490 memset (&lladdr, 0, sizeof (lladdr));
5491 lladdr.s6_addr16[0] = htons (0xfe80);
5493 connection = nm_device_get_applied_connection (self);
5495 s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection));
5497 if (s_ip6 && nm_setting_ip6_config_get_addr_gen_mode (s_ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) {
5498 if (!nm_utils_ipv6_addr_set_stable_privacy (&lladdr,
5499 nm_device_get_iface (self),
5500 nm_connection_get_uuid (connection),
5501 priv->linklocal6_dad_counter++,
5503 _LOGW (LOGD_IP6, "linklocal6: failed to generate an address: %s", error->message);
5504 g_clear_error (&error);
5505 linklocal6_failed (self);
5508 _LOGD (LOGD_IP6, "linklocal6: using IPv6 stable-privacy addressing");
5510 NMUtilsIPv6IfaceId iid;
5512 if (priv->linklocal6_timeout_id) {
5513 /* We already started and attempt to add a LL address. For the EUI-64
5514 * mode we can't pick a new one, we'll just fail. */
5515 _LOGW (LOGD_IP6, "linklocal6: DAD failed for an EUI-64 address");
5516 linklocal6_failed (self);
5520 if (!nm_device_get_ip_iface_identifier (self, &iid)) {
5521 _LOGW (LOGD_IP6, "linklocal6: failed to get interface identifier; IPv6 cannot continue");
5524 _LOGD (LOGD_IP6, "linklocal6: using EUI-64 identifier to generate IPv6LL address");
5526 nm_utils_ipv6_addr_set_interface_identfier (&lladdr, iid);
5529 _LOGD (LOGD_IP6, "linklocal6: adding IPv6LL address %s", nm_utils_inet6_ntop (&lladdr, NULL));
5530 if (!nm_platform_ip6_address_add (NM_PLATFORM_GET,
5535 NM_PLATFORM_LIFETIME_PERMANENT,
5536 NM_PLATFORM_LIFETIME_PERMANENT,
5538 _LOGW (LOGD_IP6, "failed to add IPv6 link-local address %s",
5539 nm_utils_inet6_ntop (&lladdr, NULL));
5543 static NMActStageReturn
5544 linklocal6_start (NMDevice *self)
5546 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5547 NMConnection *connection;
5550 linklocal6_cleanup (self);
5552 if ( priv->ip6_config
5553 && nm_ip6_config_get_address_first_nontentative (priv->ip6_config, TRUE))
5554 return NM_ACT_STAGE_RETURN_FINISH;
5556 connection = nm_device_get_applied_connection (self);
5557 g_assert (connection);
5559 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
5560 _LOGD (LOGD_DEVICE, "linklocal6: starting IPv6 with method '%s', but the device has no link-local addresses configured. Wait.", method);
5562 check_and_add_ipv6ll_addr (self);
5564 /* Depending on the network and what the 'dad_transmits' and 'retrans_time_ms'
5565 * sysctl values are, DAD for the IPv6LL address may take quite a while.
5566 * FIXME: use dad/retrans sysctl values if they are higher than a minimum time.
5569 priv->linklocal6_timeout_id = g_timeout_add_seconds (15, linklocal6_timeout_cb, self);
5571 return NM_ACT_STAGE_RETURN_POSTPONE;
5574 /******************************************/
5576 static void nm_device_ipv6_set_mtu (NMDevice *self, guint32 mtu);
5579 nm_device_set_mtu (NMDevice *self, guint32 mtu)
5581 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5582 int ifindex = nm_device_get_ip_ifindex (self);
5587 /* Ensure the IPv6 MTU is still alright. */
5589 nm_device_ipv6_set_mtu (self, priv->ip6_mtu);
5591 if (priv->mtu && priv->mtu != nm_platform_link_get_mtu (NM_PLATFORM_GET, ifindex))
5592 nm_platform_link_set_mtu (NM_PLATFORM_GET, ifindex, priv->mtu);
5596 nm_device_ipv6_set_mtu (NMDevice *self, guint32 mtu)
5598 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5599 guint32 plat_mtu = nm_device_ipv6_sysctl_get_int32 (self, "mtu", priv->mtu);
5602 priv->ip6_mtu = mtu ?: plat_mtu;
5604 if (priv->ip6_mtu && priv->mtu && priv->mtu < priv->ip6_mtu) {
5605 _LOGI (LOGD_DEVICE | LOGD_IP6, "Lowering IPv6 MTU (%d) to match device MTU (%d)",
5606 priv->ip6_mtu, priv->mtu);
5607 priv->ip6_mtu = priv->mtu;
5610 if (priv->ip6_mtu && priv->ip6_mtu < 1280) {
5611 _LOGI (LOGD_DEVICE | LOGD_IP6, "IPv6 MTU (%d) smaller than 1280, adjusting",
5613 priv->ip6_mtu = 1280;
5616 if (priv->ip6_mtu && priv->mtu && priv->mtu < priv->ip6_mtu) {
5617 _LOGI (LOGD_DEVICE | LOGD_IP6, "Raising device MTU (%d) to match IPv6 MTU (%d)",
5618 priv->mtu, priv->ip6_mtu);
5619 nm_device_set_mtu (self, priv->ip6_mtu);
5622 if (priv->ip6_mtu != plat_mtu) {
5623 g_snprintf (val, sizeof (val), "%d", mtu);
5624 nm_device_ipv6_sysctl_set (self, "mtu", val);
5629 rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
5631 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5634 guint32 ifa_flags = 0x00;
5637 * Check, whether kernel is recent enough to help user space handling RA.
5638 * If it's not supported, we have no ipv6-privacy and must add autoconf
5639 * addresses as /128. The reason for the /128 is to prevent the kernel
5640 * from adding a prefix route for this address.
5642 system_support = nm_platform_check_support_kernel_extended_ifa_flags (NM_PLATFORM_GET);
5645 ifa_flags = IFA_F_NOPREFIXROUTE;
5646 if ( priv->rdisc_use_tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR
5647 || priv->rdisc_use_tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)
5649 /* without system_support, this flag will be ignored. Still set it, doesn't seem to do any harm. */
5650 ifa_flags |= IFA_F_MANAGETEMPADDR;
5653 g_return_if_fail (priv->act_request);
5655 if (!priv->ac_ip6_config)
5656 priv->ac_ip6_config = nm_ip6_config_new (nm_device_get_ip_ifindex (self));
5658 if (changed & NM_RDISC_CONFIG_GATEWAYS) {
5659 /* Use the first gateway as ordered in router discovery cache. */
5660 if (rdisc->gateways->len) {
5661 NMRDiscGateway *gateway = &g_array_index (rdisc->gateways, NMRDiscGateway, 0);
5663 nm_ip6_config_set_gateway (priv->ac_ip6_config, &gateway->address);
5665 nm_ip6_config_set_gateway (priv->ac_ip6_config, NULL);
5668 if (changed & NM_RDISC_CONFIG_ADDRESSES) {
5669 /* Rebuild address list from router discovery cache. */
5670 nm_ip6_config_reset_addresses (priv->ac_ip6_config);
5672 /* rdisc->addresses contains at most max_addresses entries.
5673 * This is different from what the kernel does, which
5674 * also counts static and temporary addresses when checking
5677 for (i = 0; i < rdisc->addresses->len; i++) {
5678 NMRDiscAddress *discovered_address = &g_array_index (rdisc->addresses, NMRDiscAddress, i);
5679 NMPlatformIP6Address address;
5681 memset (&address, 0, sizeof (address));
5682 address.address = discovered_address->address;
5683 address.plen = system_support ? 64 : 128;
5684 address.timestamp = discovered_address->timestamp;
5685 address.lifetime = discovered_address->lifetime;
5686 address.preferred = discovered_address->preferred;
5687 if (address.preferred > address.lifetime)
5688 address.preferred = address.lifetime;
5689 address.source = NM_IP_CONFIG_SOURCE_RDISC;
5690 address.n_ifa_flags = ifa_flags;
5692 nm_ip6_config_add_address (priv->ac_ip6_config, &address);
5696 if (changed & NM_RDISC_CONFIG_ROUTES) {
5697 /* Rebuild route list from router discovery cache. */
5698 nm_ip6_config_reset_routes (priv->ac_ip6_config);
5700 for (i = 0; i < rdisc->routes->len; i++) {
5701 NMRDiscRoute *discovered_route = &g_array_index (rdisc->routes, NMRDiscRoute, i);
5702 NMPlatformIP6Route route;
5704 /* Only accept non-default routes. The router has no idea what the
5705 * local configuration or user preferences are, so sending routes
5706 * with a prefix length of 0 is quite rude and thus ignored.
5708 if (discovered_route->plen > 0) {
5709 memset (&route, 0, sizeof (route));
5710 route.network = discovered_route->network;
5711 route.plen = discovered_route->plen;
5712 route.gateway = discovered_route->gateway;
5713 route.source = NM_IP_CONFIG_SOURCE_RDISC;
5714 route.metric = nm_device_get_ip6_route_metric (self);
5716 nm_ip6_config_add_route (priv->ac_ip6_config, &route);
5721 if (changed & NM_RDISC_CONFIG_DNS_SERVERS) {
5722 /* Rebuild DNS server list from router discovery cache. */
5723 nm_ip6_config_reset_nameservers (priv->ac_ip6_config);
5725 for (i = 0; i < rdisc->dns_servers->len; i++) {
5726 NMRDiscDNSServer *discovered_server = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i);
5728 nm_ip6_config_add_nameserver (priv->ac_ip6_config, &discovered_server->address);
5732 if (changed & NM_RDISC_CONFIG_DNS_DOMAINS) {
5733 /* Rebuild domain list from router discovery cache. */
5734 nm_ip6_config_reset_domains (priv->ac_ip6_config);
5736 for (i = 0; i < rdisc->dns_domains->len; i++) {
5737 NMRDiscDNSDomain *discovered_domain = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i);
5739 nm_ip6_config_add_domain (priv->ac_ip6_config, discovered_domain->domain);
5743 if (changed & NM_RDISC_CONFIG_DHCP_LEVEL) {
5744 dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, TRUE);
5746 priv->dhcp6_mode = rdisc->dhcp_level;
5747 if (priv->dhcp6_mode != NM_RDISC_DHCP_LEVEL_NONE) {
5748 NMDeviceStateReason reason;
5750 _LOGD (LOGD_DEVICE | LOGD_DHCP6,
5751 "Activation: Stage 3 of 5 (IP Configure Start) starting DHCPv6"
5752 " as requested by IPv6 router...");
5753 if (!dhcp6_start (self, FALSE, &reason)) {
5754 if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) {
5755 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
5762 if (changed & NM_RDISC_CONFIG_HOP_LIMIT)
5763 nm_platform_sysctl_set_ip6_hop_limit_safe (NM_PLATFORM_GET, nm_device_get_ip_iface (self), rdisc->hop_limit);
5765 if (changed & NM_RDISC_CONFIG_MTU)
5766 priv->ip6_mtu = rdisc->mtu;
5768 nm_device_activate_schedule_ip6_config_result (self);
5772 rdisc_ra_timeout (NMRDisc *rdisc, NMDevice *self)
5774 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5776 /* We don't want to stop listening for router advertisements completely,
5777 * but instead let device activation continue activating. If an RA
5778 * shows up later, we'll use it as long as the device is not disconnected.
5781 _LOGD (LOGD_IP6, "timed out waiting for IPv6 router advertisement");
5782 if (priv->ip6_state == IP_CONF) {
5783 /* If RA is our only source of addressing information and we don't
5784 * ever receive one, then time out IPv6. But if there is other
5785 * IPv6 configuration, like manual IPv6 addresses or external IPv6
5786 * config, consider that sufficient for IPv6 success.
5788 if ( priv->ip6_config
5789 && nm_ip6_config_get_address_first_nontentative (priv->ip6_config, FALSE))
5790 nm_device_activate_schedule_ip6_config_result (self);
5792 nm_device_activate_schedule_ip6_config_timeout (self);
5797 addrconf6_start_with_link_ready (NMDevice *self)
5799 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5800 NMUtilsIPv6IfaceId iid;
5802 g_assert (priv->rdisc);
5804 if (nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &iid)) {
5805 _LOGD (LOGD_IP6, "addrconf6: IPv6 tokenized identifier present");
5806 nm_rdisc_set_iid (priv->rdisc, iid);
5807 } else if (nm_device_get_ip_iface_identifier (self, &iid)) {
5808 _LOGD (LOGD_IP6, "addrconf6: using the device EUI-64 identifier");
5809 nm_rdisc_set_iid (priv->rdisc, iid);
5811 /* Don't abort the addrconf at this point -- if rdisc needs the iid
5812 * it will notice this itself. */
5813 _LOGI (LOGD_IP6, "addrconf6: no interface identifier; IPv6 adddress creation may fail");
5816 /* Apply any manual configuration before starting RA */
5817 if (!ip6_config_merge_and_apply (self, TRUE, NULL))
5818 _LOGW (LOGD_IP6, "failed to apply manual IPv6 configuration");
5820 nm_device_ipv6_sysctl_set (self, "accept_ra", "1");
5821 nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0");
5822 nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0");
5823 nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0");
5825 priv->rdisc_changed_id = g_signal_connect (priv->rdisc,
5826 NM_RDISC_CONFIG_CHANGED,
5827 G_CALLBACK (rdisc_config_changed),
5829 priv->rdisc_timeout_id = g_signal_connect (priv->rdisc,
5830 NM_RDISC_RA_TIMEOUT,
5831 G_CALLBACK (rdisc_ra_timeout),
5834 nm_rdisc_start (priv->rdisc);
5839 addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
5841 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5842 NMConnection *connection;
5843 NMActStageReturn ret;
5844 NMSettingIP6Config *s_ip6 = NULL;
5845 GError *error = NULL;
5847 connection = nm_device_get_applied_connection (self);
5848 g_assert (connection);
5850 g_warn_if_fail (priv->ac_ip6_config == NULL);
5851 if (priv->ac_ip6_config) {
5852 g_object_unref (priv->ac_ip6_config);
5853 priv->ac_ip6_config = NULL;
5856 s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection));
5859 priv->rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET,
5860 nm_device_get_ip_ifindex (self),
5861 nm_device_get_ip_iface (self),
5862 nm_connection_get_uuid (connection),
5863 nm_setting_ip6_config_get_addr_gen_mode (s_ip6),
5866 _LOGE (LOGD_IP6, "addrconf6: failed to start router discovery: %s", error->message);
5867 g_error_free (error);
5871 priv->rdisc_use_tempaddr = use_tempaddr;
5873 if ( NM_IN_SET (use_tempaddr, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)
5874 && !nm_platform_check_support_kernel_extended_ifa_flags (NM_PLATFORM_GET)) {
5875 _LOGW (LOGD_IP6, "The kernel does not support extended IFA_FLAGS needed by NM for "
5876 "IPv6 private addresses. This feature is not available");
5879 if (!nm_setting_ip_config_get_may_fail (nm_connection_get_setting_ip6_config (connection)))
5880 nm_device_add_pending_action (self, PENDING_ACTION_AUTOCONF6, TRUE);
5882 /* ensure link local is ready... */
5883 ret = linklocal6_start (self);
5884 if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
5885 /* success; wait for the LL address to show up */
5889 /* success; already have the LL address; kick off router discovery */
5890 g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS || ret == NM_ACT_STAGE_RETURN_FINISH);
5891 return addrconf6_start_with_link_ready (self);
5895 addrconf6_cleanup (NMDevice *self)
5897 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5899 nm_clear_g_signal_handler (priv->rdisc, &priv->rdisc_changed_id);
5900 nm_clear_g_signal_handler (priv->rdisc, &priv->rdisc_timeout_id);
5902 nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE);
5904 g_clear_object (&priv->ac_ip6_config);
5905 g_clear_object (&priv->rdisc);
5908 /******************************************/
5910 static const char *ip6_properties_to_save[] = {
5914 "accept_ra_rtr_pref",
5921 save_ip6_properties (NMDevice *self)
5923 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5924 const char *ifname = nm_device_get_ip_iface (self);
5928 g_hash_table_remove_all (priv->ip6_saved_properties);
5930 for (i = 0; i < G_N_ELEMENTS (ip6_properties_to_save); i++) {
5931 value = nm_platform_sysctl_get (NM_PLATFORM_GET, nm_utils_ip6_property_path (ifname, ip6_properties_to_save[i]));
5933 g_hash_table_insert (priv->ip6_saved_properties,
5934 (char *) ip6_properties_to_save[i],
5941 restore_ip6_properties (NMDevice *self)
5943 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5944 GHashTableIter iter;
5945 gpointer key, value;
5947 g_hash_table_iter_init (&iter, priv->ip6_saved_properties);
5948 while (g_hash_table_iter_next (&iter, &key, &value)) {
5949 /* Don't touch "disable_ipv6" if we're doing userland IPv6LL */
5950 if (priv->nm_ipv6ll && strcmp (key, "disable_ipv6") == 0)
5952 nm_device_ipv6_sysctl_set (self, key, value);
5957 set_disable_ipv6 (NMDevice *self, const char *value)
5959 /* We only touch disable_ipv6 when NM is not managing the IPv6LL address */
5960 if (NM_DEVICE_GET_PRIVATE (self)->nm_ipv6ll == FALSE)
5961 nm_device_ipv6_sysctl_set (self, "disable_ipv6", value);
5965 set_nm_ipv6ll (NMDevice *self, gboolean enable)
5967 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
5968 int ifindex = nm_device_get_ip_ifindex (self);
5971 if (!nm_platform_check_support_user_ipv6ll (NM_PLATFORM_GET))
5974 priv->nm_ipv6ll = enable;
5976 const char *detail = enable ? "enable" : "disable";
5978 _LOGD (LOGD_IP6, "will %s userland IPv6LL", detail);
5979 if (!nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, ifindex, enable))
5980 _LOGW (LOGD_IP6, "failed to %s userspace IPv6LL address handling", detail);
5983 /* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */
5984 value = nm_platform_sysctl_get (NM_PLATFORM_GET,
5985 nm_utils_ip6_property_path (nm_device_get_ip_iface (self), "disable_ipv6"));
5986 if (g_strcmp0 (value, "0") == 0)
5987 nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1");
5990 /* Ensure IPv6 is enabled */
5991 nm_device_ipv6_sysctl_set (self, "disable_ipv6", "0");
5997 /************************************************************************/
5999 static NMSettingIP6ConfigPrivacy
6000 _ip6_privacy_clamp (NMSettingIP6ConfigPrivacy use_tempaddr)
6002 switch (use_tempaddr) {
6003 case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
6004 case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR:
6005 case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR:
6006 return use_tempaddr;
6008 return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
6012 static NMSettingIP6ConfigPrivacy
6013 _ip6_privacy_get (NMDevice *self)
6015 NMSettingIP6ConfigPrivacy ip6_privacy;
6016 gs_free char *value = NULL;
6017 NMConnection *connection;
6019 g_return_val_if_fail (self, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
6021 /* 1.) First look at the per-connection setting. If it is not -1 (unknown),
6023 connection = nm_device_get_applied_connection (self);
6025 NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection);
6028 ip6_privacy = nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6));
6029 ip6_privacy = _ip6_privacy_clamp (ip6_privacy);
6030 if (ip6_privacy != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)
6035 value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
6036 "ipv6.ip6-privacy", self);
6038 /* 2.) use the default value from the configuration. */
6039 ip6_privacy = _nm_utils_ascii_str_to_int64 (value, 10,
6040 NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
6041 NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
6042 NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
6043 if (ip6_privacy != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)
6046 /* 3.) No valid default-value configured. Fallback to reading sysctl.
6048 * Instead of reading static config files in /etc, just read the current sysctl value.
6049 * This works as NM only writes to "/proc/sys/net/ipv6/conf/IFNAME/use_tempaddr", but leaves
6050 * the "default" entry untouched. */
6051 ip6_privacy = nm_platform_sysctl_get_int32 (NM_PLATFORM_GET, "/proc/sys/net/ipv6/conf/default/use_tempaddr", NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
6052 return _ip6_privacy_clamp (ip6_privacy);
6055 /****************************************************************/
6058 ip6_requires_slaves (NMConnection *connection)
6062 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
6064 /* SLAAC, DHCP, and Link-Local depend on connectivity (and thus slaves)
6065 * to complete addressing. SLAAC and DHCP obviously need a peer to
6066 * provide a prefix, while Link-Local must perform DAD on the local link.
6068 return strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0
6069 || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0
6070 || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0;
6073 static NMActStageReturn
6074 act_stage3_ip6_config_start (NMDevice *self,
6075 NMIP6Config **out_config,
6076 NMDeviceStateReason *reason)
6078 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6079 NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
6080 NMConnection *connection;
6082 NMSettingIP6ConfigPrivacy ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
6083 const char *ip6_privacy_str = "0\n";
6085 gboolean ready_slaves;
6087 g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
6089 connection = nm_device_get_applied_connection (self);
6090 g_assert (connection);
6092 if ( connection_ip6_method_requires_carrier (connection, NULL)
6094 && !priv->carrier) {
6095 _LOGI (LOGD_IP6 | LOGD_DEVICE,
6096 "IPv6 config waiting until carrier is on");
6097 return NM_ACT_STAGE_RETURN_WAIT;
6100 if (priv->is_master && ip6_requires_slaves (connection)) {
6101 /* If the master has no ready slaves, and depends on slaves for
6102 * a successful IPv6 attempt, then postpone IPv6 addressing.
6104 slaves = nm_device_master_get_slaves (self);
6105 ready_slaves = NM_DEVICE_GET_CLASS (self)->have_any_ready_slaves (self, slaves);
6106 g_slist_free (slaves);
6108 if (ready_slaves == FALSE) {
6109 _LOGI (LOGD_DEVICE | LOGD_IP6,
6110 "IPv6 config waiting until slaves are ready");
6111 return NM_ACT_STAGE_RETURN_WAIT;
6115 priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE;
6117 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
6119 if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) {
6120 if (!priv->master) {
6121 gboolean old_nm_ipv6ll = priv->nm_ipv6ll;
6123 /* When activating an IPv6 'ignore' connection we need to revert back
6124 * to kernel IPv6LL, but the kernel won't actually assign an address
6125 * to the interface until disable_ipv6 is bounced.
6127 set_nm_ipv6ll (self, FALSE);
6128 if (old_nm_ipv6ll == TRUE)
6129 nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1");
6130 restore_ip6_properties (self);
6132 return NM_ACT_STAGE_RETURN_STOP;
6135 /* Ensure the MTU makes sense. If it was below 1280 the kernel would not
6136 * expose any ipv6 sysctls or allow presence of any addresses on the interface,
6137 * including LL, which * would make it impossible to autoconfigure MTU to a
6139 if (!nm_device_uses_assumed_connection (self))
6140 nm_device_ipv6_set_mtu (self, priv->ip6_mtu);
6142 /* Any method past this point requires an IPv6LL address. Use NM-controlled
6143 * IPv6LL if this is not an assumed connection, since assumed connections
6144 * will already have IPv6 set up.
6146 if (!nm_device_uses_assumed_connection (self))
6147 set_nm_ipv6ll (self, TRUE);
6149 /* Re-enable IPv6 on the interface */
6150 set_disable_ipv6 (self, "0");
6152 ip6_privacy = _ip6_privacy_get (self);
6154 if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
6155 if (!addrconf6_start (self, ip6_privacy)) {
6156 /* IPv6 might be disabled; allow IPv4 to proceed */
6157 ret = NM_ACT_STAGE_RETURN_STOP;
6159 ret = NM_ACT_STAGE_RETURN_POSTPONE;
6160 } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) {
6161 ret = linklocal6_start (self);
6162 } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) {
6163 priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_MANAGED;
6164 if (!dhcp6_start (self, TRUE, reason)) {
6165 /* IPv6 might be disabled; allow IPv4 to proceed */
6166 ret = NM_ACT_STAGE_RETURN_STOP;
6168 ret = NM_ACT_STAGE_RETURN_POSTPONE;
6169 } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0) {
6170 /* New blank config */
6171 *out_config = nm_ip6_config_new (nm_device_get_ip_ifindex (self));
6172 g_assert (*out_config);
6174 ret = NM_ACT_STAGE_RETURN_SUCCESS;
6176 _LOGW (LOGD_IP6, "unhandled IPv6 config method '%s'; will fail", method);
6178 /* Other methods (shared) aren't implemented yet */
6180 switch (ip6_privacy) {
6181 case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN:
6182 case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
6183 ip6_privacy_str = "0";
6185 case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR:
6186 ip6_privacy_str = "1";
6188 case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR:
6189 ip6_privacy_str = "2";
6192 nm_device_ipv6_sysctl_set (self, "use_tempaddr", ip6_privacy_str);
6198 * nm_device_activate_stage3_ip4_start:
6201 * Try starting IPv4 configuration.
6204 nm_device_activate_stage3_ip4_start (NMDevice *self)
6206 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6207 NMActStageReturn ret;
6208 NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
6209 NMIP4Config *ip4_config = NULL;
6211 g_assert (priv->ip4_state == IP_WAIT);
6213 priv->ip4_state = IP_CONF;
6214 ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip4_config_start (self, &ip4_config, &reason);
6215 if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
6216 g_assert (ip4_config);
6217 nm_device_activate_schedule_ip4_config_result (self, ip4_config);
6218 g_object_unref (ip4_config);
6219 } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
6220 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
6222 } else if (ret == NM_ACT_STAGE_RETURN_STOP) {
6224 priv->ip4_state = IP_FAIL;
6225 } else if (ret == NM_ACT_STAGE_RETURN_WAIT) {
6226 /* Wait for something to try IP config again */
6227 priv->ip4_state = IP_WAIT;
6229 g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE);
6235 * nm_device_activate_stage3_ip6_start:
6238 * Try starting IPv6 configuration.
6241 nm_device_activate_stage3_ip6_start (NMDevice *self)
6243 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6244 NMActStageReturn ret;
6245 NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
6246 NMIP6Config *ip6_config = NULL;
6248 g_assert (priv->ip6_state == IP_WAIT);
6250 priv->ip6_state = IP_CONF;
6251 ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip6_config_start (self, &ip6_config, &reason);
6252 if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
6253 g_assert (ip6_config);
6254 /* Here we get a static IPv6 config, like for Shared where it's
6255 * autogenerated or from modems where it comes from ModemManager.
6257 g_warn_if_fail (priv->ac_ip6_config == NULL);
6258 priv->ac_ip6_config = ip6_config;
6259 nm_device_activate_schedule_ip6_config_result (self);
6260 } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
6261 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
6263 } else if (ret == NM_ACT_STAGE_RETURN_STOP) {
6264 /* Activation not wanted */
6265 priv->ip6_state = IP_FAIL;
6266 } else if (ret == NM_ACT_STAGE_RETURN_FINISH) {
6267 /* Early finish, nothing more to do */
6268 priv->ip6_state = IP_DONE;
6269 check_ip_done (self);
6270 } else if (ret == NM_ACT_STAGE_RETURN_WAIT) {
6271 /* Wait for something to try IP config again */
6272 priv->ip6_state = IP_WAIT;
6274 g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE);
6280 * activate_stage3_ip_config_start
6282 * Begin automatic/manual IP configuration
6286 activate_stage3_ip_config_start (NMDevice *self)
6288 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6289 NMActiveConnection *master;
6290 NMDevice *master_device;
6292 priv->ip4_state = priv->ip6_state = IP_WAIT;
6294 nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE);
6296 /* Device should be up before we can do anything with it */
6297 if (!nm_platform_link_is_up (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self)))
6298 _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
6300 /* If the device is a slave, then we don't do any IP configuration but we
6301 * use the IP config stage to indicate to the master we're ready for
6302 * enslavement. If the master is already activating, it will have tried to
6303 * enslave us when we changed state to IP_CONFIG, causing us to queue a
6304 * transition to SECONDARIES (or FAILED if the enslavement failed), with
6305 * our IP states set to IP_DONE either way. If the master isn't yet
6306 * activating, then they'll still be in IP_WAIT. Either way, we bail out
6307 * of IP config here.
6309 master = nm_active_connection_get_master (NM_ACTIVE_CONNECTION (priv->act_request));
6311 master_device = nm_active_connection_get_device (master);
6312 if (priv->ip4_state == IP_WAIT && priv->ip6_state == IP_WAIT) {
6313 _LOGI (LOGD_DEVICE, "Activation: connection '%s' waiting on master '%s'",
6314 nm_connection_get_id (nm_device_get_applied_connection (self)),
6315 master_device ? nm_device_get_iface (master_device) : "(unknown)");
6321 if ( nm_device_activate_ip4_state_in_wait (self)
6322 && !nm_device_activate_stage3_ip4_start (self))
6326 if ( nm_device_activate_ip6_state_in_wait (self)
6327 && !nm_device_activate_stage3_ip6_start (self))
6330 check_ip_failed (self, TRUE);
6334 fw_change_zone_handle (NMDevice *self,
6335 NMFirewallManagerCallId call_id,
6338 NMDevicePrivate *priv;
6340 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
6342 priv = NM_DEVICE_GET_PRIVATE (self);
6344 g_return_val_if_fail (priv->fw_call == call_id, FALSE);
6345 priv->fw_call = NULL;
6347 return !nm_utils_error_is_cancelled (error, FALSE);
6351 fw_change_zone_cb_stage2 (NMFirewallManager *firewall_manager,
6352 NMFirewallManagerCallId call_id,
6356 NMDevice *self = user_data;
6357 NMDevicePrivate *priv;
6359 if (!fw_change_zone_handle (self, call_id, error))
6362 /* FIXME: fail the device on error? */
6364 priv = NM_DEVICE_GET_PRIVATE (self);
6365 priv->fw_ready = TRUE;
6367 nm_device_activate_schedule_stage3_ip_config_start (self);
6371 fw_change_zone_cb_ip_check (NMFirewallManager *firewall_manager,
6372 NMFirewallManagerCallId call_id,
6376 NMDevice *self = user_data;
6378 if (!fw_change_zone_handle (self, call_id, error))
6381 /* FIXME: fail the device on error? */
6382 nm_device_start_ip_check (self);
6386 * nm_device_activate_schedule_stage3_ip_config_start
6388 * Schedule IP configuration start
6391 nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self)
6393 NMDevicePrivate *priv;
6394 NMConnection *connection;
6395 NMSettingConnection *s_con = NULL;
6398 g_return_if_fail (NM_IS_DEVICE (self));
6400 priv = NM_DEVICE_GET_PRIVATE (self);
6401 g_return_if_fail (priv->act_request);
6403 /* Add the interface to the specified firewall zone */
6404 connection = nm_device_get_applied_connection (self);
6405 g_assert (connection);
6406 s_con = nm_connection_get_setting_connection (connection);
6408 if (!priv->fw_ready) {
6409 if (nm_device_uses_assumed_connection (self))
6410 priv->fw_ready = TRUE;
6412 if (!priv->fw_call) {
6413 zone = nm_setting_connection_get_zone (s_con);
6415 _LOGD (LOGD_DEVICE, "Activation: setting firewall zone '%s'", zone ? zone : "default");
6416 priv->fw_call = nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
6417 nm_device_get_ip_iface (self),
6420 fw_change_zone_cb_stage2,
6427 activation_source_schedule (self, activate_stage3_ip_config_start, AF_INET);
6430 static NMActStageReturn
6431 act_stage4_ip4_config_timeout (NMDevice *self, NMDeviceStateReason *reason)
6433 if (!get_ip_config_may_fail (self, AF_INET)) {
6434 *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
6435 return NM_ACT_STAGE_RETURN_FAILURE;
6437 return NM_ACT_STAGE_RETURN_SUCCESS;
6442 * nm_device_activate_stage4_ip4_config_timeout
6444 * Time out on retrieving the IPv4 config.
6448 activate_stage4_ip4_config_timeout (NMDevice *self)
6450 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6451 NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
6452 NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
6454 ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip4_config_timeout (self, &reason);
6455 if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
6457 else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
6458 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
6461 g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
6463 priv->ip4_state = IP_FAIL;
6465 check_ip_failed (self, FALSE);
6470 * nm_device_activate_schedule_ip4_config_timeout
6472 * Deal with a timeout of the IPv4 configuration
6476 nm_device_activate_schedule_ip4_config_timeout (NMDevice *self)
6478 NMDevicePrivate *priv;
6480 g_return_if_fail (NM_IS_DEVICE (self));
6482 priv = NM_DEVICE_GET_PRIVATE (self);
6483 g_return_if_fail (priv->act_request);
6485 activation_source_schedule (self, activate_stage4_ip4_config_timeout, AF_INET);
6489 static NMActStageReturn
6490 act_stage4_ip6_config_timeout (NMDevice *self, NMDeviceStateReason *reason)
6492 if (!get_ip_config_may_fail (self, AF_INET6)) {
6493 *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
6494 return NM_ACT_STAGE_RETURN_FAILURE;
6497 return NM_ACT_STAGE_RETURN_SUCCESS;
6502 * activate_stage4_ip6_config_timeout
6504 * Time out on retrieving the IPv6 config.
6508 activate_stage4_ip6_config_timeout (NMDevice *self)
6510 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6511 NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
6512 NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
6514 ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip6_config_timeout (self, &reason);
6515 if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
6517 if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
6518 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
6521 g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
6523 priv->ip6_state = IP_FAIL;
6525 check_ip_failed (self, FALSE);
6530 * nm_device_activate_schedule_ip6_config_timeout
6532 * Deal with a timeout of the IPv6 configuration
6536 nm_device_activate_schedule_ip6_config_timeout (NMDevice *self)
6538 NMDevicePrivate *priv;
6540 g_return_if_fail (NM_IS_DEVICE (self));
6542 priv = NM_DEVICE_GET_PRIVATE (self);
6543 g_return_if_fail (priv->act_request);
6545 activation_source_schedule (self, activate_stage4_ip6_config_timeout, AF_INET6);
6551 char *modules[] = { "ip_tables", "iptable_nat", "nf_nat_ftp", "nf_nat_irc",
6552 "nf_nat_sip", "nf_nat_tftp", "nf_nat_pptp", "nf_nat_h323",
6557 if (!nm_platform_sysctl_set (NM_PLATFORM_GET, "/proc/sys/net/ipv4/ip_forward", "1")) {
6559 nm_log_err (LOGD_SHARING, "share: error starting IP forwarding: (%d) %s",
6560 errsv, strerror (errsv));
6564 if (!nm_platform_sysctl_set (NM_PLATFORM_GET, "/proc/sys/net/ipv4/ip_dynaddr", "1")) {
6566 nm_log_err (LOGD_SHARING, "share: error starting IP forwarding: (%d) %s",
6567 errsv, strerror (errsv));
6570 for (iter = modules; *iter; iter++)
6571 nm_utils_modprobe (NULL, FALSE, *iter, NULL);
6577 add_share_rule (NMActRequest *req, const char *table, const char *fmt, ...)
6582 va_start (args, fmt);
6583 cmd = g_strdup_vprintf (fmt, args);
6586 nm_act_request_add_share_rule (req, table, cmd);
6591 start_sharing (NMDevice *self, NMIP4Config *config)
6593 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6595 GError *error = NULL;
6596 char str_addr[INET_ADDRSTRLEN + 1];
6597 char str_mask[INET_ADDRSTRLEN + 1];
6598 guint32 netmask, network;
6599 const NMPlatformIP4Address *ip4_addr;
6600 const char *ip_iface;
6602 g_return_val_if_fail (config != NULL, FALSE);
6604 ip_iface = nm_device_get_ip_iface (self);
6606 ip4_addr = nm_ip4_config_get_address (config, 0);
6607 if (!ip4_addr || !ip4_addr->address)
6610 netmask = nm_utils_ip4_prefix_to_netmask (ip4_addr->plen);
6611 if (!inet_ntop (AF_INET, &netmask, str_mask, sizeof (str_mask)))
6614 network = ip4_addr->address & netmask;
6615 if (!inet_ntop (AF_INET, &network, str_addr, sizeof (str_addr)))
6621 req = nm_device_get_act_request (self);
6624 add_share_rule (req, "nat", "POSTROUTING --source %s/%s ! --destination %s/%s --jump MASQUERADE", str_addr, str_mask, str_addr, str_mask);
6625 add_share_rule (req, "filter", "FORWARD --destination %s/%s --out-interface %s --match state --state ESTABLISHED,RELATED --jump ACCEPT", str_addr, str_mask, ip_iface);
6626 add_share_rule (req, "filter", "FORWARD --source %s/%s --in-interface %s --jump ACCEPT", str_addr, str_mask, ip_iface);
6627 add_share_rule (req, "filter", "FORWARD --in-interface %s --out-interface %s --jump ACCEPT", ip_iface, ip_iface);
6628 add_share_rule (req, "filter", "FORWARD --out-interface %s --jump REJECT", ip_iface);
6629 add_share_rule (req, "filter", "FORWARD --in-interface %s --jump REJECT", ip_iface);
6630 add_share_rule (req, "filter", "INPUT --in-interface %s --protocol udp --destination-port 67 --jump ACCEPT", ip_iface);
6631 add_share_rule (req, "filter", "INPUT --in-interface %s --protocol tcp --destination-port 67 --jump ACCEPT", ip_iface);
6632 add_share_rule (req, "filter", "INPUT --in-interface %s --protocol udp --destination-port 53 --jump ACCEPT", ip_iface);
6633 add_share_rule (req, "filter", "INPUT --in-interface %s --protocol tcp --destination-port 53 --jump ACCEPT", ip_iface);
6635 nm_act_request_set_shared (req, TRUE);
6637 if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, config, &error)) {
6638 _LOGE (LOGD_SHARING, "share: (%s) failed to start dnsmasq: %s",
6639 ip_iface, error->message);
6640 g_error_free (error);
6641 nm_act_request_set_shared (req, FALSE);
6645 priv->dnsmasq_state_id = g_signal_connect (priv->dnsmasq_manager, NM_DNS_MASQ_MANAGER_STATE_CHANGED,
6646 G_CALLBACK (dnsmasq_state_changed_cb),
6652 arp_cleanup (NMDevice *self)
6654 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6656 if (priv->arping.announcing) {
6657 nm_arping_manager_destroy (priv->arping.announcing);
6658 priv->arping.announcing = NULL;
6663 arp_announce (NMDevice *self)
6665 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6666 NMConnection *connection;
6667 NMSettingIPConfig *s_ip4;
6669 const guint8 *hw_addr;
6670 size_t hw_addr_len = 0;
6674 hw_addr = nm_platform_link_get_address (NM_PLATFORM_GET,
6675 nm_device_get_ip_ifindex (self),
6678 if (!hw_addr_len || !hw_addr)
6681 /* We only care about manually-configured addresses; DHCP- and autoip-configured
6682 * ones should already have been seen on the network at this point.
6684 connection = nm_device_get_applied_connection (self);
6687 s_ip4 = nm_connection_get_setting_ip4_config (connection);
6690 num = nm_setting_ip_config_get_num_addresses (s_ip4);
6694 priv->arping.announcing = nm_arping_manager_new (nm_device_get_ip_ifindex (self));
6696 for (i = 0; i < num; i++) {
6697 NMIPAddress *ip = nm_setting_ip_config_get_address (s_ip4, i);
6700 if (inet_pton (AF_INET, nm_ip_address_get_address (ip), &addr) == 1)
6701 nm_arping_manager_add_address (priv->arping.announcing, addr);
6703 g_warn_if_reached ();
6706 nm_arping_manager_announce_addresses (priv->arping.announcing);
6710 activate_stage5_ip4_config_commit (NMDevice *self)
6712 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6715 NMConnection *connection;
6716 NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
6719 req = nm_device_get_act_request (self);
6721 connection = nm_act_request_get_applied_connection (req);
6722 g_assert (connection);
6724 /* Interface must be IFF_UP before IP config can be applied */
6725 ip_ifindex = nm_device_get_ip_ifindex (self);
6726 if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex) && !nm_device_uses_assumed_connection (self)) {
6727 nm_platform_link_set_up (NM_PLATFORM_GET, ip_ifindex, NULL);
6728 if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex))
6729 _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
6732 /* NULL to use the existing priv->dev_ip4_config */
6733 if (!ip4_config_merge_and_apply (self, NULL, TRUE, &reason)) {
6734 _LOGD (LOGD_DEVICE | LOGD_IP4, "Activation: Stage 5 of 5 (IPv4 Commit) failed");
6735 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
6739 /* Start IPv4 sharing if we need it */
6740 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
6742 if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) {
6743 if (!start_sharing (self, priv->ip4_config)) {
6744 _LOGW (LOGD_SHARING, "Activation: Stage 5 of 5 (IPv4 Commit) start sharing failed.");
6745 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
6750 /* If IPv4 wasn't the first to complete, and DHCP was used, then ensure
6751 * dispatcher scripts get the DHCP lease information.
6753 if ( priv->dhcp4_client
6754 && nm_device_activate_ip4_state_in_conf (self)
6755 && (nm_device_get_state (self) > NM_DEVICE_STATE_IP_CONFIG)) {
6756 /* Notify dispatcher scripts of new DHCP4 config */
6757 nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE,
6758 nm_device_get_settings_connection (self),
6759 nm_device_get_applied_connection (self),
6766 arp_announce (self);
6768 nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
6770 /* Enter the IP_CHECK state if this is the first method to complete */
6771 priv->ip4_state = IP_DONE;
6772 check_ip_done (self);
6776 queued_ip4_config_change_clear (NMDevice *self)
6778 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6780 if (priv->queued_ip4_config_id) {
6781 _LOGD (LOGD_DEVICE, "clearing queued IP4 config change");
6782 g_source_remove (priv->queued_ip4_config_id);
6783 priv->queued_ip4_config_id = 0;
6788 queued_ip6_config_change_clear (NMDevice *self)
6790 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6792 if (priv->queued_ip6_config_id) {
6793 _LOGD (LOGD_DEVICE, "clearing queued IP6 config change");
6794 g_source_remove (priv->queued_ip6_config_id);
6795 priv->queued_ip6_config_id = 0;
6800 nm_device_activate_schedule_ip4_config_result (NMDevice *self, NMIP4Config *config)
6802 NMDevicePrivate *priv;
6804 g_return_if_fail (NM_IS_DEVICE (self));
6805 priv = NM_DEVICE_GET_PRIVATE (self);
6807 g_clear_object (&priv->dev_ip4_config);
6809 priv->dev_ip4_config = g_object_ref (config);
6811 queued_ip4_config_change_clear (self);
6812 activation_source_schedule (self, activate_stage5_ip4_config_commit, AF_INET);
6816 nm_device_activate_ip4_state_in_conf (NMDevice *self)
6818 g_return_val_if_fail (self != NULL, FALSE);
6819 return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_CONF;
6823 nm_device_activate_ip4_state_in_wait (NMDevice *self)
6825 g_return_val_if_fail (self != NULL, FALSE);
6826 return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT;
6830 activate_stage5_ip6_config_commit (NMDevice *self)
6832 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6834 NMConnection *connection;
6835 NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
6838 req = nm_device_get_act_request (self);
6840 connection = nm_act_request_get_applied_connection (req);
6841 g_assert (connection);
6843 /* Interface must be IFF_UP before IP config can be applied */
6844 ip_ifindex = nm_device_get_ip_ifindex (self);
6845 if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex) && !nm_device_uses_assumed_connection (self)) {
6846 nm_platform_link_set_up (NM_PLATFORM_GET, ip_ifindex, NULL);
6847 if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex))
6848 _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
6851 if (ip6_config_merge_and_apply (self, TRUE, &reason)) {
6852 if ( priv->dhcp6_mode != NM_RDISC_DHCP_LEVEL_NONE
6853 && priv->ip6_state == IP_CONF) {
6854 if (priv->dhcp6_ip6_config) {
6855 /* If IPv6 wasn't the first IP to complete, and DHCP was used,
6856 * then ensure dispatcher scripts get the DHCP lease information.
6858 nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE,
6859 nm_device_get_settings_connection (self),
6860 nm_device_get_applied_connection (self),
6866 /* still waiting for first dhcp6 lease. */
6871 nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
6872 nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE);
6874 /* Enter the IP_CHECK state if this is the first method to complete */
6875 priv->ip6_state = IP_DONE;
6876 check_ip_done (self);
6878 _LOGW (LOGD_DEVICE | LOGD_IP6, "Activation: Stage 5 of 5 (IPv6 Commit) failed");
6879 nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
6884 nm_device_activate_schedule_ip6_config_result (NMDevice *self)
6886 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6888 g_return_if_fail (NM_IS_DEVICE (self));
6890 /* If IP had previously failed, move it back to IP_CONF since we
6891 * clearly now have configuration.
6893 if (priv->ip6_state == IP_FAIL)
6894 priv->ip6_state = IP_CONF;
6896 activation_source_schedule (self, activate_stage5_ip6_config_commit, AF_INET6);
6900 nm_device_activate_ip6_state_in_conf (NMDevice *self)
6902 g_return_val_if_fail (self != NULL, FALSE);
6903 return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_CONF;
6907 nm_device_activate_ip6_state_in_wait (NMDevice *self)
6909 g_return_val_if_fail (self != NULL, FALSE);
6910 return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT;
6914 clear_act_request (NMDevice *self)
6916 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6918 if (!priv->act_request)
6921 nm_active_connection_set_default (NM_ACTIVE_CONNECTION (priv->act_request), FALSE);
6923 priv->master_ready_handled = FALSE;
6924 nm_clear_g_signal_handler (priv->act_request, &priv->master_ready_id);
6926 g_clear_object (&priv->act_request);
6927 _notify (self, PROP_ACTIVE_CONNECTION);
6931 dnsmasq_cleanup (NMDevice *self)
6933 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6935 if (!priv->dnsmasq_manager)
6938 nm_clear_g_signal_handler (priv->dnsmasq_manager, &priv->dnsmasq_state_id);
6940 nm_dnsmasq_manager_stop (priv->dnsmasq_manager);
6941 g_object_unref (priv->dnsmasq_manager);
6942 priv->dnsmasq_manager = NULL;
6946 _update_ip4_address (NMDevice *self)
6948 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
6951 g_return_if_fail (NM_IS_DEVICE (self));
6953 if ( priv->ip4_config
6954 && ip_config_valid (priv->state)
6955 && nm_ip4_config_get_num_addresses (priv->ip4_config)) {
6956 addr = nm_ip4_config_get_address (priv->ip4_config, 0)->address;
6957 if (addr != priv->ip4_address) {
6958 priv->ip4_address = addr;
6959 _notify (self, PROP_IP4_ADDRESS);
6965 nm_device_get_is_nm_owned (NMDevice *self)
6967 return NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
6971 * delete_on_deactivate_link_delete
6973 * Function will be queued with g_idle_add to call
6974 * nm_platform_link_delete for the underlying resources
6978 delete_on_deactivate_link_delete (gpointer user_data)
6980 DeleteOnDeactivateData *data = user_data;
6981 NMDevice *self = data->device;
6983 _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)",
6984 data->ifindex, data->idle_add_id);
6987 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (data->device);
6988 gs_free_error GError *error = NULL;
6990 g_object_remove_weak_pointer (G_OBJECT (data->device), (void **) &data->device);
6991 priv->delete_on_deactivate_data = NULL;
6993 if (!nm_device_unrealize (data->device, TRUE, &error))
6994 _LOGD (LOGD_DEVICE, "delete_on_deactivate: unrealizing %d failed (%s)", data->ifindex, error->message);
6996 nm_platform_link_delete (NM_PLATFORM_GET, data->ifindex);
7003 delete_on_deactivate_unschedule (NMDevice *self)
7005 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7007 if (priv->delete_on_deactivate_data) {
7008 DeleteOnDeactivateData *data = priv->delete_on_deactivate_data;
7010 priv->delete_on_deactivate_data = NULL;
7012 g_source_remove (data->idle_add_id);
7013 g_object_remove_weak_pointer (G_OBJECT (self), (void **) &data->device);
7014 _LOGD (LOGD_DEVICE, "delete_on_deactivate: cancel cleanup and delete virtual link #%d (id=%u)",
7015 data->ifindex, data->idle_add_id);
7021 delete_on_deactivate_check_and_schedule (NMDevice *self, int ifindex)
7023 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7024 DeleteOnDeactivateData *data;
7028 if (!priv->is_nm_owned)
7030 if (priv->queued_act_request)
7032 if (!nm_device_is_software (self) || !nm_device_is_real (self))
7034 if (nm_device_get_state (self) == NM_DEVICE_STATE_UNMANAGED)
7036 if (nm_device_get_state (self) == NM_DEVICE_STATE_UNAVAILABLE)
7038 delete_on_deactivate_unschedule (self); /* always cancel and reschedule */
7040 data = g_new (DeleteOnDeactivateData, 1);
7041 g_object_add_weak_pointer (G_OBJECT (self), (void **) &data->device);
7042 data->device = self;
7043 data->ifindex = ifindex;
7044 data->idle_add_id = g_idle_add (delete_on_deactivate_link_delete, data);
7045 priv->delete_on_deactivate_data = data;
7047 _LOGD (LOGD_DEVICE, "delete_on_deactivate: schedule cleanup and delete virtual link #%d (id=%u)",
7048 ifindex, data->idle_add_id);
7052 _cleanup_ip4_pre (NMDevice *self, CleanupType cleanup_type)
7054 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7056 priv->ip4_state = IP_NONE;
7057 queued_ip4_config_change_clear (self);
7059 dhcp4_cleanup (self, cleanup_type, FALSE);
7061 dnsmasq_cleanup (self);
7062 ipv4ll_cleanup (self);
7066 _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type)
7068 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7070 priv->ip6_state = IP_NONE;
7071 queued_ip6_config_change_clear (self);
7073 dhcp6_cleanup (self, cleanup_type, FALSE);
7074 linklocal6_cleanup (self);
7075 addrconf6_cleanup (self);
7079 _hash_check_invalid_keys_impl (GHashTable *hash, const char *setting_name, GError **error, const char **argv)
7081 guint found_keys = 0;
7084 nm_assert (argv && argv[0]);
7086 #if NM_MORE_ASSERTS > 10
7087 /* Assert that the keys are unique. */
7089 gs_unref_hashtable GHashTable *check_dups = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
7091 for (i = 0; argv[i]; i++) {
7092 if (!g_hash_table_add (check_dups, (char *) argv[i]))
7095 nm_assert (g_hash_table_size (check_dups) > 0);
7099 if (!hash || g_hash_table_size (hash) == 0)
7102 for (i = 0; argv[i]; i++) {
7103 if (g_hash_table_contains (hash, argv[i]))
7107 if (found_keys != g_hash_table_size (hash)) {
7108 GHashTableIter iter;
7109 const char *k = NULL;
7110 const char *first_invalid_key = NULL;
7115 g_hash_table_iter_init (&iter, hash);
7116 while (g_hash_table_iter_next (&iter, (gpointer *) &k, NULL)) {
7117 for (i = 0; argv[i]; i++) {
7118 if (!strcmp (argv[i], k)) {
7119 first_invalid_key = k;
7123 if (first_invalid_key)
7128 NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
7129 "Can't reapply changes to '%s%s%s' setting",
7130 setting_name ? : "",
7131 setting_name ? "." : "",
7132 first_invalid_key ? : "<UNKNOWN>");
7133 g_return_val_if_fail (first_invalid_key, FALSE);
7139 #define _hash_check_invalid_keys(hash, setting_name, error, ...) _hash_check_invalid_keys_impl (hash, setting_name, error, ((const char *[]) { __VA_ARGS__, NULL }))
7142 nm_device_reactivate_ip4_config (NMDevice *self,
7143 NMSettingIPConfig *s_ip4_old,
7144 NMSettingIPConfig *s_ip4_new)
7146 NMDevicePrivate *priv;
7148 g_return_if_fail (NM_IS_DEVICE (self));
7149 priv = NM_DEVICE_GET_PRIVATE (self);
7151 if (priv->ip4_state != IP_NONE) {
7152 g_clear_object (&priv->con_ip4_config);
7153 g_clear_object (&priv->ext_ip4_config);
7154 priv->con_ip4_config = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
7155 nm_ip4_config_merge_setting (priv->con_ip4_config,
7157 nm_device_get_ip4_route_metric (self));
7159 if (strcmp (nm_setting_ip_config_get_method (s_ip4_new),
7160 nm_setting_ip_config_get_method (s_ip4_old))) {
7161 _cleanup_ip4_pre (self, CLEANUP_TYPE_DECONFIGURE);
7162 priv->ip4_state = IP_WAIT;
7163 if (!nm_device_activate_stage3_ip4_start (self))
7164 _LOGW (LOGD_IP4, "Failed to apply IPv4 configuration");
7166 if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL))
7167 _LOGW (LOGD_IP4, "Failed to reapply IPv4 configuration");
7173 nm_device_reactivate_ip6_config (NMDevice *self,
7174 NMSettingIPConfig *s_ip6_old,
7175 NMSettingIPConfig *s_ip6_new)
7177 NMDevicePrivate *priv;
7179 g_return_if_fail (NM_IS_DEVICE (self));
7180 priv = NM_DEVICE_GET_PRIVATE (self);
7182 if (priv->ip6_state != IP_NONE) {
7183 g_clear_object (&priv->con_ip6_config);
7184 g_clear_object (&priv->ext_ip6_config);
7185 priv->con_ip6_config = nm_ip6_config_new (nm_device_get_ip_ifindex (self));
7186 nm_ip6_config_merge_setting (priv->con_ip6_config,
7188 nm_device_get_ip6_route_metric (self));
7190 if (strcmp (nm_setting_ip_config_get_method (s_ip6_new),
7191 nm_setting_ip_config_get_method (s_ip6_old))) {
7192 _cleanup_ip6_pre (self, CLEANUP_TYPE_DECONFIGURE);
7193 priv->ip6_state = IP_WAIT;
7194 if (!nm_device_activate_stage3_ip6_start (self))
7195 _LOGW (LOGD_IP6, "Failed to apply IPv6 configuration");
7197 if (!ip6_config_merge_and_apply (self, TRUE, NULL))
7198 _LOGW (LOGD_IP4, "Failed to reapply IPv6 configuration");
7204 /* reapply_connection:
7205 * @connection: the new connection settings to be applied or %NULL to reapply
7206 * the current settings connection
7207 * @version_id: either zero, or the current version id for the applied
7209 * @error: the error if %FALSE is returned
7211 * Change configuration of an already configured device if possible.
7212 * Updates the device's applied connection upon success.
7214 * Return: %FALSE if the new configuration can not be reapplied.
7217 reapply_connection (NMDevice *self,
7218 NMConnection *connection,
7222 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7223 NMConnection *applied = nm_device_get_applied_connection (self);
7224 gs_unref_object NMConnection *applied_clone = NULL;
7225 gs_unref_hashtable GHashTable *diffs = NULL;
7226 NMConnection *con_old, *con_new;
7227 NMSettingIPConfig *s_ip4_old, *s_ip4_new;
7228 NMSettingIPConfig *s_ip6_old, *s_ip6_new;
7230 if (priv->state != NM_DEVICE_STATE_ACTIVATED) {
7231 g_set_error_literal (error,
7233 NM_DEVICE_ERROR_NOT_ACTIVE,
7234 "Device is not activated");
7238 nm_connection_diff (connection,
7240 NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP |
7241 NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS,
7244 /**************************************************************************
7245 * check for unsupported changes and reject to reapply
7246 *************************************************************************/
7247 if (!_hash_check_invalid_keys (diffs, NULL, error,
7248 NM_SETTING_IP4_CONFIG_SETTING_NAME,
7249 NM_SETTING_IP6_CONFIG_SETTING_NAME,
7250 NM_SETTING_CONNECTION_SETTING_NAME))
7253 if (!_hash_check_invalid_keys (diffs ? g_hash_table_lookup (diffs, NM_SETTING_CONNECTION_SETTING_NAME) : NULL,
7254 NM_SETTING_CONNECTION_SETTING_NAME,
7256 NM_SETTING_CONNECTION_ZONE,
7257 NM_SETTING_CONNECTION_METERED))
7260 if ( version_id != 0
7261 && version_id != nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request)) {
7262 g_set_error_literal (error,
7264 NM_DEVICE_ERROR_VERSION_ID_MISMATCH,
7265 "Reapply failed because device changed in the meantime and the version-id mismatches");
7269 /**************************************************************************
7270 * Update applied connection
7271 *************************************************************************/
7274 nm_active_connection_version_id_bump ((NMActiveConnection *) priv->act_request);
7276 _LOGD (LOGD_DEVICE, "reapply (version-id %llu%s)",
7277 (long long unsigned) nm_active_connection_version_id_get (((NMActiveConnection *) priv->act_request)),
7278 diffs ? "" : " (unmodified)");
7281 con_old = applied_clone = nm_simple_connection_new_clone (applied);
7283 nm_connection_replace_settings_from_connection (applied, connection);
7285 con_old = con_new = applied;
7287 s_ip4_new = nm_connection_get_setting_ip4_config (con_new);
7288 s_ip4_old = nm_connection_get_setting_ip4_config (con_old);
7289 s_ip6_new = nm_connection_get_setting_ip6_config (con_new);
7290 s_ip6_old = nm_connection_get_setting_ip6_config (con_old);
7292 /**************************************************************************
7294 *************************************************************************/
7296 nm_device_update_firewall_zone (self);
7297 nm_device_update_metered (self);
7299 nm_device_reactivate_ip4_config (self, s_ip4_old, s_ip4_new);
7300 nm_device_reactivate_ip6_config (self, s_ip6_old, s_ip6_new);
7306 NMConnection *connection;
7311 reapply_cb (NMDevice *self,
7312 GDBusMethodInvocation *context,
7313 NMAuthSubject *subject,
7317 ReapplyData *reapply_data = user_data;
7318 guint64 version_id = 0;
7319 gs_unref_object NMConnection *connection = NULL;
7320 GError *local = NULL;
7323 connection = reapply_data->connection;
7324 version_id = reapply_data->version_id;
7325 g_slice_free (ReapplyData, reapply_data);
7329 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, subject, error->message);
7330 g_dbus_method_invocation_return_gerror (context, error);
7334 if (!reapply_connection (self,
7335 connection ? : (NMConnection *) nm_device_get_settings_connection (self),
7338 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, subject, local->message);
7339 g_dbus_method_invocation_take_error (context, local);
7342 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, TRUE, subject, NULL);
7343 g_dbus_method_invocation_return_value (context, NULL);
7348 impl_device_reapply (NMDevice *self,
7349 GDBusMethodInvocation *context,
7354 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7355 NMSettingsConnection *settings_connection;
7356 NMConnection *connection = NULL;
7357 GError *error = NULL;
7358 ReapplyData *reapply_data;
7360 /* No flags supported as of now. */
7362 error = g_error_new_literal (NM_DEVICE_ERROR,
7363 NM_DEVICE_ERROR_FAILED,
7364 "Invalid flags specified");
7365 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message);
7366 g_dbus_method_invocation_take_error (context, error);
7370 if (priv->state != NM_DEVICE_STATE_ACTIVATED) {
7371 error = g_error_new_literal (NM_DEVICE_ERROR,
7372 NM_DEVICE_ERROR_NOT_ACTIVE,
7373 "Device is not activated");
7374 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message);
7375 g_dbus_method_invocation_take_error (context, error);
7379 settings_connection = nm_device_get_settings_connection (self);
7380 g_return_if_fail (settings_connection);
7382 if (settings && g_variant_n_children (settings)) {
7383 /* New settings specified inline. */
7384 connection = _nm_simple_connection_new_from_dbus (settings,
7385 NM_SETTING_PARSE_FLAGS_STRICT
7386 | NM_SETTING_PARSE_FLAGS_NORMALIZE,
7389 g_prefix_error (&error, "The settings specified are invalid: ");
7390 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message);
7391 g_dbus_method_invocation_take_error (context, error);
7394 nm_connection_clear_secrets (connection);
7397 if (connection || version_id) {
7398 reapply_data = g_slice_new (ReapplyData);
7399 reapply_data->connection = connection;
7400 reapply_data->version_id = version_id;
7402 reapply_data = NULL;
7404 /* Ask the manager to authenticate this request for us */
7405 g_signal_emit (self, signals[AUTH_REQUEST], 0,
7407 nm_device_get_applied_connection (self),
7408 NM_AUTH_PERMISSION_NETWORK_CONTROL,
7414 /*****************************************************************************/
7417 get_applied_connection_cb (NMDevice *self,
7418 GDBusMethodInvocation *context,
7419 NMAuthSubject *subject,
7421 gpointer user_data /* possibly dangling pointer */)
7423 NMDevicePrivate *priv;
7424 NMConnection *applied_connection;
7427 g_return_if_fail (NM_IS_DEVICE (self));
7430 g_dbus_method_invocation_return_gerror (context, error);
7434 priv = NM_DEVICE_GET_PRIVATE (self);
7436 applied_connection = nm_device_get_applied_connection (self);
7438 if (!applied_connection) {
7439 error = g_error_new_literal (NM_DEVICE_ERROR,
7440 NM_DEVICE_ERROR_NOT_ACTIVE,
7441 "Device is not activated");
7442 g_dbus_method_invocation_take_error (context, error);
7446 if (applied_connection != user_data) {
7447 /* The applied connection changed due to a race. Reauthenticate. */
7448 g_signal_emit (self, signals[AUTH_REQUEST], 0,
7451 NM_AUTH_PERMISSION_NETWORK_CONTROL,
7453 get_applied_connection_cb,
7454 applied_connection /* no need take a ref. We will not dereference this pointer. */);
7458 settings = nm_connection_to_dbus (applied_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS);
7460 settings = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
7462 g_dbus_method_invocation_return_value (context,
7463 g_variant_new ("(@a{sa{sv}}t)",
7465 nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request)));
7469 impl_device_get_applied_connection (NMDevice *self,
7470 GDBusMethodInvocation *context,
7473 NMConnection *applied_connection;
7474 GError *error = NULL;
7476 g_return_if_fail (NM_IS_DEVICE (self));
7478 /* No flags supported as of now. */
7480 error = g_error_new_literal (NM_DEVICE_ERROR,
7481 NM_DEVICE_ERROR_FAILED,
7482 "Invalid flags specified");
7483 g_dbus_method_invocation_take_error (context, error);
7487 applied_connection = nm_device_get_applied_connection (self);
7488 if (!applied_connection) {
7489 error = g_error_new_literal (NM_DEVICE_ERROR,
7490 NM_DEVICE_ERROR_NOT_ACTIVE,
7491 "Device is not activated");
7492 g_dbus_method_invocation_take_error (context, error);
7496 /* Ask the manager to authenticate this request for us */
7497 g_signal_emit (self, signals[AUTH_REQUEST], 0,
7500 NM_AUTH_PERMISSION_NETWORK_CONTROL,
7502 get_applied_connection_cb,
7503 applied_connection /* no need take a ref. We will not dereference this pointer. */);
7506 /*****************************************************************************/
7509 disconnect_cb (NMDevice *self,
7510 GDBusMethodInvocation *context,
7511 NMAuthSubject *subject,
7515 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7516 GError *local = NULL;
7519 g_dbus_method_invocation_return_gerror (context, error);
7520 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, subject, error->message);
7525 if (priv->state <= NM_DEVICE_STATE_DISCONNECTED) {
7526 local = g_error_new_literal (NM_DEVICE_ERROR,
7527 NM_DEVICE_ERROR_NOT_ACTIVE,
7528 "Device is not active");
7529 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, subject, local->message);
7530 g_dbus_method_invocation_take_error (context, local);
7532 nm_device_set_autoconnect (self, FALSE);
7534 nm_device_state_changed (self,
7535 NM_DEVICE_STATE_DEACTIVATING,
7536 NM_DEVICE_STATE_REASON_USER_REQUESTED);
7537 g_dbus_method_invocation_return_value (context, NULL);
7538 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, TRUE, subject, NULL);
7543 _clear_queued_act_request (NMDevicePrivate *priv)
7545 if (priv->queued_act_request) {
7546 nm_active_connection_set_state ((NMActiveConnection *) priv->queued_act_request, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
7547 g_clear_object (&priv->queued_act_request);
7552 impl_device_disconnect (NMDevice *self, GDBusMethodInvocation *context)
7554 NMConnection *connection;
7555 GError *error = NULL;
7557 if (NM_DEVICE_GET_PRIVATE (self)->act_request == NULL) {
7558 error = g_error_new_literal (NM_DEVICE_ERROR,
7559 NM_DEVICE_ERROR_NOT_ACTIVE,
7560 "This device is not active");
7561 g_dbus_method_invocation_take_error (context, error);
7565 connection = nm_device_get_applied_connection (self);
7566 g_assert (connection);
7568 /* Ask the manager to authenticate this request for us */
7569 g_signal_emit (self, signals[AUTH_REQUEST], 0,
7572 NM_AUTH_PERMISSION_NETWORK_CONTROL,
7579 delete_cb (NMDevice *self,
7580 GDBusMethodInvocation *context,
7581 NMAuthSubject *subject,
7585 GError *local = NULL;
7588 g_dbus_method_invocation_return_gerror (context, error);
7589 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, FALSE, subject, error->message);
7594 nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, TRUE, subject, NULL);
7595 if (nm_device_unrealize (self, TRUE, &local))
7596 g_dbus_method_invocation_return_value (context, NULL);
7598 g_dbus_method_invocation_take_error (context, local);
7602 impl_device_delete (NMDevice *self, GDBusMethodInvocation *context)
7604 GError *error = NULL;
7606 if (!nm_device_is_software (self) || !nm_device_is_real (self)) {
7607 error = g_error_new_literal (NM_DEVICE_ERROR,
7608 NM_DEVICE_ERROR_NOT_SOFTWARE,
7609 "This device is not a software device or is not realized");
7610 g_dbus_method_invocation_take_error (context, error);
7614 /* Ask the manager to authenticate this request for us */
7615 g_signal_emit (self, signals[AUTH_REQUEST], 0,
7618 NM_AUTH_PERMISSION_NETWORK_CONTROL,
7625 _device_activate (NMDevice *self, NMActRequest *req)
7627 NMDevicePrivate *priv;
7628 NMConnection *connection;
7630 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
7631 g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
7632 g_return_val_if_fail (nm_device_get_managed (self, FALSE), FALSE);
7634 /* Ensure the activation request is still valid; the master may have
7635 * already failed in which case activation of this device should not proceed.
7637 if (nm_active_connection_get_state (NM_ACTIVE_CONNECTION (req)) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING)
7640 priv = NM_DEVICE_GET_PRIVATE (self);
7642 connection = nm_act_request_get_applied_connection (req);
7643 g_assert (connection);
7645 _LOGI (LOGD_DEVICE, "Activation: starting connection '%s' (%s)",
7646 nm_connection_get_id (connection),
7647 nm_connection_get_uuid (connection));
7649 delete_on_deactivate_unschedule (self);
7651 /* note: don't notify D-Bus of the new AC here, but do it later when
7652 * changing state to PREPARE so that the two properties change together.
7654 priv->act_request = g_object_ref (req);
7656 nm_device_activate_schedule_stage1_device_prepare (self);
7661 _carrier_wait_check_queued_act_request (NMDevice *self)
7663 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7664 NMActRequest *queued_req;
7666 if ( !priv->queued_act_request
7667 || !priv->queued_act_request_is_waiting_for_carrier)
7670 priv->queued_act_request_is_waiting_for_carrier = FALSE;
7671 if (!priv->carrier) {
7672 _LOGD (LOGD_DEVICE, "Cancel queued activation request as we have no carrier after timeout");
7673 _clear_queued_act_request (priv);
7675 _LOGD (LOGD_DEVICE, "Activate queued activation request as we now have carrier");
7676 queued_req = priv->queued_act_request;
7677 priv->queued_act_request = NULL;
7678 _device_activate (self, queued_req);
7679 g_object_unref (queued_req);
7684 _carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req)
7686 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7687 NMConnection *connection;
7689 /* If we have carrier or if we are not waiting for it, the activation
7690 * request is not blocked waiting for carrier. */
7693 if (priv->carrier_wait_id == 0)
7696 connection = nm_act_request_get_applied_connection (req);
7697 if (!connection_requires_carrier (connection))
7700 if (!nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL, NULL)) {
7701 /* We passed all @flags we have, and no @specific_object.
7702 * This equals maximal availability, if a connection is not available
7703 * in this case, it is not waiting for carrier.
7705 * Actually, why are we even trying to activate it? Strange, but whatever
7706 * the reason, don't wait for carrier.
7711 if (nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL & ~_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER, NULL)) {
7712 /* The connection was available with flags ALL, and it is still available
7713 * if we pretend not to wait for carrier. That means that the
7714 * connection is available now, and does not wait for carrier.
7716 * Since the flags increase the availability of a connection, when checking
7717 * ALL&~WAITING_CARRIER, it means that we certainly would wait for carrier. */
7721 /* The activation request must wait for carrier. */
7726 nm_device_steal_connection (NMDevice *self, NMSettingsConnection *connection)
7728 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7730 _LOGW (LOGD_DEVICE, "disconnecting connection '%s' for new activation request.",
7731 nm_settings_connection_get_id (connection));
7733 if ( priv->queued_act_request
7734 && connection == nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (priv->queued_act_request)))
7735 _clear_queued_act_request (priv);
7737 if ( priv->act_request
7738 && connection == nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (priv->act_request))
7739 && priv->state < NM_DEVICE_STATE_DEACTIVATING)
7740 nm_device_state_changed (self,
7741 NM_DEVICE_STATE_DEACTIVATING,
7742 NM_DEVICE_STATE_REASON_NEW_ACTIVATION);
7746 nm_device_queue_activation (NMDevice *self, NMActRequest *req)
7748 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7749 gboolean must_queue;
7751 must_queue = _carrier_wait_check_act_request_must_queue (self, req);
7753 if (!priv->act_request && !must_queue && nm_device_is_real (self)) {
7754 /* Just activate immediately */
7755 if (!_device_activate (self, req))
7756 g_assert_not_reached ();
7760 /* supercede any already-queued request */
7761 _clear_queued_act_request (priv);
7762 priv->queued_act_request = g_object_ref (req);
7763 priv->queued_act_request_is_waiting_for_carrier = must_queue;
7765 _LOGD (LOGD_DEVICE, "queue activation request waiting for %s", must_queue ? "carrier" : "currently active connection to disconnect");
7767 /* Deactivate existing activation request first */
7768 if (priv->act_request) {
7769 _LOGI (LOGD_DEVICE, "disconnecting for new activation request.");
7770 nm_device_state_changed (self,
7771 NM_DEVICE_STATE_DEACTIVATING,
7772 NM_DEVICE_STATE_REASON_NEW_ACTIVATION);
7777 * nm_device_is_activating
7779 * Return whether or not the device is currently activating itself.
7783 nm_device_is_activating (NMDevice *self)
7785 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7786 NMDeviceState state;
7788 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
7790 state = nm_device_get_state (self);
7791 if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_SECONDARIES)
7794 /* There's a small race between the time when stage 1 is scheduled
7795 * and when the device actually sets STATE_PREPARE when the activation
7796 * handler is actually run. If there's an activation handler scheduled
7797 * we're activating anyway.
7799 return priv->act_handle4.id ? TRUE : FALSE;
7802 /* IP Configuration stuff */
7805 nm_device_get_dhcp4_config (NMDevice *self)
7807 g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
7809 return NM_DEVICE_GET_PRIVATE (self)->dhcp4_config;
7813 nm_device_get_ip4_config (NMDevice *self)
7815 g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
7817 return NM_DEVICE_GET_PRIVATE (self)->ip4_config;
7822 nm_device_set_ip4_config (NMDevice *self,
7823 NMIP4Config *new_config,
7824 guint32 default_route_metric,
7826 gboolean routes_full_sync,
7827 NMDeviceStateReason *reason)
7829 NMDevicePrivate *priv;
7830 NMIP4Config *old_config = NULL;
7831 gboolean has_changes = FALSE;
7832 gboolean success = TRUE;
7833 NMDeviceStateReason reason_local = NM_DEVICE_STATE_REASON_NONE;
7834 int ip_ifindex, config_ifindex;
7836 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
7838 priv = NM_DEVICE_GET_PRIVATE (self);
7839 ip_ifindex = nm_device_get_ip_ifindex (self);
7842 config_ifindex = nm_ip4_config_get_ifindex (new_config);
7843 if (config_ifindex > 0)
7844 g_return_val_if_fail (ip_ifindex == config_ifindex, FALSE);
7847 old_config = priv->ip4_config;
7849 /* Always commit to nm-platform to update lifetimes */
7850 if (commit && new_config) {
7851 gboolean assumed = nm_device_uses_assumed_connection (self);
7853 nm_device_set_mtu (self, nm_ip4_config_get_mtu (new_config));
7855 /* For assumed devices we must not touch the kernel-routes, such as the device-route.
7856 * FIXME: this is wrong in case where "assumed" means "take-over-seamlessly". In this
7857 * case, we should manage the device route, for example on new DHCP lease. */
7858 success = nm_ip4_config_commit (new_config, ip_ifindex,
7860 assumed ? (gint64) -1 : (gint64) default_route_metric);
7862 reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
7867 /* has_changes is set only on relevant changes, because when the configuration changes,
7868 * this causes a re-read and reset. This should only happen for relevant changes */
7869 nm_ip4_config_replace (old_config, new_config, &has_changes);
7871 _LOGD (LOGD_IP4, "update IP4Config instance (%s)",
7872 nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
7876 priv->ip4_config = g_object_ref (new_config);
7878 if (success && !nm_exported_object_is_exported (NM_EXPORTED_OBJECT (new_config)))
7879 nm_exported_object_export (NM_EXPORTED_OBJECT (new_config));
7881 _LOGD (LOGD_IP4, "set IP4Config instance (%s)",
7882 nm_exported_object_get_path (NM_EXPORTED_OBJECT (new_config)));
7884 } else if (old_config) {
7886 priv->ip4_config = NULL;
7887 _LOGD (LOGD_IP4, "clear IP4Config instance (%s)",
7888 nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
7889 /* Device config is invalid if combined config is invalid */
7890 g_clear_object (&priv->dev_ip4_config);
7893 nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self);
7896 _update_ip4_address (self);
7898 if (old_config != priv->ip4_config)
7899 _notify (self, PROP_IP4_CONFIG);
7900 g_signal_emit (self, signals[IP4_CONFIG_CHANGED], 0, priv->ip4_config, old_config);
7902 if (old_config != priv->ip4_config)
7903 nm_exported_object_clear_and_unexport (&old_config);
7905 if (nm_device_uses_generated_assumed_connection (self)) {
7906 NMConnection *connection = nm_device_get_applied_connection (self);
7907 NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (self));
7910 g_object_freeze_notify (G_OBJECT (connection));
7911 g_object_freeze_notify (G_OBJECT (settings_connection));
7913 nm_connection_remove_setting (settings_connection, NM_TYPE_SETTING_IP4_CONFIG);
7914 s_ip4 = nm_ip4_config_create_setting (priv->ip4_config);
7915 nm_connection_add_setting (settings_connection, s_ip4);
7917 nm_connection_remove_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
7918 s_ip4 = nm_ip4_config_create_setting (priv->ip4_config);
7919 nm_connection_add_setting (connection, s_ip4);
7921 g_object_thaw_notify (G_OBJECT (settings_connection));
7922 g_object_thaw_notify (G_OBJECT (connection));
7925 nm_device_queue_recheck_assume (self);
7929 *reason = reason_local;
7935 _replace_vpn_config_in_list (GSList **plist, GObject *old, GObject *new)
7939 /* Below, assert that @new is not yet tracked, but still behave
7940 * correctly in any case. Don't complain for missing @old since
7941 * it could have been removed when the parent device became
7945 && (old_link = g_slist_find (*plist, old))) {
7948 old_link->data = g_object_ref (new);
7950 *plist = g_slist_delete_link (*plist, old_link);
7951 g_object_unref (old);
7957 if (!g_slist_find (*plist, new))
7958 *plist = g_slist_append (*plist, g_object_ref (new));
7960 g_return_val_if_reached (TRUE);
7968 nm_device_replace_vpn4_config (NMDevice *self, NMIP4Config *old, NMIP4Config *config)
7970 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7972 if (!_replace_vpn_config_in_list (&priv->vpn4_configs, (GObject *) old, (GObject *) config))
7975 /* NULL to use existing configs */
7976 if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL))
7977 _LOGW (LOGD_IP4, "failed to set VPN routes for device");
7981 nm_device_set_wwan_ip4_config (NMDevice *self, NMIP4Config *config)
7983 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
7985 if (priv->wwan_ip4_config == config)
7988 g_clear_object (&priv->wwan_ip4_config);
7990 priv->wwan_ip4_config = g_object_ref (config);
7992 /* NULL to use existing configs */
7993 if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL))
7994 _LOGW (LOGD_IP4, "failed to set WWAN IPv4 configuration");
7998 nm_device_set_ip6_config (NMDevice *self,
7999 NMIP6Config *new_config,
8001 gboolean routes_full_sync,
8002 NMDeviceStateReason *reason)
8004 NMDevicePrivate *priv;
8005 NMIP6Config *old_config = NULL;
8006 gboolean has_changes = FALSE;
8007 gboolean success = TRUE;
8008 NMDeviceStateReason reason_local = NM_DEVICE_STATE_REASON_NONE;
8009 int ip_ifindex, config_ifindex;
8011 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
8013 priv = NM_DEVICE_GET_PRIVATE (self);
8014 ip_ifindex = nm_device_get_ip_ifindex (self);
8017 config_ifindex = nm_ip6_config_get_ifindex (new_config);
8018 if (config_ifindex > 0)
8019 g_return_val_if_fail (ip_ifindex == config_ifindex, FALSE);
8022 old_config = priv->ip6_config;
8024 /* Always commit to nm-platform to update lifetimes */
8025 if (commit && new_config) {
8026 nm_device_ipv6_set_mtu (self, priv->ip6_mtu);
8027 success = nm_ip6_config_commit (new_config,
8031 reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
8036 /* has_changes is set only on relevant changes, because when the configuration changes,
8037 * this causes a re-read and reset. This should only happen for relevant changes */
8038 nm_ip6_config_replace (old_config, new_config, &has_changes);
8040 _LOGD (LOGD_IP6, "update IP6Config instance (%s)",
8041 nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
8045 priv->ip6_config = g_object_ref (new_config);
8047 if (success && !nm_exported_object_is_exported (NM_EXPORTED_OBJECT (new_config)))
8048 nm_exported_object_export (NM_EXPORTED_OBJECT (new_config));
8050 _LOGD (LOGD_IP6, "set IP6Config instance (%s)",
8051 nm_exported_object_get_path (NM_EXPORTED_OBJECT (new_config)));
8053 } else if (old_config) {
8055 priv->ip6_config = NULL;
8056 _LOGD (LOGD_IP6, "clear IP6Config instance (%s)",
8057 nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
8060 nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self);
8063 if (old_config != priv->ip6_config)
8064 _notify (self, PROP_IP6_CONFIG);
8065 g_signal_emit (self, signals[IP6_CONFIG_CHANGED], 0, priv->ip6_config, old_config);
8067 if (old_config != priv->ip6_config)
8068 nm_exported_object_clear_and_unexport (&old_config);
8070 if (nm_device_uses_generated_assumed_connection (self)) {
8071 NMConnection *connection = nm_device_get_applied_connection (self);
8072 NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (self));
8075 g_object_freeze_notify (G_OBJECT (connection));
8076 g_object_freeze_notify (G_OBJECT (settings_connection));
8078 nm_connection_remove_setting (settings_connection, NM_TYPE_SETTING_IP6_CONFIG);
8079 s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
8080 nm_connection_add_setting (settings_connection, s_ip6);
8082 nm_connection_remove_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
8083 s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
8084 nm_connection_add_setting (connection, s_ip6);
8086 g_object_thaw_notify (G_OBJECT (settings_connection));
8087 g_object_thaw_notify (G_OBJECT (connection));
8090 nm_device_queue_recheck_assume (self);
8094 *reason = reason_local;
8100 nm_device_replace_vpn6_config (NMDevice *self, NMIP6Config *old, NMIP6Config *config)
8102 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8104 if (!_replace_vpn_config_in_list (&priv->vpn6_configs, (GObject *) old, (GObject *) config))
8107 /* NULL to use existing configs */
8108 if (!ip6_config_merge_and_apply (self, TRUE, NULL))
8109 _LOGW (LOGD_IP6, "failed to set VPN routes for device");
8113 nm_device_set_wwan_ip6_config (NMDevice *self, NMIP6Config *config)
8115 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8117 if (priv->wwan_ip6_config == config)
8120 g_clear_object (&priv->wwan_ip6_config);
8122 priv->wwan_ip6_config = g_object_ref (config);
8124 /* NULL to use existing configs */
8125 if (!ip6_config_merge_and_apply (self, TRUE, NULL))
8126 _LOGW (LOGD_IP6, "failed to set WWAN IPv6 configuration");
8130 nm_device_get_dhcp6_config (NMDevice *self)
8132 g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
8134 return NM_DEVICE_GET_PRIVATE (self)->dhcp6_config;
8138 nm_device_get_ip6_config (NMDevice *self)
8140 g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
8142 return NM_DEVICE_GET_PRIVATE (self)->ip6_config;
8145 /****************************************************************/
8148 dispatcher_cleanup (NMDevice *self)
8150 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8152 if (priv->dispatcher.call_id) {
8153 nm_dispatcher_call_cancel (priv->dispatcher.call_id);
8154 priv->dispatcher.call_id = 0;
8155 priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN;
8156 priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
8161 dispatcher_complete_proceed_state (guint call_id, gpointer user_data)
8163 NMDevice *self = NM_DEVICE (user_data);
8164 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8166 g_return_if_fail (call_id == priv->dispatcher.call_id);
8168 priv->dispatcher.call_id = 0;
8169 nm_device_queue_state (self, priv->dispatcher.post_state,
8170 priv->dispatcher.post_state_reason);
8171 priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN;
8172 priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
8175 /****************************************************************/
8178 ip_check_pre_up (NMDevice *self)
8180 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8182 if (priv->dispatcher.call_id != 0) {
8183 g_warn_if_reached ();
8184 dispatcher_cleanup (self);
8187 priv->dispatcher.post_state = NM_DEVICE_STATE_SECONDARIES;
8188 priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
8189 if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_UP,
8190 nm_device_get_settings_connection (self),
8191 nm_device_get_applied_connection (self),
8193 dispatcher_complete_proceed_state,
8195 &priv->dispatcher.call_id)) {
8196 /* Just proceed on errors */
8197 dispatcher_complete_proceed_state (0, self);
8202 ip_check_gw_ping_cleanup (NMDevice *self)
8204 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8206 nm_clear_g_source (&priv->gw_ping.watch);
8207 nm_clear_g_source (&priv->gw_ping.timeout);
8209 if (priv->gw_ping.pid) {
8210 nm_utils_kill_child_async (priv->gw_ping.pid, SIGTERM, priv->gw_ping.log_domain, "ping", 1000, NULL, NULL);
8211 priv->gw_ping.pid = 0;
8214 g_clear_pointer (&priv->gw_ping.binary, g_free);
8215 g_clear_pointer (&priv->gw_ping.address, g_free);
8219 spawn_ping (NMDevice *self)
8221 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8222 gs_free char *str_timeout = NULL;
8223 gs_free char *tmp_str = NULL;
8224 const char *args[] = { priv->gw_ping.binary, "-I", nm_device_get_ip_iface (self),
8225 "-c", "1", "-w", NULL, priv->gw_ping.address, NULL };
8226 gs_free_error GError *error = NULL;
8229 args[6] = str_timeout = g_strdup_printf ("%u", priv->gw_ping.deadline);
8230 tmp_str = g_strjoinv (" ", (gchar **) args);
8231 _LOGD (priv->gw_ping.log_domain, "ping: running '%s'", tmp_str);
8233 ret = g_spawn_async ("/",
8236 G_SPAWN_DO_NOT_REAP_CHILD,
8243 _LOGW (priv->gw_ping.log_domain, "ping: could not spawn %s: %s",
8244 priv->gw_ping.binary, error->message);
8251 respawn_ping_cb (gpointer user_data)
8253 NMDevice *self = NM_DEVICE (user_data);
8254 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8256 priv->gw_ping.watch = 0;
8258 if (spawn_ping (self)) {
8259 priv->gw_ping.watch = g_child_watch_add (priv->gw_ping.pid,
8260 ip_check_ping_watch_cb, self);
8262 ip_check_gw_ping_cleanup (self);
8263 ip_check_pre_up (self);
8270 ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data)
8272 NMDevice *self = NM_DEVICE (user_data);
8273 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8274 NMLogDomain log_domain = priv->gw_ping.log_domain;
8275 gboolean success = FALSE;
8277 if (!priv->gw_ping.watch)
8279 priv->gw_ping.watch = 0;
8280 priv->gw_ping.pid = 0;
8282 if (WIFEXITED (status)) {
8283 if (WEXITSTATUS (status) == 0) {
8284 _LOGD (log_domain, "ping: gateway ping succeeded");
8287 _LOGW (log_domain, "ping: gateway ping failed with error code %d",
8288 WEXITSTATUS (status));
8291 _LOGW (log_domain, "ping: stopped unexpectedly with status %d", status);
8294 /* We've got connectivity, proceed to pre_up */
8295 ip_check_gw_ping_cleanup (self);
8296 ip_check_pre_up (self);
8298 /* If ping exited with an error it may have returned early,
8299 * wait 1 second and restart it */
8300 priv->gw_ping.watch = g_timeout_add_seconds (1, respawn_ping_cb, self);
8305 ip_check_ping_timeout_cb (gpointer user_data)
8307 NMDevice *self = NM_DEVICE (user_data);
8308 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8310 priv->gw_ping.timeout = 0;
8312 _LOGW (priv->gw_ping.log_domain, "ping: gateway ping timed out");
8314 ip_check_gw_ping_cleanup (self);
8315 ip_check_pre_up (self);
8320 start_ping (NMDevice *self,
8321 NMLogDomain log_domain,
8323 const char *address,
8326 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8328 g_return_val_if_fail (priv->gw_ping.watch == 0, FALSE);
8329 g_return_val_if_fail (priv->gw_ping.timeout == 0, FALSE);
8331 priv->gw_ping.log_domain = log_domain;
8332 priv->gw_ping.address = g_strdup (address);
8333 priv->gw_ping.binary = g_strdup (binary);
8334 priv->gw_ping.deadline = timeout + 10; /* the proper termination is enforced by a timer */
8336 if (spawn_ping (self)) {
8337 priv->gw_ping.watch = g_child_watch_add (priv->gw_ping.pid, ip_check_ping_watch_cb, self);
8338 priv->gw_ping.timeout = g_timeout_add_seconds (timeout, ip_check_ping_timeout_cb, self);
8342 ip_check_gw_ping_cleanup (self);
8347 nm_device_start_ip_check (NMDevice *self)
8349 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8350 NMConnection *connection;
8351 NMSettingConnection *s_con;
8353 const char *ping_binary = NULL;
8354 char buf[INET6_ADDRSTRLEN] = { 0 };
8355 NMLogDomain log_domain = LOGD_IP4;
8357 /* Shouldn't be any active ping here, since IP_CHECK happens after the
8358 * first IP method completes. Any subsequently completing IP method doesn't
8361 g_assert (!priv->gw_ping.watch);
8362 g_assert (!priv->gw_ping.timeout);
8363 g_assert (!priv->gw_ping.pid);
8364 g_assert (priv->ip4_state == IP_DONE || priv->ip6_state == IP_DONE);
8366 connection = nm_device_get_applied_connection (self);
8367 g_assert (connection);
8369 s_con = nm_connection_get_setting_connection (connection);
8371 timeout = nm_setting_connection_get_gateway_ping_timeout (s_con);
8374 if (priv->ip4_config && priv->ip4_state == IP_DONE) {
8377 ping_binary = nm_utils_find_helper ("ping", "/usr/bin/ping", NULL);
8378 log_domain = LOGD_IP4;
8380 gw = nm_ip4_config_get_gateway (priv->ip4_config);
8381 if (gw && !inet_ntop (AF_INET, &gw, buf, sizeof (buf)))
8383 } else if (priv->ip6_config && priv->ip6_state == IP_DONE) {
8384 const struct in6_addr *gw = NULL;
8386 ping_binary = nm_utils_find_helper ("ping6", "/usr/bin/ping6", NULL);
8387 log_domain = LOGD_IP6;
8389 gw = nm_ip6_config_get_gateway (priv->ip6_config);
8390 if (gw && !inet_ntop (AF_INET6, gw, buf, sizeof (buf)))
8396 start_ping (self, log_domain, ping_binary, buf, timeout);
8398 /* If no ping was started, just advance to pre_up */
8399 if (!priv->gw_ping.pid)
8400 ip_check_pre_up (self);
8403 /****************************************************************/
8406 carrier_wait_timeout (gpointer user_data)
8408 NMDevice *self = NM_DEVICE (user_data);
8410 NM_DEVICE_GET_PRIVATE (self)->carrier_wait_id = 0;
8411 nm_device_remove_pending_action (self, "carrier wait", TRUE);
8413 _carrier_wait_check_queued_act_request (self);
8415 return G_SOURCE_REMOVE;
8419 nm_device_is_up (NMDevice *self)
8421 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
8423 if (NM_DEVICE_GET_CLASS (self)->is_up)
8424 return NM_DEVICE_GET_CLASS (self)->is_up (self);
8430 is_up (NMDevice *self)
8432 int ifindex = nm_device_get_ip_ifindex (self);
8434 return ifindex > 0 ? nm_platform_link_is_up (NM_PLATFORM_GET, ifindex) : TRUE;
8438 nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware)
8440 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8441 gboolean device_is_up = FALSE;
8443 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
8445 _LOGD (LOGD_HW, "bringing up device");
8447 if (NM_DEVICE_GET_CLASS (self)->bring_up) {
8448 if (!NM_DEVICE_GET_CLASS (self)->bring_up (self, no_firmware))
8452 device_is_up = nm_device_is_up (self);
8453 if (block && !device_is_up) {
8454 int ifindex = nm_device_get_ip_ifindex (self);
8455 gint64 wait_until = nm_utils_get_monotonic_timestamp_us () + 10000 /* microseconds */;
8459 if (!nm_platform_link_refresh (NM_PLATFORM_GET, ifindex))
8461 device_is_up = nm_device_is_up (self);
8462 } while (!device_is_up && nm_utils_get_monotonic_timestamp_us () < wait_until);
8465 if (!device_is_up) {
8467 _LOGW (LOGD_HW, "device not up after timeout!");
8469 _LOGD (LOGD_HW, "device not up immediately");
8473 /* Devices that support carrier detect must be IFF_UP to report carrier
8474 * changes; so after setting the device IFF_UP we must suppress startup
8475 * complete (via a pending action) until either the carrier turns on, or
8476 * a timeout is reached.
8478 if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
8479 if (!nm_clear_g_source (&priv->carrier_wait_id))
8480 nm_device_add_pending_action (self, "carrier wait", TRUE);
8481 priv->carrier_wait_id = g_timeout_add_seconds (5, carrier_wait_timeout, self);
8484 /* Can only get HW address of some devices when they are up */
8485 nm_device_update_hw_address (self);
8487 _update_ip4_address (self);
8492 bring_up (NMDevice *self, gboolean *no_firmware)
8494 int ifindex = nm_device_get_ip_ifindex (self);
8499 *no_firmware = FALSE;
8503 result = nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, no_firmware);
8505 /* Store carrier immediately. */
8506 if (result && nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT))
8507 check_carrier (self);
8513 nm_device_take_down (NMDevice *self, gboolean block)
8515 gboolean device_is_up;
8517 g_return_if_fail (NM_IS_DEVICE (self));
8519 _LOGD (LOGD_HW, "taking down device");
8521 if (NM_DEVICE_GET_CLASS (self)->take_down) {
8522 if (!NM_DEVICE_GET_CLASS (self)->take_down (self))
8526 device_is_up = nm_device_is_up (self);
8527 if (block && device_is_up) {
8528 int ifindex = nm_device_get_ip_ifindex (self);
8529 gint64 wait_until = nm_utils_get_monotonic_timestamp_us () + 10000 /* microseconds */;
8533 if (!nm_platform_link_refresh (NM_PLATFORM_GET, ifindex))
8535 device_is_up = nm_device_is_up (self);
8536 } while (device_is_up && nm_utils_get_monotonic_timestamp_us () < wait_until);
8541 _LOGW (LOGD_HW, "device not down after timeout!");
8543 _LOGD (LOGD_HW, "device not down immediately");
8548 take_down (NMDevice *self)
8550 int ifindex = nm_device_get_ip_ifindex (self);
8553 return nm_platform_link_set_down (NM_PLATFORM_GET, ifindex);
8555 /* devices without ifindex are always up. */
8556 _LOGD (LOGD_HW, "cannot take down device without ifindex");
8561 nm_device_set_firmware_missing (NMDevice *self, gboolean new_missing)
8563 NMDevicePrivate *priv;
8565 g_return_if_fail (NM_IS_DEVICE (self));
8567 priv = NM_DEVICE_GET_PRIVATE (self);
8568 if (priv->firmware_missing != new_missing) {
8569 priv->firmware_missing = new_missing;
8570 _notify (self, PROP_FIRMWARE_MISSING);
8575 nm_device_get_firmware_missing (NMDevice *self)
8577 return NM_DEVICE_GET_PRIVATE (self)->firmware_missing;
8581 nm_device_set_nm_plugin_missing (NMDevice *self, gboolean new_missing)
8583 NMDevicePrivate *priv;
8585 g_return_if_fail (NM_IS_DEVICE (self));
8587 priv = NM_DEVICE_GET_PRIVATE (self);
8588 if (priv->nm_plugin_missing != new_missing) {
8589 priv->nm_plugin_missing = new_missing;
8590 _notify (self, PROP_NM_PLUGIN_MISSING);
8595 nm_device_get_nm_plugin_missing (NMDevice *self)
8597 return NM_DEVICE_GET_PRIVATE (self)->nm_plugin_missing;
8600 static NMIP4Config *
8601 find_ip4_lease_config (NMDevice *self,
8602 NMConnection *connection,
8603 NMIP4Config *ext_ip4_config)
8605 const char *ip_iface = nm_device_get_ip_iface (self);
8606 int ip_ifindex = nm_device_get_ip_ifindex (self);
8607 GSList *leases, *liter;
8608 NMIP4Config *found = NULL;
8610 g_return_val_if_fail (NM_IS_IP4_CONFIG (ext_ip4_config), NULL);
8611 g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
8613 leases = nm_dhcp_manager_get_lease_ip_configs (nm_dhcp_manager_get (),
8616 nm_connection_get_uuid (connection),
8618 nm_device_get_ip4_route_metric (self));
8619 for (liter = leases; liter && !found; liter = liter->next) {
8620 NMIP4Config *lease_config = liter->data;
8621 const NMPlatformIP4Address *address = nm_ip4_config_get_address (lease_config, 0);
8622 guint32 gateway = nm_ip4_config_get_gateway (lease_config);
8625 if (!nm_ip4_config_address_exists (ext_ip4_config, address))
8627 if (gateway != nm_ip4_config_get_gateway (ext_ip4_config))
8629 found = g_object_ref (lease_config);
8632 g_slist_free_full (leases, g_object_unref);
8637 capture_lease_config (NMDevice *self,
8638 NMIP4Config *ext_ip4_config,
8639 NMIP4Config **out_ip4_config,
8640 NMIP6Config *ext_ip6_config,
8641 NMIP6Config **out_ip6_config)
8643 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8644 const GSList *connections, *citer;
8646 gboolean dhcp_used = FALSE;
8648 /* Ensure at least one address on the device has a non-infinite lifetime,
8649 * otherwise DHCP cannot possibly be active on the device right now.
8651 if (ext_ip4_config && out_ip4_config) {
8652 for (i = 0; i < nm_ip4_config_get_num_addresses (ext_ip4_config); i++) {
8653 const NMPlatformIP4Address *addr = nm_ip4_config_get_address (ext_ip4_config, i);
8655 if (addr->lifetime != NM_PLATFORM_LIFETIME_PERMANENT) {
8660 } else if (ext_ip6_config && out_ip6_config) {
8661 for (i = 0; i < nm_ip6_config_get_num_addresses (ext_ip6_config); i++) {
8662 const NMPlatformIP6Address *addr = nm_ip6_config_get_address (ext_ip6_config, i);
8664 if (addr->lifetime != NM_PLATFORM_LIFETIME_PERMANENT) {
8670 g_return_if_fail ( (ext_ip6_config && out_ip6_config)
8671 || (ext_ip4_config && out_ip4_config));
8677 connections = nm_connection_provider_get_connections (priv->con_provider);
8678 for (citer = connections; citer; citer = citer->next) {
8679 NMConnection *candidate = citer->data;
8682 if (!nm_device_check_connection_compatible (self, candidate))
8686 method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP4_CONFIG);
8687 if (out_ip4_config && strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) {
8688 *out_ip4_config = find_ip4_lease_config (self, candidate, ext_ip4_config);
8689 if (*out_ip4_config)
8694 method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP6_CONFIG);
8695 if (out_ip6_config && strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
8696 /* FIXME: implement find_ip6_lease_config() */
8702 _ip4_config_intersect (gpointer value, gpointer user_data)
8704 NMIP4Config *dst = (NMIP4Config *) value;
8705 NMIP4Config *src = (NMIP4Config *) user_data;
8707 nm_ip4_config_intersect (dst, src);
8711 _ip4_config_subtract (gpointer value, gpointer user_data)
8713 NMIP4Config *dst = (NMIP4Config *) user_data;
8714 NMIP4Config *src = (NMIP4Config *) value;
8716 nm_ip4_config_subtract (dst, src);
8720 update_ip4_config (NMDevice *self, gboolean initial)
8722 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8724 gboolean capture_resolv_conf;
8725 NMDnsManagerResolvConfMode resolv_conf_mode;
8727 ifindex = nm_device_get_ip_ifindex (self);
8731 resolv_conf_mode = nm_dns_manager_get_resolv_conf_mode (nm_dns_manager_get ());
8732 capture_resolv_conf = initial && (resolv_conf_mode == NM_DNS_MANAGER_RESOLV_CONF_EXPLICIT);
8735 g_clear_object (&priv->ext_ip4_config);
8736 priv->ext_ip4_config = nm_ip4_config_capture (ifindex, capture_resolv_conf);
8737 if (priv->ext_ip4_config) {
8739 g_clear_object (&priv->dev_ip4_config);
8740 capture_lease_config (self, priv->ext_ip4_config, &priv->dev_ip4_config, NULL, NULL);
8743 /* FIXME: ext_ip4_config does not contain routes with source==RTPROT_KERNEL.
8744 * Hence, we will wrongly remove device-routes with metric=0 if they were added by
8745 * the user on purpose. This should be fixed by also tracking and exposing
8748 /* This function was called upon external changes. Remove the configuration
8749 * (addresses,routes) that is no longer present externally from the internal
8750 * config. This way, we don't re-add addresses that were manually removed
8752 if (priv->con_ip4_config)
8753 nm_ip4_config_intersect (priv->con_ip4_config, priv->ext_ip4_config);
8754 if (priv->dev_ip4_config)
8755 nm_ip4_config_intersect (priv->dev_ip4_config, priv->ext_ip4_config);
8757 g_slist_foreach (priv->vpn4_configs, _ip4_config_intersect, priv->ext_ip4_config);
8759 if (priv->wwan_ip4_config)
8760 nm_ip4_config_intersect (priv->wwan_ip4_config, priv->ext_ip4_config);
8762 /* Remove parts from ext_ip4_config to only contain the information that
8763 * was configured externally -- we already have the same configuration from
8764 * internal origins. */
8765 if (priv->con_ip4_config)
8766 nm_ip4_config_subtract (priv->ext_ip4_config, priv->con_ip4_config);
8767 if (priv->dev_ip4_config)
8768 nm_ip4_config_subtract (priv->ext_ip4_config, priv->dev_ip4_config);
8770 g_slist_foreach (priv->vpn4_configs, _ip4_config_subtract, priv->ext_ip4_config);
8772 if (priv->wwan_ip4_config)
8773 nm_ip4_config_subtract (priv->ext_ip4_config, priv->wwan_ip4_config);
8775 ip4_config_merge_and_apply (self, NULL, FALSE, NULL);
8780 _ip6_config_intersect (gpointer value, gpointer user_data)
8782 NMIP6Config *dst = (NMIP6Config *) value;
8783 NMIP6Config *src = (NMIP6Config *) user_data;
8785 nm_ip6_config_intersect (dst, src);
8789 _ip6_config_subtract (gpointer value, gpointer user_data)
8791 NMIP6Config *dst = (NMIP6Config *) user_data;
8792 NMIP6Config *src = (NMIP6Config *) value;
8794 nm_ip6_config_subtract (dst, src);
8798 update_ip6_config (NMDevice *self, gboolean initial)
8800 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8802 gboolean capture_resolv_conf;
8803 NMDnsManagerResolvConfMode resolv_conf_mode;
8805 ifindex = nm_device_get_ip_ifindex (self);
8809 resolv_conf_mode = nm_dns_manager_get_resolv_conf_mode (nm_dns_manager_get ());
8810 capture_resolv_conf = initial && (resolv_conf_mode == NM_DNS_MANAGER_RESOLV_CONF_EXPLICIT);
8813 g_clear_object (&priv->ext_ip6_config);
8814 g_clear_object (&priv->ext_ip6_config_captured);
8815 priv->ext_ip6_config_captured = nm_ip6_config_capture (ifindex, capture_resolv_conf, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
8816 if (priv->ext_ip6_config_captured) {
8818 priv->ext_ip6_config = nm_ip6_config_new_cloned (priv->ext_ip6_config_captured);
8820 /* This function was called upon external changes. Remove the configuration
8821 * (addresses,routes) that is no longer present externally from the internal
8822 * config. This way, we don't re-add addresses that were manually removed
8824 if (priv->con_ip6_config)
8825 nm_ip6_config_intersect (priv->con_ip6_config, priv->ext_ip6_config);
8826 if (priv->ac_ip6_config)
8827 nm_ip6_config_intersect (priv->ac_ip6_config, priv->ext_ip6_config);
8828 if (priv->dhcp6_ip6_config)
8829 nm_ip6_config_intersect (priv->dhcp6_ip6_config, priv->ext_ip6_config);
8830 if (priv->wwan_ip6_config)
8831 nm_ip6_config_intersect (priv->wwan_ip6_config, priv->ext_ip6_config);
8832 g_slist_foreach (priv->vpn6_configs, _ip6_config_intersect, priv->ext_ip6_config);
8834 /* Remove parts from ext_ip6_config to only contain the information that
8835 * was configured externally -- we already have the same configuration from
8836 * internal origins. */
8837 if (priv->con_ip6_config)
8838 nm_ip6_config_subtract (priv->ext_ip6_config, priv->con_ip6_config);
8839 if (priv->ac_ip6_config)
8840 nm_ip6_config_subtract (priv->ext_ip6_config, priv->ac_ip6_config);
8841 if (priv->dhcp6_ip6_config)
8842 nm_ip6_config_subtract (priv->ext_ip6_config, priv->dhcp6_ip6_config);
8843 if (priv->wwan_ip6_config)
8844 nm_ip6_config_subtract (priv->ext_ip6_config, priv->wwan_ip6_config);
8845 g_slist_foreach (priv->vpn6_configs, _ip6_config_subtract, priv->ext_ip6_config);
8847 ip6_config_merge_and_apply (self, FALSE, NULL);
8850 if ( priv->linklocal6_timeout_id
8851 && priv->ext_ip6_config_captured
8852 && nm_ip6_config_get_address_first_nontentative (priv->ext_ip6_config_captured, TRUE)) {
8853 /* linklocal6 is ready now, do the state transition... we are also
8854 * invoked as g_idle_add, so no problems with reentrance doing it now.
8856 linklocal6_complete (self);
8861 nm_device_capture_initial_config (NMDevice *self)
8863 update_ip4_config (self, TRUE);
8864 update_ip6_config (self, TRUE);
8868 queued_ip4_config_change (gpointer user_data)
8870 NMDevice *self = NM_DEVICE (user_data);
8871 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8873 /* Wait for any queued state changes */
8874 if (priv->queued_state.id)
8877 priv->queued_ip4_config_id = 0;
8878 g_object_ref (self);
8879 update_ip4_config (self, FALSE);
8880 g_object_unref (self);
8886 queued_ip6_config_change (gpointer user_data)
8888 NMDevice *self = NM_DEVICE (user_data);
8889 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
8891 gboolean need_ipv6ll = FALSE;
8893 /* Wait for any queued state changes */
8894 if (priv->queued_state.id)
8897 priv->queued_ip6_config_id = 0;
8898 g_object_ref (self);
8899 update_ip6_config (self, FALSE);
8901 if ( nm_platform_link_get (NM_PLATFORM_GET, priv->ifindex)
8902 && priv->state < NM_DEVICE_STATE_DEACTIVATING) {
8903 /* Handle DAD falures */
8904 for (iter = priv->dad6_failed_addrs; iter; iter = g_slist_next (iter)) {
8905 NMPlatformIP6Address *addr = iter->data;
8907 if (addr->source >= NM_IP_CONFIG_SOURCE_USER)
8910 _LOGI (LOGD_IP6, "ipv6: duplicate address check failed for the %s address",
8911 nm_platform_ip6_address_to_string (addr, NULL, 0));
8913 if (IN6_IS_ADDR_LINKLOCAL (&addr->address))
8915 else if (priv->rdisc)
8916 nm_rdisc_dad_failed (priv->rdisc, &addr->address);
8919 /* If no IPv6 link-local address exists but other addresses do then we
8920 * must add the LL address to remain conformant with RFC 3513 chapter 2.1
8921 * ("Addressing Model"): "All interfaces are required to have at least
8922 * one link-local unicast address".
8924 if (priv->ip6_config && nm_ip6_config_get_num_addresses (priv->ip6_config))
8928 check_and_add_ipv6ll_addr (self);
8931 g_slist_free_full (priv->dad6_failed_addrs, g_free);
8932 priv->dad6_failed_addrs = NULL;
8934 g_object_unref (self);
8940 device_ipx_changed (NMPlatform *platform,
8941 NMPObjectType obj_type,
8943 gpointer platform_object,
8944 NMPlatformSignalChangeType change_type,
8947 NMDevicePrivate *priv;
8948 NMPlatformIP6Address *addr;
8950 if (nm_device_get_ip_ifindex (self) != ifindex)
8953 priv = NM_DEVICE_GET_PRIVATE (self);
8956 case NMP_OBJECT_TYPE_IP4_ADDRESS:
8957 case NMP_OBJECT_TYPE_IP4_ROUTE:
8958 if (!priv->queued_ip4_config_id) {
8959 priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
8960 _LOGD (LOGD_DEVICE, "queued IP4 config change");
8963 case NMP_OBJECT_TYPE_IP6_ADDRESS:
8964 addr = platform_object;
8966 if ( priv->state > NM_DEVICE_STATE_DISCONNECTED
8967 && priv->state < NM_DEVICE_STATE_DEACTIVATING
8968 && ( (change_type == NM_PLATFORM_SIGNAL_CHANGED && addr->n_ifa_flags & IFA_F_DADFAILED)
8969 || (change_type == NM_PLATFORM_SIGNAL_REMOVED && addr->n_ifa_flags & IFA_F_TENTATIVE))) {
8970 priv->dad6_failed_addrs = g_slist_append (priv->dad6_failed_addrs,
8971 g_memdup (addr, sizeof (NMPlatformIP6Address)));
8974 case NMP_OBJECT_TYPE_IP6_ROUTE:
8975 if (!priv->queued_ip6_config_id) {
8976 priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
8977 _LOGD (LOGD_DEVICE, "queued IP6 config change");
8981 g_return_if_reached ();
8985 /*****************************************************************************/
8987 NM_UTILS_FLAGS2STR_DEFINE (nm_unmanaged_flags2str, NMUnmanagedFlags,
8988 NM_UTILS_FLAGS2STR (NM_UNMANAGED_SLEEPING, "sleeping"),
8989 NM_UTILS_FLAGS2STR (NM_UNMANAGED_QUITTING, "quitting"),
8990 NM_UTILS_FLAGS2STR (NM_UNMANAGED_PARENT, "parent"),
8991 NM_UTILS_FLAGS2STR (NM_UNMANAGED_LOOPBACK, "loopback"),
8992 NM_UTILS_FLAGS2STR (NM_UNMANAGED_PLATFORM_INIT, "platform-init"),
8993 NM_UTILS_FLAGS2STR (NM_UNMANAGED_USER_EXPLICIT, "user-explicit"),
8994 NM_UTILS_FLAGS2STR (NM_UNMANAGED_BY_DEFAULT, "by-default"),
8995 NM_UTILS_FLAGS2STR (NM_UNMANAGED_USER_SETTINGS, "user-settings"),
8996 NM_UTILS_FLAGS2STR (NM_UNMANAGED_USER_UDEV, "user-udev"),
8997 NM_UTILS_FLAGS2STR (NM_UNMANAGED_EXTERNAL_DOWN, "external-down"),
8998 NM_UTILS_FLAGS2STR (NM_UNMANAGED_IS_SLAVE, "is-slave"),
9002 _unmanaged_flags2str (NMUnmanagedFlags flags, NMUnmanagedFlags mask, char *buf, gsize len)
9009 nm_utils_to_string_buffer_init (&buf, &len);
9017 nm_unmanaged_flags2str (flags, b, len);
9022 nm_unmanaged_flags2str (mask & ~flags, buf2, sizeof (buf2));
9024 gboolean add_separator = l > 0;
9029 nm_utils_strbuf_append_c (&b, &len, ',');
9030 add_separator = TRUE;
9032 tmp2 = strchr (tmp, ',');
9036 nm_utils_strbuf_append_c (&b, &len, '!');
9037 nm_utils_strbuf_append_str (&b, &len, tmp);
9049 _get_managed_by_flags(NMUnmanagedFlags flags, NMUnmanagedFlags mask, gboolean for_user_request)
9051 /* Evaluate the managed state based on the unmanaged flags.
9053 * Some flags are authoritative, meaning they always cause
9054 * the device to be unmanaged (e.g. @NM_UNMANAGED_PLATFORM_INIT).
9056 * OTOH, some flags can be overwritten. For example NM_UNMANAGED_USER_SETTINGS
9057 * is ignored once NM_UNMANAGED_USER_EXPLICIT is set. The idea is that
9058 * the flag from the configuration has no effect once the user explicitly
9059 * touches the unmanaged flags. */
9061 if (for_user_request) {
9063 /* @for_user_request can make the result only ~more~ managed.
9064 * If the flags already indicate a managed state for a non-user-request,
9065 * then it is also managed for an explict user-request.
9067 * Effectively, this check is redundant, as the code below already
9068 * already ensures that. Still, express this invariant explictly here. */
9069 if (_get_managed_by_flags (flags, mask, FALSE))
9072 /* A for-user-request, is effectively the same as pretending
9073 * that user-dbus flag is cleared. */
9074 mask |= NM_UNMANAGED_USER_EXPLICIT;
9075 flags &= ~NM_UNMANAGED_USER_EXPLICIT;
9078 if ( NM_FLAGS_ANY (mask, NM_UNMANAGED_USER_SETTINGS)
9079 && !NM_FLAGS_ANY (flags, NM_UNMANAGED_USER_SETTINGS)) {
9080 /* NM_UNMANAGED_USER_SETTINGS can only explicitly unmanage a device. It cannot
9081 * *manage* it. Having NM_UNMANAGED_USER_SETTINGS explicitly not set, is the
9082 * same as having it not set at all. */
9083 mask &= ~NM_UNMANAGED_USER_SETTINGS;
9086 if (NM_FLAGS_ANY (mask, NM_UNMANAGED_USER_UDEV)) {
9087 /* configuration from udev or nm-config overwrites the by-default flag
9088 * which is based on the device type. */
9089 flags &= ~NM_UNMANAGED_BY_DEFAULT;
9092 if ( NM_FLAGS_HAS (mask, NM_UNMANAGED_IS_SLAVE)
9093 && !NM_FLAGS_HAS (flags, NM_UNMANAGED_IS_SLAVE)) {
9094 /* for an enslaved device, by-default doesn't matter */
9095 flags &= ~NM_UNMANAGED_BY_DEFAULT;
9098 if (NM_FLAGS_HAS (mask, NM_UNMANAGED_USER_EXPLICIT)) {
9099 /* if the device is managed by user-decision, certain other flags
9102 flags &= ~( NM_UNMANAGED_BY_DEFAULT
9103 | NM_UNMANAGED_USER_UDEV
9104 | NM_UNMANAGED_EXTERNAL_DOWN);
9107 return flags == NM_UNMANAGED_NONE;
9111 * nm_device_get_managed:
9112 * @self: the #NMDevice
9113 * @for_user_request: whether to check the flags for an explict user-request
9115 * Whether the device is unmanaged according to the unmanaged flags.
9117 * Returns: %TRUE if the device is unmanaged because of the flags.
9120 nm_device_get_managed (NMDevice *self, gboolean for_user_request)
9122 NMDevicePrivate *priv;
9124 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
9126 if (!nm_device_is_real (self)) {
9127 /* a unrealized device is always considered unmanaged. */
9131 priv = NM_DEVICE_GET_PRIVATE (self);
9133 return _get_managed_by_flags (priv->unmanaged_flags, priv->unmanaged_mask, for_user_request);
9137 * nm_device_get_unmanaged_mask:
9138 * @self: the #NMDevice
9139 * @flag: the unmanaged flags to check.
9141 * Return the unmanaged flags mask set on this device.
9143 * Returns: the flags of the device ( & @flag)
9146 nm_device_get_unmanaged_mask (NMDevice *self, NMUnmanagedFlags flag)
9148 g_return_val_if_fail (NM_IS_DEVICE (self), NM_UNMANAGED_NONE);
9149 g_return_val_if_fail (flag != NM_UNMANAGED_NONE, NM_UNMANAGED_NONE);
9151 return NM_DEVICE_GET_PRIVATE (self)->unmanaged_mask & flag;
9155 * nm_device_get_unmanaged_flags:
9156 * @self: the #NMDevice
9157 * @flag: the unmanaged flags to check.
9159 * Return the unmanaged flags of the device.
9161 * Returns: the flags of the device ( & @flag)
9164 nm_device_get_unmanaged_flags (NMDevice *self, NMUnmanagedFlags flag)
9166 g_return_val_if_fail (NM_IS_DEVICE (self), NM_UNMANAGED_NONE);
9167 g_return_val_if_fail (flag != NM_UNMANAGED_NONE, NM_UNMANAGED_NONE);
9169 return NM_DEVICE_GET_PRIVATE (self)->unmanaged_flags & flag;
9173 * _set_unmanaged_flags:
9174 * @self: the #NMDevice instance
9175 * @flags: which #NMUnmanagedFlags to set.
9176 * @set_op: whether to set/clear/forget the flags. You can also pass
9177 * boolean values %TRUE and %FALSE, which mean %NM_UNMAN_FLAG_OP_SET_UNMANAGED
9178 * and %NM_UNMAN_FLAG_OP_SET_MANAGED, respectively.
9179 * @allow_state_transition: if %FALSE, setting flags never triggers a device
9180 * state change. If %TRUE, the device can change state, if it is real and
9181 * switches from managed to unmanaged (or vice versa).
9182 * @reason: the device state reason passed to nm_device_state_changed() if
9183 * the device becomes managed/unmanaged. This is only relevant if the
9184 * device switches state and if @allow_state_transition is %TRUE.
9186 * Set the unmanaged flags of the device.
9189 _set_unmanaged_flags (NMDevice *self,
9190 NMUnmanagedFlags flags,
9191 NMUnmanFlagOp set_op,
9192 gboolean allow_state_transition,
9193 NMDeviceStateReason reason)
9195 NMDevicePrivate *priv;
9196 gboolean was_managed, transition_state;
9197 NMUnmanagedFlags old_flags, old_mask;
9198 const char *operation = NULL;
9202 g_return_if_fail (NM_IS_DEVICE (self));
9203 g_return_if_fail (flags);
9205 priv = NM_DEVICE_GET_PRIVATE (self);
9208 allow_state_transition = FALSE;
9209 was_managed = allow_state_transition && nm_device_get_managed (self, FALSE);
9211 old_flags = priv->unmanaged_flags;
9212 old_mask = priv->unmanaged_mask;
9215 case NM_UNMAN_FLAG_OP_FORGET:
9216 priv->unmanaged_mask &= ~flags;
9217 priv->unmanaged_flags &= ~flags;
9218 operation = "forget";
9220 case NM_UNMAN_FLAG_OP_SET_UNMANAGED:
9221 priv->unmanaged_mask |= flags;
9222 priv->unmanaged_flags |= flags;
9223 operation = "set-unmanaged";
9225 case NM_UNMAN_FLAG_OP_SET_MANAGED:
9226 priv->unmanaged_mask |= flags;
9227 priv->unmanaged_flags &= ~flags;
9228 operation = "set-managed";
9231 g_return_if_reached ();
9234 if ( old_flags == priv->unmanaged_flags
9235 && old_mask == priv->unmanaged_mask)
9238 transition_state = allow_state_transition
9239 && was_managed != nm_device_get_managed (self, FALSE)
9242 && nm_device_get_state (self) == NM_DEVICE_STATE_UNMANAGED));
9244 #define _FMTX "[%s%s0x%0x/0x%x/%s"
9245 #define _FMT(flags, mask, str) \
9246 _unmanaged_flags2str ((flags), (mask), str, sizeof (str)), \
9247 ((flags) | (mask)) ? "=" : "", \
9250 (_get_managed_by_flags (flags, mask, FALSE) \
9252 : (_get_managed_by_flags (flags, mask, TRUE) \
9255 _LOGD (LOGD_DEVICE, "unmanaged: flags set to "_FMTX"%s, %s [%s=0x%0x]%s%s%s)",
9256 _FMT (priv->unmanaged_flags, priv->unmanaged_mask, str1),
9257 priv->real ? "" : "/unrealized",
9259 nm_unmanaged_flags2str (flags, str2, sizeof (str2)),
9261 NM_PRINT_FMT_QUOTED (allow_state_transition,
9263 reason_to_string (reason),
9264 transition_state ? ", transition-state" : "",
9268 if (transition_state) {
9270 nm_device_state_changed (self, NM_DEVICE_STATE_UNMANAGED, reason);
9272 nm_device_state_changed (self, NM_DEVICE_STATE_UNAVAILABLE, reason);
9277 * @self: the #NMDevice instance
9278 * @flags: which #NMUnmanagedFlags to set.
9279 * @set_op: whether to set/clear/forget the flags. You can also pass
9280 * boolean values %TRUE and %FALSE, which mean %NM_UNMAN_FLAG_OP_SET_UNMANAGED
9281 * and %NM_UNMAN_FLAG_OP_SET_MANAGED, respectively.
9283 * Set the unmanaged flags of the device (does not trigger a state change).
9286 nm_device_set_unmanaged_flags (NMDevice *self,
9287 NMUnmanagedFlags flags,
9288 NMUnmanFlagOp set_op)
9290 _set_unmanaged_flags (self, flags, set_op, FALSE, NM_DEVICE_STATE_REASON_NONE);
9294 * nm_device_set_unmanaged_by_flags:
9295 * @self: the #NMDevice instance
9296 * @flags: which #NMUnmanagedFlags to set.
9297 * @set_op: whether to set/clear/forget the flags. You can also pass
9298 * boolean values %TRUE and %FALSE, which mean %NM_UNMAN_FLAG_OP_SET_UNMANAGED
9299 * and %NM_UNMAN_FLAG_OP_SET_MANAGED, respectively.
9300 * @reason: the device state reason passed to nm_device_state_changed() if
9301 * the device becomes managed/unmanaged.
9303 * Set the unmanaged flags of the device and possibly trigger a state change.
9306 nm_device_set_unmanaged_by_flags (NMDevice *self,
9307 NMUnmanagedFlags flags,
9308 NMUnmanFlagOp set_op,
9309 NMDeviceStateReason reason)
9311 _set_unmanaged_flags (self, flags, set_op, TRUE, reason);
9315 nm_device_set_unmanaged_by_user_config (NMDevice *self, const GSList *unmanaged_specs)
9317 NMDevicePrivate *priv;
9320 g_return_if_fail (NM_IS_DEVICE (self));
9322 priv = NM_DEVICE_GET_PRIVATE (self);
9324 unmanaged = nm_device_spec_match_list (self, unmanaged_specs);
9326 nm_device_set_unmanaged_by_flags (self,
9327 NM_UNMANAGED_USER_SETTINGS,
9330 ? NM_DEVICE_STATE_REASON_NOW_UNMANAGED
9331 : NM_DEVICE_STATE_REASON_NOW_MANAGED);
9335 nm_device_set_unmanaged_by_user_udev (NMDevice *self)
9338 gboolean platform_unmanaged = FALSE;
9340 ifindex = self->priv->ifindex;
9343 || !nm_platform_link_get_unmanaged (NM_PLATFORM_GET, ifindex, &platform_unmanaged))
9346 nm_device_set_unmanaged_by_flags (self,
9347 NM_UNMANAGED_USER_UDEV,
9349 NM_DEVICE_STATE_REASON_USER_REQUESTED);
9353 nm_device_set_unmanaged_by_quitting (NMDevice *self)
9355 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9356 gboolean need_deactivate = nm_device_is_activating (self) ||
9357 priv->state == NM_DEVICE_STATE_ACTIVATED;
9359 /* It's OK to block here because we're quitting */
9360 if (need_deactivate)
9361 _set_state_full (self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_NOW_UNMANAGED, TRUE);
9363 nm_device_set_unmanaged_by_flags (self,
9364 NM_UNMANAGED_QUITTING,
9366 need_deactivate ? NM_DEVICE_STATE_REASON_REMOVED
9367 : NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
9370 /*****************************************************************************/
9373 nm_device_set_dhcp_timeout (NMDevice *self, guint32 timeout)
9375 g_return_if_fail (NM_IS_DEVICE (self));
9377 NM_DEVICE_GET_PRIVATE (self)->dhcp_timeout = timeout;
9381 nm_device_set_dhcp_anycast_address (NMDevice *self, const char *addr)
9383 NMDevicePrivate *priv;
9385 g_return_if_fail (NM_IS_DEVICE (self));
9386 g_return_if_fail (!addr || nm_utils_hwaddr_valid (addr, ETH_ALEN));
9388 priv = NM_DEVICE_GET_PRIVATE (self);
9390 g_free (priv->dhcp_anycast_address);
9391 priv->dhcp_anycast_address = g_strdup (addr);
9395 nm_device_reapply_settings_immediately (NMDevice *self)
9397 NMConnection *applied_connection;
9398 NMSettingsConnection *settings_connection;
9399 NMDeviceState state;
9400 NMSettingConnection *s_con_settings;
9401 NMSettingConnection *s_con_applied;
9406 g_return_if_fail (NM_IS_DEVICE (self));
9408 state = nm_device_get_state (self);
9409 if ( state <= NM_DEVICE_STATE_DISCONNECTED
9410 || state > NM_DEVICE_STATE_ACTIVATED)
9413 applied_connection = nm_device_get_applied_connection (self);
9414 settings_connection = nm_device_get_settings_connection (self);
9416 if (!nm_settings_connection_has_unmodified_applied_connection (settings_connection,
9418 NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY))
9421 s_con_settings = nm_connection_get_setting_connection ((NMConnection *) settings_connection);
9422 s_con_applied = nm_connection_get_setting_connection (applied_connection);
9424 if (g_strcmp0 ((zone = nm_setting_connection_get_zone (s_con_settings)),
9425 nm_setting_connection_get_zone (s_con_applied)) != 0) {
9427 version_id = nm_active_connection_version_id_bump ((NMActiveConnection *) self->priv->act_request);
9428 _LOGD (LOGD_DEVICE, "reapply setting: zone = %s%s%s (version-id %llu)", NM_PRINT_FMT_QUOTE_STRING (zone), (long long unsigned) version_id);
9430 g_object_set (G_OBJECT (s_con_applied),
9431 NM_SETTING_CONNECTION_ZONE, zone,
9434 nm_device_update_firewall_zone (self);
9437 if ((metered = nm_setting_connection_get_metered (s_con_settings)) != nm_setting_connection_get_metered (s_con_applied)) {
9439 version_id = nm_active_connection_version_id_bump ((NMActiveConnection *) self->priv->act_request);
9440 _LOGD (LOGD_DEVICE, "reapply setting: metered = %d (version-id %llu)", (int) metered, (long long unsigned) version_id);
9442 g_object_set (G_OBJECT (s_con_applied),
9443 NM_SETTING_CONNECTION_METERED, metered,
9446 nm_device_update_metered (self);
9451 nm_device_update_firewall_zone (NMDevice *self)
9453 NMConnection *applied_connection;
9454 NMSettingConnection *s_con;
9456 g_return_if_fail (NM_IS_DEVICE (self));
9458 applied_connection = nm_device_get_applied_connection (self);
9459 if (!applied_connection)
9462 s_con = nm_connection_get_setting_connection (applied_connection);
9463 if ( nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED
9464 && !nm_device_uses_assumed_connection (self)) {
9465 nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
9466 nm_device_get_ip_iface (self),
9467 nm_setting_connection_get_zone (s_con),
9468 FALSE, /* change zone */
9475 nm_device_update_metered (NMDevice *self)
9477 #define NM_METERED_INVALID ((NMMetered) -1)
9478 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9479 NMSettingConnection *setting;
9480 NMMetered conn_value, value = NM_METERED_INVALID;
9481 NMConnection *connection = NULL;
9482 NMDeviceState state;
9484 g_return_if_fail (NM_IS_DEVICE (self));
9486 state = nm_device_get_state (self);
9487 if ( state <= NM_DEVICE_STATE_DISCONNECTED
9488 || state > NM_DEVICE_STATE_ACTIVATED)
9489 value = NM_METERED_UNKNOWN;
9491 if (value == NM_METERED_INVALID) {
9492 connection = nm_device_get_applied_connection (self);
9494 setting = nm_connection_get_setting_connection (connection);
9496 conn_value = nm_setting_connection_get_metered (setting);
9497 if (conn_value != NM_METERED_UNKNOWN)
9503 /* Try to guess a value using the metered flag in IP configuration */
9504 if (value == NM_METERED_INVALID) {
9505 if ( priv->ip4_config
9506 && priv->ip4_state == IP_DONE
9507 && nm_ip4_config_get_metered (priv->ip4_config))
9508 value = NM_METERED_GUESS_YES;
9511 /* Otherwise look at connection type */
9512 if (value == NM_METERED_INVALID) {
9513 if ( nm_connection_is_type (connection, NM_SETTING_GSM_SETTING_NAME)
9514 || nm_connection_is_type (connection, NM_SETTING_CDMA_SETTING_NAME))
9515 value = NM_METERED_GUESS_YES;
9517 value = NM_METERED_GUESS_NO;
9520 if (value != priv->metered) {
9521 _LOGD (LOGD_DEVICE, "set metered value %d", value);
9522 priv->metered = value;
9523 _notify (self, PROP_METERED);
9528 _nm_device_check_connection_available (NMDevice *self,
9529 NMConnection *connection,
9530 NMDeviceCheckConAvailableFlags flags,
9531 const char *specific_object)
9533 NMDeviceState state;
9535 /* an unrealized software device is always available, hardware devices never. */
9536 if (!nm_device_is_real (self)) {
9537 if (nm_device_is_software (self))
9538 return nm_device_check_connection_compatible (self, connection);
9542 state = nm_device_get_state (self);
9543 if (state < NM_DEVICE_STATE_UNMANAGED)
9545 if ( state < NM_DEVICE_STATE_UNAVAILABLE
9546 && ( ( !NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST)
9547 && !nm_device_get_managed (self, FALSE))
9548 || ( NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST)
9549 && !nm_device_get_managed (self, TRUE))))
9551 if ( state < NM_DEVICE_STATE_DISCONNECTED
9552 && !nm_device_is_software (self)
9553 && ( ( !NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST)
9554 && !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE))
9555 || ( NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST)
9556 && !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST))))
9559 if (!nm_device_check_connection_compatible (self, connection))
9562 return NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, flags, specific_object);
9566 * nm_device_check_connection_available():
9567 * @self: the #NMDevice
9568 * @connection: the #NMConnection to check for availability
9569 * @flags: flags to affect the decision making of whether a connection
9570 * is available. Adding a flag can only make a connection more available,
9572 * @specific_object: a device type dependent argument to further
9573 * filter the result. Passing a non %NULL specific object can only reduce
9574 * the availability of a connection.
9576 * Check if @connection is available to be activated on @self.
9578 * Returns: %TRUE if @connection can be activated on @self
9581 nm_device_check_connection_available (NMDevice *self,
9582 NMConnection *connection,
9583 NMDeviceCheckConAvailableFlags flags,
9584 const char *specific_object)
9588 available = _nm_device_check_connection_available (self, connection, flags, specific_object);
9590 #if NM_MORE_ASSERTS >= 2
9592 /* The meaning of the flags is so that *adding* a flag relaxes a condition, thus making
9593 * the device *more* available. Assert against that requirement by testing all the flags. */
9594 NMDeviceCheckConAvailableFlags i, j, k;
9595 gboolean available_all[NM_DEVICE_CHECK_CON_AVAILABLE_ALL + 1] = { FALSE };
9597 for (i = 0; i <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; i++)
9598 available_all[i] = _nm_device_check_connection_available (self, connection, i, specific_object);
9600 for (i = 0; i <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; i++) {
9601 for (j = 1; j <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; j <<= 1) {
9602 if (NM_FLAGS_HAS (i, j)) {
9604 nm_assert ( available_all[i] == available_all[k]
9605 || available_all[i]);
9616 available_connections_notify (NMDevice *self)
9618 _notify (self, PROP_AVAILABLE_CONNECTIONS);
9622 available_connections_del_all (NMDevice *self)
9624 if (g_hash_table_size (self->priv->available_connections) == 0)
9626 g_hash_table_remove_all (self->priv->available_connections);
9631 available_connections_add (NMDevice *self, NMConnection *connection)
9633 return nm_g_hash_table_add (self->priv->available_connections, g_object_ref (connection));
9637 available_connections_del (NMDevice *self, NMConnection *connection)
9639 return g_hash_table_remove (self->priv->available_connections, connection);
9643 check_connection_available (NMDevice *self,
9644 NMConnection *connection,
9645 NMDeviceCheckConAvailableFlags flags,
9646 const char *specific_object)
9648 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
9650 /* Connections which require a network connection are not available when
9651 * the device has no carrier, even with ignore-carrer=TRUE.
9654 || !connection_requires_carrier (connection))
9657 if ( NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)
9658 && priv->carrier_wait_id != 0) {
9659 /* The device has no carrier though the connection requires it.
9661 * If we are still waiting for carrier, the connection is available
9662 * for an explicit user-request. */
9670 nm_device_recheck_available_connections (NMDevice *self)
9672 NMDevicePrivate *priv;
9673 const GSList *connections, *iter;
9674 gboolean changed = FALSE;
9675 GHashTableIter h_iter;
9676 NMConnection *connection;
9678 g_return_if_fail (NM_IS_DEVICE (self));
9680 priv = NM_DEVICE_GET_PRIVATE(self);
9682 if (priv->con_provider) {
9683 gs_unref_hashtable GHashTable *prune_list = NULL;
9685 if (g_hash_table_size (priv->available_connections) > 0) {
9686 prune_list = g_hash_table_new (g_direct_hash, g_direct_equal);
9687 g_hash_table_iter_init (&h_iter, priv->available_connections);
9688 while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL))
9689 g_hash_table_add (prune_list, connection);
9692 connections = nm_connection_provider_get_connections (priv->con_provider);
9693 for (iter = connections; iter; iter = g_slist_next (iter)) {
9694 connection = NM_CONNECTION (iter->data);
9696 if (nm_device_check_connection_available (self,
9698 NM_DEVICE_CHECK_CON_AVAILABLE_NONE,
9700 if (available_connections_add (self, connection))
9703 g_hash_table_remove (prune_list, connection);
9708 g_hash_table_iter_init (&h_iter, prune_list);
9709 while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL)) {
9710 if (available_connections_del (self, connection))
9715 if (available_connections_del_all (self))
9720 available_connections_notify (self);
9721 available_connections_check_delete_unrealized (self);
9725 * nm_device_get_best_connection:
9726 * @self: the #NMDevice
9727 * @specific_object: a specific object path if any
9728 * @error: reason why no connection was returned
9730 * Returns a connection that's most suitable for user-initiated activation
9731 * of a device, optionally with a given specific object.
9733 * Returns: the #NMSettingsConnection or %NULL (setting an @error)
9735 NMSettingsConnection *
9736 nm_device_get_best_connection (NMDevice *self,
9737 const char *specific_object,
9740 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9741 NMSettingsConnection *connection = NULL;
9742 NMSettingsConnection *candidate;
9743 guint64 best_timestamp = 0;
9744 GHashTableIter iter;
9746 g_hash_table_iter_init (&iter, priv->available_connections);
9747 while (g_hash_table_iter_next (&iter, (gpointer) &candidate, NULL)) {
9748 guint64 candidate_timestamp = 0;
9750 /* If a specific object is given, only include connections that are
9751 * compatible with it.
9753 if ( specific_object /* << Optimization: we know that the connection is available without @specific_object. */
9754 && !nm_device_check_connection_available (self,
9755 NM_CONNECTION (candidate),
9756 _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST,
9760 nm_settings_connection_get_timestamp (candidate, &candidate_timestamp);
9761 if (!connection || (candidate_timestamp > best_timestamp)) {
9762 connection = candidate;
9763 best_timestamp = candidate_timestamp;
9768 g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
9769 "The device '%s' has no connections available for activation.",
9770 nm_device_get_iface (self));
9777 cp_connection_added_or_updated (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
9780 NMDevice *self = user_data;
9782 g_return_if_fail (NM_IS_DEVICE (self));
9783 g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection));
9785 if (nm_device_check_connection_available (self,
9787 _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST,
9789 changed = available_connections_add (self, connection);
9791 changed = available_connections_del (self, connection);
9794 available_connections_notify (self);
9795 available_connections_check_delete_unrealized (self);
9800 cp_connection_removed (NMConnectionProvider *cp, NMConnection *connection, gpointer user_data)
9802 NMDevice *self = user_data;
9804 g_return_if_fail (NM_IS_DEVICE (self));
9806 if (available_connections_del (self, connection)) {
9807 available_connections_notify (self);
9808 available_connections_check_delete_unrealized (self);
9813 nm_device_supports_vlans (NMDevice *self)
9815 return nm_platform_link_supports_vlans (NM_PLATFORM_GET, nm_device_get_ifindex (self));
9819 * nm_device_add_pending_action():
9820 * @self: the #NMDevice to add the pending action to
9821 * @action: a static string that identifies the action
9822 * @assert_not_yet_pending: if %TRUE, assert that the @action is currently not yet pending.
9823 * Otherwise, ignore duplicate scheduling of the same action silently.
9825 * Adds a pending action to the device.
9827 * Returns: %TRUE if the action was added (and not already added before). %FALSE
9828 * if the same action is already scheduled. In the latter case, the action was not scheduled
9832 nm_device_add_pending_action (NMDevice *self, const char *action, gboolean assert_not_yet_pending)
9834 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9838 g_return_val_if_fail (action, FALSE);
9840 /* Check if the action is already pending. Cannot add duplicate actions */
9841 for (iter = priv->pending_actions; iter; iter = iter->next) {
9842 if (!strcmp (action, iter->data)) {
9843 if (assert_not_yet_pending) {
9844 _LOGW (LOGD_DEVICE, "add_pending_action (%d): '%s' already pending",
9845 count + g_slist_length (iter), action);
9846 g_return_val_if_reached (FALSE);
9848 _LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s' already pending (expected)",
9849 count + g_slist_length (iter), action);
9856 priv->pending_actions = g_slist_append (priv->pending_actions, g_strdup (action));
9859 _LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s'", count, action);
9862 _notify (self, PROP_HAS_PENDING_ACTION);
9868 * nm_device_remove_pending_action():
9869 * @self: the #NMDevice to remove the pending action from
9870 * @action: a static string that identifies the action
9871 * @assert_is_pending: if %TRUE, assert that the @action is pending.
9872 * If %FALSE, don't do anything if the current action is not pending and
9875 * Removes a pending action previously added by nm_device_add_pending_action().
9877 * Returns: whether the @action was pending and is now removed.
9880 nm_device_remove_pending_action (NMDevice *self, const char *action, gboolean assert_is_pending)
9882 NMDevicePrivate *priv;
9883 GSList *iter, *next;
9886 g_return_val_if_fail (self, FALSE);
9887 g_return_val_if_fail (action, FALSE);
9889 priv = NM_DEVICE_GET_PRIVATE (self);
9891 for (iter = priv->pending_actions; iter; iter = next) {
9893 if (!strcmp (action, iter->data)) {
9894 _LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s'",
9895 count + g_slist_length (iter->next), /* length excluding 'iter' */
9897 g_free (iter->data);
9898 priv->pending_actions = g_slist_delete_link (priv->pending_actions, iter);
9899 if (priv->pending_actions == NULL)
9900 _notify (self, PROP_HAS_PENDING_ACTION);
9906 if (assert_is_pending) {
9907 _LOGW (LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending", count, action);
9908 g_return_val_if_reached (FALSE);
9910 _LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending (expected)", count, action);
9916 nm_device_has_pending_action (NMDevice *self)
9918 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9920 return !!priv->pending_actions;
9923 /***********************************************************/
9926 _cancel_activation (NMDevice *self)
9928 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9930 /* Clean up when device was deactivated during call to firewall */
9931 if (priv->fw_call) {
9932 nm_firewall_manager_cancel_call (priv->fw_call);
9933 g_warn_if_fail (!priv->fw_call);
9934 priv->fw_call = NULL;
9936 priv->fw_ready = FALSE;
9938 ip_check_gw_ping_cleanup (self);
9940 /* Break the activation chain */
9941 activation_source_clear (self, AF_INET);
9942 activation_source_clear (self, AF_INET6);
9946 _cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type)
9948 NMConnection *connection;
9950 _cancel_activation (self);
9952 connection = nm_device_get_applied_connection (self);
9953 if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE
9955 && !nm_device_uses_assumed_connection (self)) {
9956 nm_firewall_manager_remove_from_zone (nm_firewall_manager_get (),
9957 nm_device_get_ip_iface (self),
9963 /* Clear any queued transitions */
9964 nm_device_queued_state_clear (self);
9966 _cleanup_ip4_pre (self, cleanup_type);
9967 _cleanup_ip6_pre (self, cleanup_type);
9971 _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type)
9973 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
9974 NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE;
9976 priv->default_route.v4_has = FALSE;
9977 priv->default_route.v6_has = FALSE;
9979 if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) {
9980 priv->default_route.v4_is_assumed = FALSE;
9981 priv->default_route.v6_is_assumed = FALSE;
9982 nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self);
9983 nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self);
9986 priv->default_route.v4_is_assumed = TRUE;
9987 priv->default_route.v6_is_assumed = TRUE;
9988 nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self);
9989 nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self);
9991 priv->v4_commit_first_time = TRUE;
9992 priv->v6_commit_first_time = TRUE;
9994 priv->linklocal6_dad_counter = 0;
9996 /* Clean up IP configs; this does not actually deconfigure the
9997 * interface; the caller must flush routes and addresses explicitly.
9999 nm_device_set_ip4_config (self, NULL, 0, TRUE, TRUE, &ignored);
10000 nm_device_set_ip6_config (self, NULL, TRUE, TRUE, &ignored);
10001 g_clear_object (&priv->con_ip4_config);
10002 g_clear_object (&priv->dev_ip4_config);
10003 g_clear_object (&priv->ext_ip4_config);
10004 g_clear_object (&priv->wwan_ip4_config);
10005 g_clear_object (&priv->ip4_config);
10006 g_clear_object (&priv->con_ip6_config);
10007 g_clear_object (&priv->ac_ip6_config);
10008 g_clear_object (&priv->ext_ip6_config);
10009 g_clear_object (&priv->ext_ip6_config_captured);
10010 g_clear_object (&priv->wwan_ip6_config);
10011 g_clear_object (&priv->ip6_config);
10013 g_slist_free_full (priv->vpn4_configs, g_object_unref);
10014 priv->vpn4_configs = NULL;
10015 g_slist_free_full (priv->vpn6_configs, g_object_unref);
10016 priv->vpn6_configs = NULL;
10018 clear_act_request (self);
10020 /* Clear legacy IPv4 address property */
10021 if (priv->ip4_address) {
10022 priv->ip4_address = 0;
10023 _notify (self, PROP_IP4_ADDRESS);
10026 if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) {
10027 /* Check if the device was deactivated, and if so, delete_link.
10028 * Don't call delete_link synchronously because we are currently
10029 * handling a state change -- which is not reentrant. */
10030 delete_on_deactivate_check_and_schedule (self, nm_device_get_ip_ifindex (self));
10033 /* ip_iface should be cleared after flushing all routes and addreses, since
10034 * those are identified by ip_iface, not by iface (which might be a tty
10037 nm_device_set_ip_iface (self, NULL);
10041 * nm_device_cleanup
10043 * Remove a device's routing table entries and IP addresses.
10047 nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType cleanup_type)
10049 NMDevicePrivate *priv;
10052 g_return_if_fail (NM_IS_DEVICE (self));
10054 if (reason == NM_DEVICE_STATE_REASON_NOW_MANAGED)
10055 _LOGD (LOGD_DEVICE, "preparing device");
10057 _LOGD (LOGD_DEVICE, "deactivating device (reason '%s') [%d]", reason_to_string (reason), reason);
10059 /* Save whether or not we tried IPv6 for later */
10060 priv = NM_DEVICE_GET_PRIVATE (self);
10062 _cleanup_generic_pre (self, cleanup_type);
10064 /* Turn off kernel IPv6 */
10065 if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) {
10066 set_disable_ipv6 (self, "1");
10067 nm_device_ipv6_sysctl_set (self, "accept_ra", "0");
10068 nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0");
10071 /* Call device type-specific deactivation */
10072 if (NM_DEVICE_GET_CLASS (self)->deactivate)
10073 NM_DEVICE_GET_CLASS (self)->deactivate (self);
10075 /* master: release slaves */
10076 nm_device_master_release_slaves (self);
10078 /* slave: mark no longer enslaved */
10080 && nm_platform_link_get_master (NM_PLATFORM_GET, priv->ifindex) <= 0)
10081 nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
10083 /* Take out any entries in the routing table and any IP address the device had. */
10084 ifindex = nm_device_get_ip_ifindex (self);
10086 nm_route_manager_route_flush (nm_route_manager_get (), ifindex);
10087 nm_platform_address_flush (NM_PLATFORM_GET, ifindex);
10090 if (priv->lldp_listener)
10091 nm_lldp_listener_stop (priv->lldp_listener);
10093 nm_device_update_metered (self);
10094 _cleanup_generic_post (self, cleanup_type);
10098 bin2hexstr (const char *bytes, gsize len)
10103 g_return_val_if_fail (bytes != NULL, NULL);
10104 g_return_val_if_fail (len > 0, NULL);
10106 str = g_string_sized_new (len * 2 + 1);
10107 for (i = 0; i < len; i++) {
10109 g_string_append_c (str, ':');
10110 g_string_append_printf (str, "%02x", (guint8) bytes[i]);
10112 return g_string_free (str, FALSE);
10116 find_dhcp4_address (NMDevice *self)
10118 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10121 if (!priv->ip4_config)
10124 n = nm_ip4_config_get_num_addresses (priv->ip4_config);
10125 for (i = 0; i < n; i++) {
10126 const NMPlatformIP4Address *a = nm_ip4_config_get_address (priv->ip4_config, i);
10128 if (a->source == NM_IP_CONFIG_SOURCE_DHCP)
10129 return g_strdup (nm_utils_inet4_ntop (a->address, NULL));
10135 nm_device_spawn_iface_helper (NMDevice *self)
10137 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10138 gboolean configured = FALSE;
10139 NMConnection *connection;
10140 GError *error = NULL;
10141 const char *method;
10143 gs_free char *dhcp4_address = NULL;
10144 char *logging_backend;
10146 if (priv->state != NM_DEVICE_STATE_ACTIVATED)
10148 if (!nm_device_can_assume_connections (self))
10151 connection = nm_device_get_applied_connection (self);
10152 g_assert (connection);
10154 argv = g_ptr_array_sized_new (10);
10155 g_ptr_array_set_free_func (argv, g_free);
10157 g_ptr_array_add (argv, g_strdup (LIBEXECDIR "/nm-iface-helper"));
10158 g_ptr_array_add (argv, g_strdup ("--ifname"));
10159 g_ptr_array_add (argv, g_strdup (nm_device_get_ip_iface (self)));
10160 g_ptr_array_add (argv, g_strdup ("--uuid"));
10161 g_ptr_array_add (argv, g_strdup (nm_connection_get_uuid (connection)));
10163 logging_backend = nm_config_get_is_debug (nm_config_get ())
10164 ? g_strdup ("debug")
10165 : nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG,
10166 NM_CONFIG_KEYFILE_GROUP_LOGGING,
10167 NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND,
10168 NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY);
10169 if (logging_backend) {
10170 g_ptr_array_add (argv, g_strdup ("--logging-backend"));
10171 g_ptr_array_add (argv, logging_backend);
10174 dhcp4_address = find_dhcp4_address (self);
10176 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
10177 if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) {
10178 NMSettingIPConfig *s_ip4;
10179 char *hex_client_id;
10181 s_ip4 = nm_connection_get_setting_ip4_config (connection);
10184 g_ptr_array_add (argv, g_strdup ("--priority4"));
10185 g_ptr_array_add (argv, g_strdup_printf ("%u", nm_device_get_ip4_route_metric (self)));
10187 g_ptr_array_add (argv, g_strdup ("--dhcp4"));
10188 g_ptr_array_add (argv, g_strdup (dhcp4_address));
10189 if (nm_setting_ip_config_get_may_fail (s_ip4) == FALSE)
10190 g_ptr_array_add (argv, g_strdup ("--dhcp4-required"));
10192 if (priv->dhcp4_client) {
10193 const char *hostname, *fqdn;
10196 client_id = nm_dhcp_client_get_client_id (priv->dhcp4_client);
10198 g_ptr_array_add (argv, g_strdup ("--dhcp4-clientid"));
10199 hex_client_id = bin2hexstr (g_bytes_get_data (client_id, NULL),
10200 g_bytes_get_size (client_id));
10201 g_ptr_array_add (argv, hex_client_id);
10204 hostname = nm_dhcp_client_get_hostname (priv->dhcp4_client);
10206 g_ptr_array_add (argv, g_strdup ("--dhcp4-hostname"));
10207 g_ptr_array_add (argv, g_strdup (hostname));
10210 fqdn = nm_dhcp_client_get_fqdn (priv->dhcp4_client);
10212 g_ptr_array_add (argv, g_strdup ("--dhcp4-fqdn"));
10213 g_ptr_array_add (argv, g_strdup (fqdn));
10220 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
10221 if (g_strcmp0 (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) {
10222 NMSettingIPConfig *s_ip6;
10224 NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT;
10226 s_ip6 = nm_connection_get_setting_ip6_config (connection);
10229 g_ptr_array_add (argv, g_strdup ("--priority6"));
10230 g_ptr_array_add (argv, g_strdup_printf ("%u", nm_device_get_ip6_route_metric (self)));
10232 g_ptr_array_add (argv, g_strdup ("--slaac"));
10234 if (nm_setting_ip_config_get_may_fail (s_ip6) == FALSE)
10235 g_ptr_array_add (argv, g_strdup ("--slaac-required"));
10237 g_ptr_array_add (argv, g_strdup ("--slaac-tempaddr"));
10238 g_ptr_array_add (argv, g_strdup_printf ("%d", priv->rdisc_use_tempaddr));
10240 if (nm_device_get_ip_iface_identifier (self, &iid)) {
10241 g_ptr_array_add (argv, g_strdup ("--iid"));
10242 hex_iid = bin2hexstr ((const char *) iid.id_u8, sizeof (NMUtilsIPv6IfaceId));
10243 g_ptr_array_add (argv, hex_iid);
10246 g_ptr_array_add (argv, g_strdup ("--addr-gen-mode"));
10247 g_ptr_array_add (argv, g_strdup_printf ("%d", nm_setting_ip6_config_get_addr_gen_mode (NM_SETTING_IP6_CONFIG (s_ip6))));
10255 g_ptr_array_add (argv, NULL);
10257 if (nm_logging_enabled (LOGL_DEBUG, LOGD_DEVICE)) {
10260 tmp = g_strjoinv (" ", (char **) argv->pdata);
10261 _LOGD (LOGD_DEVICE, "running '%s'", tmp);
10265 if (g_spawn_async (NULL, (char **) argv->pdata, NULL,
10266 G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &error)) {
10267 _LOGI (LOGD_DEVICE, "spawned helper PID %u", (guint) pid);
10269 _LOGW (LOGD_DEVICE, "failed to spawn helper: %s", error->message);
10270 g_error_free (error);
10274 g_ptr_array_unref (argv);
10277 /***********************************************************/
10280 ip_config_valid (NMDeviceState state)
10282 return (state == NM_DEVICE_STATE_UNMANAGED) ||
10283 (state >= NM_DEVICE_STATE_IP_CHECK &&
10284 state <= NM_DEVICE_STATE_DEACTIVATING);
10288 notify_ip_properties (NMDevice *self)
10290 _notify (self, PROP_IP_IFACE);
10291 _notify (self, PROP_IP4_CONFIG);
10292 _notify (self, PROP_DHCP4_CONFIG);
10293 _notify (self, PROP_IP6_CONFIG);
10294 _notify (self, PROP_DHCP6_CONFIG);
10298 ip6_managed_setup (NMDevice *self)
10300 set_nm_ipv6ll (self, TRUE);
10301 set_disable_ipv6 (self, "1");
10302 nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0");
10303 nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0");
10304 nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0");
10305 nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0");
10309 deactivate_async_ready (NMDevice *self,
10311 gpointer user_data)
10313 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10314 NMDeviceStateReason reason = GPOINTER_TO_UINT (user_data);
10315 GError *error = NULL;
10317 NM_DEVICE_GET_CLASS (self)->deactivate_async_finish (self, res, &error);
10319 /* If operation cancelled, just return */
10320 if ( g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)
10321 || (priv->deactivating_cancellable && g_cancellable_is_cancelled (priv->deactivating_cancellable))) {
10322 _LOGW (LOGD_DEVICE, "Deactivation cancelled");
10324 /* In every other case, transition to the DISCONNECTED state */
10327 _LOGW (LOGD_DEVICE, "Deactivation failed: %s",
10330 nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
10333 g_clear_object (&priv->deactivating_cancellable);
10334 g_clear_error (&error);
10338 deactivate_dispatcher_complete (guint call_id, gpointer user_data)
10340 NMDevice *self = NM_DEVICE (user_data);
10341 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10342 NMDeviceStateReason reason;
10344 g_return_if_fail (call_id == priv->dispatcher.call_id);
10345 g_return_if_fail (priv->dispatcher.post_state == NM_DEVICE_STATE_DISCONNECTED);
10347 reason = priv->dispatcher.post_state_reason;
10349 priv->dispatcher.call_id = 0;
10350 priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN;
10351 priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
10353 if (priv->deactivating_cancellable) {
10354 g_warn_if_reached ();
10355 g_cancellable_cancel (priv->deactivating_cancellable);
10356 g_clear_object (&priv->deactivating_cancellable);
10359 if ( NM_DEVICE_GET_CLASS (self)->deactivate_async
10360 && NM_DEVICE_GET_CLASS (self)->deactivate_async_finish) {
10361 priv->deactivating_cancellable = g_cancellable_new ();
10362 NM_DEVICE_GET_CLASS (self)->deactivate_async (self,
10363 priv->deactivating_cancellable,
10364 (GAsyncReadyCallback) deactivate_async_ready,
10365 GUINT_TO_POINTER (reason));
10367 nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
10371 _set_state_full (NMDevice *self,
10372 NMDeviceState state,
10373 NMDeviceStateReason reason,
10376 NMDevicePrivate *priv;
10377 NMDeviceState old_state;
10379 gboolean no_firmware = FALSE;
10380 NMSettingsConnection *connection;
10381 NMConnection *applied_connection;
10383 g_return_if_fail (NM_IS_DEVICE (self));
10385 priv = NM_DEVICE_GET_PRIVATE (self);
10387 /* Track re-entry */
10388 g_warn_if_fail (priv->in_state_changed == FALSE);
10390 old_state = priv->state;
10392 /* Do nothing if state isn't changing, but as a special case allow
10393 * re-setting UNAVAILABLE if the device is missing firmware so that we
10394 * can retry device initialization.
10396 if ( (priv->state == state)
10397 && ( state != NM_DEVICE_STATE_UNAVAILABLE
10398 || !priv->firmware_missing)) {
10399 _LOGD (LOGD_DEVICE, "state change: %s -> %s (reason '%s') [%d %d %d]%s",
10400 state_to_string (old_state),
10401 state_to_string (state),
10402 reason_to_string (reason),
10406 priv->firmware_missing ? " (missing firmware)" : "");
10410 _LOGI (LOGD_DEVICE, "state change: %s -> %s (reason '%s') [%d %d %d]",
10411 state_to_string (old_state),
10412 state_to_string (state),
10413 reason_to_string (reason),
10418 priv->in_state_changed = TRUE;
10420 priv->state = state;
10421 priv->state_reason = reason;
10423 /* Clear any queued transitions */
10424 nm_device_queued_state_clear (self);
10426 dispatcher_cleanup (self);
10427 if (priv->deactivating_cancellable)
10428 g_cancellable_cancel (priv->deactivating_cancellable);
10430 /* Cache the activation request for the dispatcher */
10431 req = priv->act_request ? g_object_ref (priv->act_request) : NULL;
10433 if (state <= NM_DEVICE_STATE_UNAVAILABLE) {
10434 if (available_connections_del_all (self))
10435 available_connections_notify (self);
10436 if (old_state > NM_DEVICE_STATE_UNAVAILABLE)
10437 _clear_queued_act_request (priv);
10440 /* Update the available connections list when a device first becomes available */
10441 if (state >= NM_DEVICE_STATE_DISCONNECTED && old_state < NM_DEVICE_STATE_DISCONNECTED)
10442 nm_device_recheck_available_connections (self);
10444 /* Handle the new state here; but anything that could trigger
10445 * another state change should be done below.
10448 case NM_DEVICE_STATE_UNMANAGED:
10449 nm_device_set_firmware_missing (self, FALSE);
10450 if (old_state > NM_DEVICE_STATE_UNMANAGED) {
10451 if (reason == NM_DEVICE_STATE_REASON_REMOVED) {
10452 nm_device_cleanup (self, reason, CLEANUP_TYPE_REMOVED);
10454 /* Clean up if the device is now unmanaged but was activated */
10455 if (nm_device_get_act_request (self))
10456 nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
10457 nm_device_take_down (self, TRUE);
10458 set_nm_ipv6ll (self, FALSE);
10459 restore_ip6_properties (self);
10463 case NM_DEVICE_STATE_UNAVAILABLE:
10464 if (old_state == NM_DEVICE_STATE_UNMANAGED) {
10465 save_ip6_properties (self);
10466 if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED)
10467 ip6_managed_setup (self);
10470 if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) {
10471 if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) {
10472 if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware)
10473 _LOGW (LOGD_HW, "firmware may be missing.");
10474 nm_device_set_firmware_missing (self, no_firmware ? TRUE : FALSE);
10477 /* Ensure the device gets deactivated in response to stuff like
10478 * carrier changes or rfkill. But don't deactivate devices that are
10479 * about to assume a connection since that defeats the purpose of
10480 * assuming the device's existing connection.
10482 * Note that we "deactivate" the device even when coming from
10483 * UNMANAGED, to ensure that it's in a clean state.
10485 nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
10488 case NM_DEVICE_STATE_DISCONNECTED:
10489 if (old_state > NM_DEVICE_STATE_DISCONNECTED) {
10490 /* Ensure devices that previously assumed a connection now have
10491 * userspace IPv6LL enabled.
10493 set_nm_ipv6ll (self, TRUE);
10495 nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
10496 } else if (old_state < NM_DEVICE_STATE_DISCONNECTED) {
10497 if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) {
10498 /* Ensure IPv6 is set up as it may not have been done when
10499 * entering the UNAVAILABLE state depending on the reason.
10501 ip6_managed_setup (self);
10505 case NM_DEVICE_STATE_NEED_AUTH:
10506 if (old_state > NM_DEVICE_STATE_NEED_AUTH) {
10507 /* Clean up any half-done IP operations if the device's layer2
10508 * finds out it needs authentication during IP config.
10510 _cleanup_ip4_pre (self, CLEANUP_TYPE_DECONFIGURE);
10511 _cleanup_ip6_pre (self, CLEANUP_TYPE_DECONFIGURE);
10518 /* Reset autoconnect flag when the device is activating or connected. */
10519 if ( state >= NM_DEVICE_STATE_PREPARE
10520 && state <= NM_DEVICE_STATE_ACTIVATED)
10521 nm_device_set_autoconnect (self, TRUE);
10523 _notify (self, PROP_STATE);
10524 _notify (self, PROP_STATE_REASON);
10525 g_signal_emit_by_name (self, NM_DEVICE_STATE_CHANGED, state, old_state, reason);
10527 /* Post-process the event after internal notification */
10530 case NM_DEVICE_STATE_UNAVAILABLE:
10531 /* If the device can activate now (ie, it's got a carrier, the supplicant
10532 * is active, or whatever) schedule a delayed transition to DISCONNECTED
10533 * to get things rolling. The device can't transition immediately because
10534 * we can't change states again from the state handler for a variety of
10537 if (nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) {
10538 nm_device_queue_recheck_available (self,
10539 NM_DEVICE_STATE_REASON_NONE,
10540 NM_DEVICE_STATE_REASON_NONE);
10542 _LOGD (LOGD_DEVICE, "device not yet available for transition to DISCONNECTED");
10545 case NM_DEVICE_STATE_DEACTIVATING:
10546 _cancel_activation (self);
10548 if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
10549 /* We cache the ignore_carrier state to not react on config-reloads while the connection
10550 * is active. But on deactivating, reset the ignore-carrier flag to the current state. */
10551 priv->ignore_carrier = nm_config_data_get_ignore_carrier (NM_CONFIG_GET_DATA, self);
10555 nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN,
10556 nm_act_request_get_settings_connection (req),
10557 nm_act_request_get_applied_connection (req),
10560 priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED;
10561 priv->dispatcher.post_state_reason = reason;
10562 if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN,
10563 nm_act_request_get_settings_connection (req),
10564 nm_act_request_get_applied_connection (req),
10566 deactivate_dispatcher_complete,
10568 &priv->dispatcher.call_id)) {
10569 /* Just proceed on errors */
10570 deactivate_dispatcher_complete (0, self);
10574 case NM_DEVICE_STATE_DISCONNECTED:
10575 if ( priv->queued_act_request
10576 && !priv->queued_act_request_is_waiting_for_carrier) {
10577 NMActRequest *queued_req;
10580 queued_req = priv->queued_act_request;
10581 priv->queued_act_request = NULL;
10582 success = _device_activate (self, queued_req);
10583 g_object_unref (queued_req);
10589 case NM_DEVICE_STATE_ACTIVATED:
10590 _LOGI (LOGD_DEVICE, "Activation: successful, device activated.");
10591 nm_device_update_metered (self);
10592 nm_dispatcher_call (DISPATCHER_ACTION_UP,
10593 nm_act_request_get_settings_connection (req),
10594 nm_act_request_get_applied_connection (req),
10595 self, NULL, NULL, NULL);
10597 case NM_DEVICE_STATE_FAILED:
10598 /* Usually upon failure the activation chain is interrupted in
10599 * one of the stages; but in some cases the device fails for
10600 * external events (as a failure of master connection) while
10601 * the activation sequence is running and so we need to ensure
10602 * that the chain is terminated here.
10604 _cancel_activation (self);
10606 if (nm_device_uses_assumed_connection (self)) {
10607 /* Avoid tearing down assumed connection, assume it's connected */
10608 nm_device_queue_state (self,
10609 NM_DEVICE_STATE_ACTIVATED,
10610 NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
10614 connection = nm_device_get_settings_connection (self);
10615 _LOGW (LOGD_DEVICE | LOGD_WIFI,
10616 "Activation: failed for connection '%s'",
10617 connection ? nm_settings_connection_get_id (connection) : "<unknown>");
10619 /* Notify any slaves of the unexpected failure */
10620 nm_device_master_release_slaves (self);
10622 /* If the connection doesn't yet have a timestamp, set it to zero so that
10623 * we can distinguish between connections we've tried to activate and have
10624 * failed (zero timestamp), connections that succeeded (non-zero timestamp),
10625 * and those we haven't tried yet (no timestamp).
10627 if (connection && !nm_settings_connection_get_timestamp (connection, NULL))
10628 nm_settings_connection_update_timestamp (connection, (guint64) 0, TRUE);
10630 /* Schedule the transition to DISCONNECTED. The device can't transition
10631 * immediately because we can't change states again from the state
10632 * handler for a variety of reasons.
10634 nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE);
10636 case NM_DEVICE_STATE_IP_CHECK:
10637 /* Now that IP config has completed, check if the firewall
10638 * zone must be set again for the IP interface.
10640 applied_connection = nm_device_get_applied_connection (self);
10642 if ( applied_connection
10643 && priv->ifindex != priv->ip_ifindex
10644 && !nm_device_uses_assumed_connection (self)) {
10645 NMSettingConnection *s_con;
10648 s_con = nm_connection_get_setting_connection (applied_connection);
10649 zone = nm_setting_connection_get_zone (s_con);
10650 g_assert (!priv->fw_call);
10651 priv->fw_call = nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
10652 nm_device_get_ip_iface (self),
10655 fw_change_zone_cb_ip_check,
10658 nm_device_start_ip_check (self);
10660 /* IP-related properties are only valid when the device has IP configuration;
10661 * now that it does, ensure their change notifications are emitted.
10663 notify_ip_properties (self);
10665 case NM_DEVICE_STATE_SECONDARIES:
10666 ip_check_gw_ping_cleanup (self);
10667 _LOGD (LOGD_DEVICE, "device entered SECONDARIES state");
10673 if (state > NM_DEVICE_STATE_DISCONNECTED)
10674 delete_on_deactivate_unschedule (self);
10676 if ( (old_state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_DEACTIVATING)
10677 && (state != NM_DEVICE_STATE_DEACTIVATING)) {
10679 nm_dispatcher_call_sync (DISPATCHER_ACTION_DOWN,
10680 nm_act_request_get_settings_connection (req),
10681 nm_act_request_get_applied_connection (req),
10684 nm_dispatcher_call (DISPATCHER_ACTION_DOWN,
10685 nm_act_request_get_settings_connection (req),
10686 nm_act_request_get_applied_connection (req),
10687 self, NULL, NULL, NULL);
10691 /* IP-related properties are only valid when the device has IP configuration.
10692 * If it no longer does, ensure their change notifications are emitted.
10694 if (ip_config_valid (old_state) && !ip_config_valid (state))
10695 notify_ip_properties (self);
10697 /* Dispose of the cached activation request */
10699 g_object_unref (req);
10701 priv->in_state_changed = FALSE;
10703 if ((old_state > NM_DEVICE_STATE_UNMANAGED) != (state > NM_DEVICE_STATE_UNMANAGED))
10704 _notify (self, PROP_MANAGED);
10708 nm_device_state_changed (NMDevice *self,
10709 NMDeviceState state,
10710 NMDeviceStateReason reason)
10712 _set_state_full (self, state, reason, FALSE);
10716 queued_set_state (gpointer user_data)
10718 NMDevice *self = NM_DEVICE (user_data);
10719 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10720 NMDeviceState new_state;
10721 NMDeviceStateReason new_reason;
10723 if (priv->queued_state.id) {
10724 _LOGD (LOGD_DEVICE, "running queued state change to %s (id %d)",
10725 state_to_string (priv->queued_state.state),
10726 priv->queued_state.id);
10728 /* Clear queued state struct before triggering state change, since
10729 * the state change may queue another state.
10731 priv->queued_state.id = 0;
10732 new_state = priv->queued_state.state;
10733 new_reason = priv->queued_state.reason;
10734 nm_device_queued_state_clear (self);
10736 nm_device_state_changed (self, new_state, new_reason);
10737 nm_device_remove_pending_action (self, queued_state_to_string (new_state), TRUE);
10739 g_warn_if_fail (priv->queued_state.state == NM_DEVICE_STATE_UNKNOWN);
10740 g_warn_if_fail (priv->queued_state.reason == NM_DEVICE_STATE_REASON_NONE);
10746 nm_device_queue_state (NMDevice *self,
10747 NMDeviceState state,
10748 NMDeviceStateReason reason)
10750 NMDevicePrivate *priv;
10752 g_return_if_fail (NM_IS_DEVICE (self));
10754 priv = NM_DEVICE_GET_PRIVATE (self);
10756 if (priv->queued_state.id && priv->queued_state.state == state)
10759 /* Add pending action for the new state before clearing the queued states, so
10760 * that we don't accidently pop all pending states and reach 'startup complete' */
10761 nm_device_add_pending_action (self, queued_state_to_string (state), TRUE);
10763 /* We should only ever have one delayed state transition at a time */
10764 if (priv->queued_state.id) {
10765 _LOGW (LOGD_DEVICE, "overwriting previously queued state change to %s (%s)",
10766 state_to_string (priv->queued_state.state),
10767 reason_to_string (priv->queued_state.reason));
10768 nm_device_queued_state_clear (self);
10771 priv->queued_state.state = state;
10772 priv->queued_state.reason = reason;
10773 priv->queued_state.id = g_idle_add (queued_set_state, self);
10775 _LOGD (LOGD_DEVICE, "queued state change to %s due to %s (id %d)",
10776 state_to_string (state), reason_to_string (reason),
10777 priv->queued_state.id);
10781 nm_device_queued_state_peek (NMDevice *self)
10783 NMDevicePrivate *priv;
10785 g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_STATE_UNKNOWN);
10787 priv = NM_DEVICE_GET_PRIVATE (self);
10789 return priv->queued_state.id ? priv->queued_state.state : NM_DEVICE_STATE_UNKNOWN;
10793 nm_device_queued_state_clear (NMDevice *self)
10795 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10797 if (priv->queued_state.id) {
10798 _LOGD (LOGD_DEVICE, "clearing queued state transition (id %d)",
10799 priv->queued_state.id);
10800 nm_clear_g_source (&priv->queued_state.id);
10801 nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE);
10803 memset (&priv->queued_state, 0, sizeof (priv->queued_state));
10807 nm_device_get_state (NMDevice *self)
10809 g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_STATE_UNKNOWN);
10811 return NM_DEVICE_GET_PRIVATE (self)->state;
10814 /***********************************************************/
10815 /* NMConfigDevice interface related stuff */
10818 nm_device_get_hw_address (NMDevice *self)
10820 NMDevicePrivate *priv;
10822 g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
10823 priv = NM_DEVICE_GET_PRIVATE (self);
10825 return priv->hw_addr_len ? priv->hw_addr : NULL;
10829 nm_device_update_hw_address (NMDevice *self)
10831 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10832 int ifindex = nm_device_get_ifindex (self);
10833 const guint8 *hwaddr;
10834 gsize hwaddrlen = 0;
10835 static const guint8 zero_hwaddr[ETH_ALEN];
10840 hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddrlen);
10842 if ( priv->type == NM_DEVICE_TYPE_ETHERNET
10843 && nm_utils_hwaddr_matches (hwaddr, hwaddrlen, zero_hwaddr, sizeof (zero_hwaddr)))
10847 priv->hw_addr_len = hwaddrlen;
10848 if (!priv->hw_addr || !nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) {
10849 g_free (priv->hw_addr);
10850 priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen);
10852 _LOGD (LOGD_HW | LOGD_DEVICE, "hardware address now %s", priv->hw_addr);
10853 _notify (self, PROP_HW_ADDRESS);
10856 /* Invalid or no hardware address */
10857 if (priv->hw_addr_len != 0) {
10858 g_clear_pointer (&priv->hw_addr, g_free);
10859 priv->hw_addr_len = 0;
10860 _LOGD (LOGD_HW | LOGD_DEVICE,
10861 "previous hardware address is no longer valid");
10862 _notify (self, PROP_HW_ADDRESS);
10868 nm_device_update_initial_hw_address (NMDevice *self)
10870 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10872 if (priv->hw_addr_len) {
10873 priv->initial_hw_addr = g_strdup (priv->hw_addr);
10874 _LOGD (LOGD_DEVICE | LOGD_HW, "read initial MAC address %s", priv->initial_hw_addr);
10876 if (priv->ifindex > 0) {
10877 guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
10880 if (nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len)) {
10881 g_warn_if_fail (len == priv->hw_addr_len);
10882 priv->perm_hw_addr = nm_utils_hwaddr_ntoa (buf, priv->hw_addr_len);
10883 _LOGD (LOGD_DEVICE | LOGD_HW, "read permanent MAC address %s",
10884 priv->perm_hw_addr);
10886 /* Fall back to current address */
10887 _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address");
10888 priv->perm_hw_addr = g_strdup (priv->hw_addr);
10895 nm_device_set_hw_addr (NMDevice *self, const char *addr,
10896 const char *detail, guint64 hw_log_domain)
10898 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10899 gboolean success = FALSE;
10900 const char *cur_addr = nm_device_get_hw_address (self);
10901 guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX];
10903 /* Fall back to the permanent address */
10905 addr = priv->perm_hw_addr;
10909 /* Do nothing if current MAC is same */
10910 if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
10911 _LOGD (LOGD_DEVICE | hw_log_domain, "no MAC address change needed");
10914 if (!nm_utils_hwaddr_aton (addr, addr_bytes, priv->hw_addr_len)) {
10915 _LOGW (LOGD_DEVICE | hw_log_domain, "invalid MAC address %s", addr);
10919 /* Can't change MAC address while device is up */
10920 nm_device_take_down (self, FALSE);
10922 success = nm_platform_link_set_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), addr_bytes, priv->hw_addr_len);
10924 /* MAC address succesfully changed; update the current MAC to match */
10925 nm_device_update_hw_address (self);
10926 cur_addr = nm_device_get_hw_address (self);
10927 if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) {
10928 _LOGI (LOGD_DEVICE | hw_log_domain, "%s MAC address to %s",
10931 _LOGW (LOGD_DEVICE | hw_log_domain,
10932 "new MAC address %s not successfully set", addr);
10936 _LOGW (LOGD_DEVICE | hw_log_domain, "failed to %s MAC address to %s",
10939 nm_device_bring_up (self, TRUE, NULL);
10945 nm_device_get_permanent_hw_address (NMDevice *self)
10947 g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
10949 return NM_DEVICE_GET_PRIVATE (self)->perm_hw_addr;
10953 nm_device_get_initial_hw_address (NMDevice *self)
10955 g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
10957 return NM_DEVICE_GET_PRIVATE (self)->initial_hw_addr;
10961 * nm_device_spec_match_list:
10962 * @self: an #NMDevice
10963 * @specs: (element-type utf8): a list of device specs
10965 * Checks if @self matches any of the specifications in @specs. The
10966 * currently-supported spec types are:
10968 * "mac:00:11:22:33:44:55" - matches a device with the given
10971 * "interface-name:foo0" - matches a device with the given
10974 * "s390-subchannels:00.11.22" - matches a device with the given
10975 * z/VM / s390 subchannels.
10977 * "*" - matches any device
10979 * Returns: #TRUE if @self matches one of the specs in @specs
10982 nm_device_spec_match_list (NMDevice *self, const GSList *specs)
10984 g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
10989 return NM_DEVICE_GET_CLASS (self)->spec_match_list (self, specs) == NM_MATCH_SPEC_MATCH;
10992 static NMMatchSpecMatchType
10993 spec_match_list (NMDevice *self, const GSList *specs)
10995 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
10996 NMMatchSpecMatchType matched = NM_MATCH_SPEC_NO_MATCH, m;
10997 const GSList *iter;
10999 for (iter = specs; iter; iter = g_slist_next (iter)) {
11000 if (!strcmp ((const char *) iter->data, "*")) {
11001 matched = NM_MATCH_SPEC_MATCH;
11005 if (priv->hw_addr_len && priv->hw_addr) {
11006 m = nm_match_spec_hwaddr (specs, priv->hw_addr);
11007 matched = MAX (matched, m);
11009 if (matched != NM_MATCH_SPEC_NEG_MATCH) {
11010 m = nm_match_spec_interface_name (specs, nm_device_get_iface (self));
11011 matched = MAX (matched, m);
11013 if (matched != NM_MATCH_SPEC_NEG_MATCH) {
11014 m = nm_match_spec_device_type (specs, nm_device_get_type_description (self));
11015 matched = MAX (matched, m);
11020 /***********************************************************/
11022 static const char *
11023 _activation_func_to_string (ActivationHandleFunc func)
11025 #define FUNC_TO_STRING_CHECK_AND_RETURN(func, f) \
11027 if ((func) == (f)) \
11030 FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage1_device_prepare);
11031 FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage2_device_config);
11032 FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage3_ip_config_start);
11033 FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage4_ip4_config_timeout);
11034 FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage4_ip6_config_timeout);
11035 FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage5_ip4_config_commit);
11036 FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage5_ip6_config_commit);
11037 g_return_val_if_reached ("unknown");
11040 /***********************************************************/
11043 nm_device_init (NMDevice *self)
11045 NMDevicePrivate *priv;
11047 priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DEVICE, NMDevicePrivate);
11051 priv->type = NM_DEVICE_TYPE_UNKNOWN;
11052 priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED;
11053 priv->state = NM_DEVICE_STATE_UNMANAGED;
11054 priv->state_reason = NM_DEVICE_STATE_REASON_NONE;
11055 priv->dhcp_timeout = 0;
11056 priv->rfkill_type = RFKILL_TYPE_UNKNOWN;
11057 priv->autoconnect = DEFAULT_AUTOCONNECT;
11058 priv->unmanaged_flags = NM_UNMANAGED_PLATFORM_INIT;
11059 priv->unmanaged_mask = priv->unmanaged_flags;
11060 priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
11061 priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
11063 priv->default_route.v4_is_assumed = TRUE;
11064 priv->default_route.v6_is_assumed = TRUE;
11066 priv->v4_commit_first_time = TRUE;
11067 priv->v6_commit_first_time = TRUE;
11071 constructor (GType type,
11072 guint n_construct_params,
11073 GObjectConstructParam *construct_params)
11076 GObjectClass *klass;
11078 NMDevicePrivate *priv;
11079 const NMPlatformLink *pllink;
11081 klass = G_OBJECT_CLASS (nm_device_parent_class);
11082 object = klass->constructor (type, n_construct_params, construct_params);
11086 self = NM_DEVICE (object);
11087 priv = NM_DEVICE_GET_PRIVATE (self);
11090 pllink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, priv->iface);
11092 if (pllink && link_type_compatible (self, pllink->type, NULL, NULL)) {
11093 priv->ifindex = pllink->ifindex;
11094 priv->up = NM_FLAGS_HAS (pllink->n_ifi_flags, IFF_UP);
11102 constructed (GObject *object)
11104 NMDevice *self = NM_DEVICE (object);
11105 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
11106 NMPlatform *platform;
11108 platform = nm_platform_get ();
11110 if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities)
11111 priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self);
11113 /* Watch for external IP config changes */
11114 g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (device_ipx_changed), self);
11115 g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (device_ipx_changed), self);
11116 g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self);
11117 g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self);
11118 g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), self);
11120 priv->con_provider = nm_connection_provider_get ();
11121 g_assert (priv->con_provider);
11122 g_signal_connect (priv->con_provider,
11123 NM_CP_SIGNAL_CONNECTION_ADDED,
11124 G_CALLBACK (cp_connection_added_or_updated),
11127 g_signal_connect (priv->con_provider,
11128 NM_CP_SIGNAL_CONNECTION_REMOVED,
11129 G_CALLBACK (cp_connection_removed),
11132 g_signal_connect (priv->con_provider,
11133 NM_CP_SIGNAL_CONNECTION_UPDATED,
11134 G_CALLBACK (cp_connection_added_or_updated),
11137 G_OBJECT_CLASS (nm_device_parent_class)->constructed (object);
11139 _LOGD (LOGD_DEVICE, "constructed (%s)", G_OBJECT_TYPE_NAME (self));
11143 dispose (GObject *object)
11145 NMDevice *self = NM_DEVICE (object);
11146 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
11147 NMPlatform *platform;
11149 _LOGD (LOGD_DEVICE, "disposing");
11151 g_slist_free_full (priv->arping.dad_list, (GDestroyNotify) nm_arping_manager_destroy);
11152 priv->arping.dad_list = NULL;
11154 arp_cleanup (self);
11156 g_signal_handlers_disconnect_by_func (nm_config_get (), config_changed_update_ignore_carrier, self);
11158 dispatcher_cleanup (self);
11160 _cleanup_generic_pre (self, CLEANUP_TYPE_KEEP);
11162 g_warn_if_fail (priv->slaves == NULL);
11163 g_assert (priv->master_ready_id == 0);
11165 /* Let the kernel manage IPv6LL again */
11166 set_nm_ipv6ll (self, FALSE);
11168 _cleanup_generic_post (self, CLEANUP_TYPE_KEEP);
11170 g_hash_table_remove_all (priv->ip6_saved_properties);
11172 nm_clear_g_source (&priv->recheck_assume_id);
11173 nm_clear_g_source (&priv->recheck_available.call_id);
11175 nm_clear_g_source (&priv->check_delete_unrealized_id);
11177 link_disconnect_action_cancel (self);
11179 if (priv->con_provider) {
11180 g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_added_or_updated, self);
11181 g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_removed, self);
11182 priv->con_provider = NULL;
11185 available_connections_del_all (self);
11187 nm_clear_g_source (&priv->carrier_wait_id);
11189 _clear_queued_act_request (priv);
11191 platform = nm_platform_get ();
11192 g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ipx_changed), self);
11193 g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (link_changed_cb), self);
11195 nm_clear_g_source (&priv->device_link_changed_id);
11196 nm_clear_g_source (&priv->device_ip_link_changed_id);
11198 if (priv->lldp_listener) {
11199 g_signal_handlers_disconnect_by_func (priv->lldp_listener,
11200 G_CALLBACK (lldp_neighbors_changed),
11202 nm_lldp_listener_stop (priv->lldp_listener);
11203 g_clear_object (&priv->lldp_listener);
11206 G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
11208 if (nm_clear_g_source (&priv->queued_state.id)) {
11209 /* FIXME: we'd expect the queud_state to be alredy cleared and this statement
11210 * not being necessary. Add this check here to hopefully investigate crash
11212 g_return_if_reached ();
11217 finalize (GObject *object)
11219 NMDevice *self = NM_DEVICE (object);
11220 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
11222 _LOGD (LOGD_DEVICE, "finalize(): %s", G_OBJECT_TYPE_NAME (self));
11224 g_free (priv->hw_addr);
11225 g_free (priv->perm_hw_addr);
11226 g_free (priv->initial_hw_addr);
11227 g_slist_free_full (priv->pending_actions, g_free);
11228 g_slist_free_full (priv->dad6_failed_addrs, g_free);
11229 g_clear_pointer (&priv->physical_port_id, g_free);
11230 g_free (priv->udi);
11231 g_free (priv->iface);
11232 g_free (priv->ip_iface);
11233 g_free (priv->driver);
11234 g_free (priv->driver_version);
11235 g_free (priv->firmware_version);
11236 g_free (priv->type_desc);
11237 g_free (priv->type_description);
11238 g_free (priv->dhcp_anycast_address);
11240 g_hash_table_unref (priv->ip6_saved_properties);
11241 g_hash_table_unref (priv->available_connections);
11243 G_OBJECT_CLASS (nm_device_parent_class)->finalize (object);
11247 set_property (GObject *object, guint prop_id,
11248 const GValue *value, GParamSpec *pspec)
11250 NMDevice *self = NM_DEVICE (object);
11251 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
11252 const char *hw_addr, *p;
11257 if (g_value_get_string (value)) {
11258 g_free (priv->udi);
11259 priv->udi = g_value_dup_string (value);
11263 /* construct only */
11264 g_return_if_fail (!priv->iface);
11265 priv->iface = g_value_dup_string (value);
11268 if (g_value_get_string (value)) {
11269 g_free (priv->driver);
11270 priv->driver = g_value_dup_string (value);
11273 case PROP_DRIVER_VERSION:
11274 g_free (priv->driver_version);
11275 priv->driver_version = g_strdup (g_value_get_string (value));
11277 case PROP_FIRMWARE_VERSION:
11278 g_free (priv->firmware_version);
11279 priv->firmware_version = g_strdup (g_value_get_string (value));
11282 priv->mtu = g_value_get_uint (value);
11284 case PROP_IP4_ADDRESS:
11285 priv->ip4_address = g_value_get_uint (value);
11287 case PROP_MANAGED: {
11289 NMDeviceStateReason reason;
11291 managed = g_value_get_boolean (value);
11293 reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED;
11295 reason = NM_DEVICE_STATE_REASON_REMOVED;
11296 nm_device_set_unmanaged_by_flags (self,
11297 NM_UNMANAGED_USER_EXPLICIT,
11302 case PROP_AUTOCONNECT:
11303 nm_device_set_autoconnect (self, g_value_get_boolean (value));
11305 case PROP_FIRMWARE_MISSING:
11306 /* construct only */
11307 priv->firmware_missing = g_value_get_boolean (value);
11309 case PROP_NM_PLUGIN_MISSING:
11310 priv->nm_plugin_missing = g_value_get_boolean (value);
11312 case PROP_DEVICE_TYPE:
11313 g_return_if_fail (priv->type == NM_DEVICE_TYPE_UNKNOWN);
11314 priv->type = g_value_get_uint (value);
11316 case PROP_LINK_TYPE:
11317 /* construct only */
11318 g_return_if_fail (priv->link_type == NM_LINK_TYPE_NONE);
11319 priv->link_type = g_value_get_uint (value);
11321 case PROP_TYPE_DESC:
11322 g_free (priv->type_desc);
11323 priv->type_desc = g_value_dup_string (value);
11325 case PROP_RFKILL_TYPE:
11326 priv->rfkill_type = g_value_get_uint (value);
11328 case PROP_IS_MASTER:
11329 priv->is_master = g_value_get_boolean (value);
11331 case PROP_HW_ADDRESS:
11332 /* construct only */
11333 p = hw_addr = g_value_get_string (value);
11335 /* Hardware address length is the number of ':' plus 1 */
11341 if (count < ETH_ALEN || count > NM_UTILS_HWADDR_LEN_MAX) {
11342 if (hw_addr && *hw_addr) {
11343 _LOGW (LOGD_DEVICE, "ignoring hardware address '%s' with unexpected length %d",
11349 priv->hw_addr_len = count;
11350 g_free (priv->hw_addr);
11351 if (nm_utils_hwaddr_valid (hw_addr, priv->hw_addr_len))
11352 priv->hw_addr = g_strdup (hw_addr);
11354 _LOGW (LOGD_DEVICE, "could not parse hw-address '%s'", hw_addr);
11355 priv->hw_addr = NULL;
11359 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
11365 get_property (GObject *object, guint prop_id,
11366 GValue *value, GParamSpec *pspec)
11368 NMDevice *self = NM_DEVICE (object);
11369 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
11371 GHashTableIter iter;
11372 NMConnection *connection;
11373 GVariantBuilder array_builder;
11377 g_value_set_string (value, priv->udi);
11380 g_value_set_string (value, priv->iface);
11382 case PROP_IP_IFACE:
11383 if (ip_config_valid (priv->state))
11384 g_value_set_string (value, nm_device_get_ip_iface (self));
11386 g_value_set_string (value, NULL);
11389 g_value_set_int (value, priv->ifindex);
11392 g_value_set_string (value, priv->driver);
11394 case PROP_DRIVER_VERSION:
11395 g_value_set_string (value, priv->driver_version);
11397 case PROP_FIRMWARE_VERSION:
11398 g_value_set_string (value, priv->firmware_version);
11400 case PROP_CAPABILITIES:
11401 g_value_set_uint (value, (priv->capabilities & ~NM_DEVICE_CAP_INTERNAL_MASK));
11403 case PROP_IP4_ADDRESS:
11404 g_value_set_uint (value, priv->ip4_address);
11407 g_value_set_boolean (value, priv->carrier);
11410 g_value_set_uint (value, priv->mtu);
11412 case PROP_IP4_CONFIG:
11413 nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip4_config : NULL);
11415 case PROP_DHCP4_CONFIG:
11416 nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp4_config : NULL);
11418 case PROP_IP6_CONFIG:
11419 nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip6_config : NULL);
11421 case PROP_DHCP6_CONFIG:
11422 nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp6_config : NULL);
11425 g_value_set_uint (value, priv->state);
11427 case PROP_STATE_REASON:
11428 g_value_take_variant (value,
11429 g_variant_new ("(uu)", priv->state, priv->state_reason));
11431 case PROP_ACTIVE_CONNECTION:
11432 nm_utils_g_value_set_object_path (value, priv->act_request);
11434 case PROP_DEVICE_TYPE:
11435 g_value_set_uint (value, priv->type);
11437 case PROP_LINK_TYPE:
11438 g_value_set_uint (value, priv->link_type);
11441 /* The managed state exposed on D-Bus only depends on the current device state alone. */
11442 g_value_set_boolean (value, nm_device_get_state (self) > NM_DEVICE_STATE_UNMANAGED);
11444 case PROP_AUTOCONNECT:
11445 g_value_set_boolean (value, priv->autoconnect);
11447 case PROP_FIRMWARE_MISSING:
11448 g_value_set_boolean (value, priv->firmware_missing);
11450 case PROP_NM_PLUGIN_MISSING:
11451 g_value_set_boolean (value, priv->nm_plugin_missing);
11453 case PROP_TYPE_DESC:
11454 g_value_set_string (value, priv->type_desc);
11456 case PROP_RFKILL_TYPE:
11457 g_value_set_uint (value, priv->rfkill_type);
11459 case PROP_AVAILABLE_CONNECTIONS:
11460 array = g_ptr_array_sized_new (g_hash_table_size (priv->available_connections));
11461 g_hash_table_iter_init (&iter, priv->available_connections);
11462 while (g_hash_table_iter_next (&iter, (gpointer) &connection, NULL))
11463 g_ptr_array_add (array, g_strdup (nm_connection_get_path (connection)));
11464 g_ptr_array_add (array, NULL);
11465 g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE));
11467 case PROP_PHYSICAL_PORT_ID:
11468 g_value_set_string (value, priv->physical_port_id);
11470 case PROP_IS_MASTER:
11471 g_value_set_boolean (value, priv->is_master);
11474 g_value_set_object (value, nm_device_get_master (self));
11476 case PROP_HW_ADDRESS:
11477 g_value_set_string (value, priv->hw_addr);
11479 case PROP_HAS_PENDING_ACTION:
11480 g_value_set_boolean (value, nm_device_has_pending_action (self));
11483 g_value_set_uint (value, priv->metered);
11485 case PROP_LLDP_NEIGHBORS:
11486 if (priv->lldp_listener)
11487 g_value_set_variant (value, nm_lldp_listener_get_neighbors (priv->lldp_listener));
11489 g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}"));
11490 g_value_take_variant (value, g_variant_builder_end (&array_builder));
11494 g_value_set_boolean (value, nm_device_is_real (self));
11496 case PROP_SLAVES: {
11497 GSList *slave_iter;
11501 slave_list = g_new (char *, g_slist_length (priv->slaves) + 1);
11502 for (slave_iter = priv->slaves, i = 0; slave_iter; slave_iter = slave_iter->next) {
11503 SlaveInfo *info = slave_iter->data;
11506 if (!NM_DEVICE_GET_PRIVATE (info->slave)->is_enslaved)
11508 path = nm_exported_object_get_path ((NMExportedObject *) info->slave);
11510 slave_list[i++] = g_strdup (path);
11512 slave_list[i] = NULL;
11513 g_value_take_boxed (value, slave_list);
11517 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
11523 nm_device_class_init (NMDeviceClass *klass)
11525 GObjectClass *object_class = G_OBJECT_CLASS (klass);
11526 NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (klass);
11528 g_type_class_add_private (object_class, sizeof (NMDevicePrivate));
11530 exported_object_class->export_path = NM_DBUS_PATH "/Devices/%u";
11532 /* Virtual methods */
11533 object_class->dispose = dispose;
11534 object_class->finalize = finalize;
11535 object_class->set_property = set_property;
11536 object_class->get_property = get_property;
11537 object_class->constructor = constructor;
11538 object_class->constructed = constructed;
11540 klass->link_changed = link_changed;
11542 klass->is_available = is_available;
11543 klass->act_stage1_prepare = act_stage1_prepare;
11544 klass->act_stage2_config = act_stage2_config;
11545 klass->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
11546 klass->act_stage3_ip6_config_start = act_stage3_ip6_config_start;
11547 klass->act_stage4_ip4_config_timeout = act_stage4_ip4_config_timeout;
11548 klass->act_stage4_ip6_config_timeout = act_stage4_ip6_config_timeout;
11549 klass->have_any_ready_slaves = have_any_ready_slaves;
11551 klass->get_type_description = get_type_description;
11552 klass->spec_match_list = spec_match_list;
11553 klass->can_auto_connect = can_auto_connect;
11554 klass->check_connection_compatible = check_connection_compatible;
11555 klass->check_connection_available = check_connection_available;
11556 klass->can_unmanaged_external_down = can_unmanaged_external_down;
11557 klass->realize_start_notify = realize_start_notify;
11558 klass->unrealize_notify = unrealize_notify;
11559 klass->is_up = is_up;
11560 klass->bring_up = bring_up;
11561 klass->take_down = take_down;
11562 klass->carrier_changed = carrier_changed;
11563 klass->get_ip_iface_identifier = get_ip_iface_identifier;
11566 obj_properties[PROP_UDI] =
11567 g_param_spec_string (NM_DEVICE_UDI, "", "",
11569 G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
11570 G_PARAM_STATIC_STRINGS);
11571 obj_properties[PROP_IFACE] =
11572 g_param_spec_string (NM_DEVICE_IFACE, "", "",
11574 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11575 G_PARAM_STATIC_STRINGS);
11576 obj_properties[PROP_IP_IFACE] =
11577 g_param_spec_string (NM_DEVICE_IP_IFACE, "", "",
11580 G_PARAM_STATIC_STRINGS);
11581 obj_properties[PROP_DRIVER] =
11582 g_param_spec_string (NM_DEVICE_DRIVER, "", "",
11584 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11585 G_PARAM_STATIC_STRINGS);
11586 obj_properties[PROP_DRIVER_VERSION] =
11587 g_param_spec_string (NM_DEVICE_DRIVER_VERSION, "", "",
11589 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11590 G_PARAM_STATIC_STRINGS);
11591 obj_properties[PROP_FIRMWARE_VERSION] =
11592 g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, "", "",
11594 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11595 G_PARAM_STATIC_STRINGS);
11596 obj_properties[PROP_CAPABILITIES] =
11597 g_param_spec_uint (NM_DEVICE_CAPABILITIES, "", "",
11598 0, G_MAXUINT32, NM_DEVICE_CAP_NONE,
11600 G_PARAM_STATIC_STRINGS);
11601 obj_properties[PROP_CARRIER] =
11602 g_param_spec_boolean (NM_DEVICE_CARRIER, "", "",
11605 G_PARAM_STATIC_STRINGS);
11606 obj_properties[PROP_MTU] =
11607 g_param_spec_uint (NM_DEVICE_MTU, "", "",
11608 0, G_MAXUINT32, 1500,
11610 G_PARAM_STATIC_STRINGS);
11611 obj_properties[PROP_IP4_ADDRESS] =
11612 g_param_spec_uint (NM_DEVICE_IP4_ADDRESS, "", "",
11613 0, G_MAXUINT32, 0, /* FIXME */
11614 G_PARAM_READWRITE |
11615 G_PARAM_STATIC_STRINGS);
11616 obj_properties[PROP_IP4_CONFIG] =
11617 g_param_spec_string (NM_DEVICE_IP4_CONFIG, "", "",
11619 G_PARAM_READWRITE |
11620 G_PARAM_STATIC_STRINGS);
11621 obj_properties[PROP_DHCP4_CONFIG] =
11622 g_param_spec_string (NM_DEVICE_DHCP4_CONFIG, "", "",
11624 G_PARAM_READWRITE |
11625 G_PARAM_STATIC_STRINGS);
11626 obj_properties[PROP_IP6_CONFIG] =
11627 g_param_spec_string (NM_DEVICE_IP6_CONFIG, "", "",
11629 G_PARAM_READWRITE |
11630 G_PARAM_STATIC_STRINGS);
11631 obj_properties[PROP_DHCP6_CONFIG] =
11632 g_param_spec_string (NM_DEVICE_DHCP6_CONFIG, "", "",
11634 G_PARAM_READWRITE |
11635 G_PARAM_STATIC_STRINGS);
11636 obj_properties[PROP_STATE] =
11637 g_param_spec_uint (NM_DEVICE_STATE, "", "",
11638 0, G_MAXUINT32, NM_DEVICE_STATE_UNKNOWN,
11640 G_PARAM_STATIC_STRINGS);
11641 obj_properties[PROP_STATE_REASON] =
11642 g_param_spec_variant (NM_DEVICE_STATE_REASON, "", "",
11643 G_VARIANT_TYPE ("(uu)"),
11646 G_PARAM_STATIC_STRINGS);
11647 obj_properties[PROP_ACTIVE_CONNECTION] =
11648 g_param_spec_string (NM_DEVICE_ACTIVE_CONNECTION, "", "",
11651 G_PARAM_STATIC_STRINGS);
11652 obj_properties[PROP_DEVICE_TYPE] =
11653 g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, "", "",
11654 0, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN,
11655 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11656 G_PARAM_STATIC_STRINGS);
11657 obj_properties[PROP_LINK_TYPE] =
11658 g_param_spec_uint (NM_DEVICE_LINK_TYPE, "", "",
11659 0, G_MAXUINT32, NM_LINK_TYPE_NONE,
11660 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11661 G_PARAM_STATIC_STRINGS);
11662 obj_properties[PROP_MANAGED] =
11663 g_param_spec_boolean (NM_DEVICE_MANAGED, "", "",
11665 G_PARAM_READWRITE |
11666 G_PARAM_STATIC_STRINGS);
11667 obj_properties[PROP_AUTOCONNECT] =
11668 g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, "", "",
11669 DEFAULT_AUTOCONNECT,
11670 G_PARAM_READWRITE |
11671 G_PARAM_STATIC_STRINGS);
11672 obj_properties[PROP_FIRMWARE_MISSING] =
11673 g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, "", "",
11675 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11676 G_PARAM_STATIC_STRINGS);
11677 obj_properties[PROP_NM_PLUGIN_MISSING] =
11678 g_param_spec_boolean (NM_DEVICE_NM_PLUGIN_MISSING, "", "",
11680 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11681 G_PARAM_STATIC_STRINGS);
11682 obj_properties[PROP_TYPE_DESC] =
11683 g_param_spec_string (NM_DEVICE_TYPE_DESC, "", "",
11685 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11686 G_PARAM_STATIC_STRINGS);
11687 obj_properties[PROP_RFKILL_TYPE] =
11688 g_param_spec_uint (NM_DEVICE_RFKILL_TYPE, "", "",
11691 RFKILL_TYPE_UNKNOWN,
11692 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11693 G_PARAM_STATIC_STRINGS);
11694 obj_properties[PROP_IFINDEX] =
11695 g_param_spec_int (NM_DEVICE_IFINDEX, "", "",
11698 G_PARAM_STATIC_STRINGS);
11699 obj_properties[PROP_AVAILABLE_CONNECTIONS] =
11700 g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, "", "",
11703 G_PARAM_STATIC_STRINGS);
11704 obj_properties[PROP_PHYSICAL_PORT_ID] =
11705 g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, "", "",
11708 G_PARAM_STATIC_STRINGS);
11709 obj_properties[PROP_IS_MASTER] =
11710 g_param_spec_boolean (NM_DEVICE_IS_MASTER, "", "",
11712 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11713 G_PARAM_STATIC_STRINGS);
11714 obj_properties[PROP_MASTER] =
11715 g_param_spec_object (NM_DEVICE_MASTER, "", "",
11718 G_PARAM_STATIC_STRINGS);
11719 obj_properties[PROP_HW_ADDRESS] =
11720 g_param_spec_string (NM_DEVICE_HW_ADDRESS, "", "",
11722 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
11723 G_PARAM_STATIC_STRINGS);
11724 obj_properties[PROP_HAS_PENDING_ACTION] =
11725 g_param_spec_boolean (NM_DEVICE_HAS_PENDING_ACTION, "", "",
11728 G_PARAM_STATIC_STRINGS);
11731 * NMDevice:metered:
11733 * Whether the connection is metered.
11737 obj_properties[PROP_METERED] =
11738 g_param_spec_uint (NM_DEVICE_METERED, "", "",
11739 0, G_MAXUINT32, NM_METERED_UNKNOWN,
11741 G_PARAM_STATIC_STRINGS);
11742 obj_properties[PROP_LLDP_NEIGHBORS] =
11743 g_param_spec_variant (NM_DEVICE_LLDP_NEIGHBORS, "", "",
11744 G_VARIANT_TYPE ("aa{sv}"),
11747 G_PARAM_STATIC_STRINGS);
11748 obj_properties[PROP_REAL] =
11749 g_param_spec_boolean (NM_DEVICE_REAL, "", "",
11752 G_PARAM_STATIC_STRINGS);
11753 obj_properties[PROP_SLAVES] =
11754 g_param_spec_boxed (NM_DEVICE_SLAVES, "", "",
11757 G_PARAM_STATIC_STRINGS);
11759 g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
11762 signals[STATE_CHANGED] =
11763 g_signal_new (NM_DEVICE_STATE_CHANGED,
11764 G_OBJECT_CLASS_TYPE (object_class),
11766 G_STRUCT_OFFSET (NMDeviceClass, state_changed),
11769 G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
11771 signals[AUTOCONNECT_ALLOWED] =
11772 g_signal_new ("autoconnect-allowed",
11773 G_OBJECT_CLASS_TYPE (object_class),
11776 autoconnect_allowed_accumulator, NULL, NULL,
11777 G_TYPE_BOOLEAN, 0);
11779 signals[AUTH_REQUEST] =
11780 g_signal_new (NM_DEVICE_AUTH_REQUEST,
11781 G_OBJECT_CLASS_TYPE (object_class),
11782 G_SIGNAL_RUN_FIRST,
11783 0, NULL, NULL, NULL,
11784 /* context, connection, permission, allow_interaction, callback, user_data */
11785 G_TYPE_NONE, 6, G_TYPE_DBUS_METHOD_INVOCATION, NM_TYPE_CONNECTION, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER, G_TYPE_POINTER);
11787 signals[IP4_CONFIG_CHANGED] =
11788 g_signal_new (NM_DEVICE_IP4_CONFIG_CHANGED,
11789 G_OBJECT_CLASS_TYPE (object_class),
11790 G_SIGNAL_RUN_FIRST,
11791 0, NULL, NULL, NULL,
11792 G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT);
11794 signals[IP6_CONFIG_CHANGED] =
11795 g_signal_new (NM_DEVICE_IP6_CONFIG_CHANGED,
11796 G_OBJECT_CLASS_TYPE (object_class),
11797 G_SIGNAL_RUN_FIRST,
11798 0, NULL, NULL, NULL,
11799 G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT);
11802 g_signal_new (NM_DEVICE_REMOVED,
11803 G_OBJECT_CLASS_TYPE (object_class),
11804 G_SIGNAL_RUN_FIRST,
11805 0, NULL, NULL, NULL,
11808 signals[RECHECK_AUTO_ACTIVATE] =
11809 g_signal_new (NM_DEVICE_RECHECK_AUTO_ACTIVATE,
11810 G_OBJECT_CLASS_TYPE (object_class),
11811 G_SIGNAL_RUN_FIRST,
11812 0, NULL, NULL, NULL,
11815 signals[RECHECK_ASSUME] =
11816 g_signal_new (NM_DEVICE_RECHECK_ASSUME,
11817 G_OBJECT_CLASS_TYPE (object_class),
11818 G_SIGNAL_RUN_FIRST,
11819 0, NULL, NULL, NULL,
11822 nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
11823 NMDBUS_TYPE_DEVICE_SKELETON,
11824 "Reapply", impl_device_reapply,
11825 "GetAppliedConnection", impl_device_get_applied_connection,
11826 "Disconnect", impl_device_disconnect,
11827 "Delete", impl_device_delete,