diff options
| author | Michael Biebl <biebl@debian.org> | 2018-07-01 20:58:23 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2018-07-01 20:58:23 +0200 |
| commit | 429393567647935d9123e21fd27a7529d50255eb (patch) | |
| tree | b5a99bf0cbbe77fccd7fee81caf71915ccf9eb96 /src | |
| parent | 069cb5c3a525ebcc19cc2927964258acaca87b13 (diff) | |
New upstream version 1.12.0 upstream/1.12.0
Diffstat (limited to 'src')
32 files changed, 619 insertions, 445 deletions
diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 22f7cdde..f59ec9ff 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -338,8 +338,6 @@ apply_bonding_config (NMDevice *device) set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_FAIL_OVER_MAC); set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_LACP_RATE); set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_LP_INTERVAL); - set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP); - set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA); set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_MIN_LINKS); set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE); set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_PRIMARY_RESELECT); @@ -348,6 +346,16 @@ apply_bonding_config (NMDevice *device) set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_USE_CARRIER); set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY); + /* num_grat_arp and num_unsol_na are actually the same attribute + * on kernel side and their value in the bond setting is guaranteed + * to be equal. Write only one of the two. + */ + value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP); + if (value) + set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, value); + else + set_simple_option (device, mode, s_bond, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA); + return NM_ACT_STAGE_RETURN_SUCCESS; } diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 87d16dbe..a9a9f968 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -1317,13 +1317,13 @@ act_stage3_ip4_config_start (NMDevice *device, } static guint32 -get_configured_mtu (NMDevice *device, gboolean *out_is_user_config) +get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) { /* MTU only set for plain ethernet */ if (NM_DEVICE_ETHERNET_GET_PRIVATE ((NMDeviceEthernet *) device)->ppp_manager) return 0; - return nm_device_get_configured_mtu_for_wired (device, out_is_user_config); + return nm_device_get_configured_mtu_for_wired (device, out_source); } static void diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index d8e30346..bc717bb3 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -35,8 +35,6 @@ #define PLUGIN_PREFIX "libnm-device-plugin-" -static NM_CACHED_QUARK_FCN ("NMManager-plugin-path", plugin_path_quark) - /*****************************************************************************/ enum { @@ -303,7 +301,10 @@ _add_factory (NMDeviceFactory *factory, nm_device_factory_get_supported_types (factory, &link_types, &setting_types); - g_object_set_qdata_full (G_OBJECT (factory), plugin_path_quark (), g_strdup (path), g_free); + g_return_val_if_fail ( (link_types && link_types[0] > NM_LINK_TYPE_UNKNOWN) + || (setting_types && setting_types[0]), + FALSE); + for (i = 0; link_types && link_types[i] > NM_LINK_TYPE_UNKNOWN; i++) g_hash_table_insert (factories_by_link, GUINT_TO_POINTER (link_types[i]), g_object_ref (factory)); for (i = 0; setting_types && setting_types[i]; i++) { @@ -319,7 +320,12 @@ _add_factory (NMDeviceFactory *factory, callback (factory, user_data); - nm_log_info (LOGD_PLATFORM, "Loaded device plugin: %s (%s)", G_OBJECT_TYPE_NAME (factory), path); + nm_log (path ? LOGL_INFO : LOGL_DEBUG, + LOGD_PLATFORM, + NULL, NULL, + "Loaded device plugin: %s (%s)", + G_OBJECT_TYPE_NAME (factory), + path ?: "internal"); return TRUE; } @@ -328,10 +334,10 @@ _load_internal_factory (GType factory_gtype, NMDeviceFactoryManagerFactoryFunc callback, gpointer user_data) { - NMDeviceFactory *factory; + gs_unref_object NMDeviceFactory *factory = NULL; factory = (NMDeviceFactory *) g_object_new (factory_gtype, NULL); - _add_factory (factory, "internal", callback, user_data); + _add_factory (factory, NULL, callback, user_data); } static void diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index 781bbd69..99bcef00 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -115,29 +115,11 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) } static guint32 -get_configured_mtu (NMDevice *device, gboolean *out_is_user_config) +get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) { - NMSettingInfiniband *setting; - gint64 mtu_default; - guint32 mtu; - - nm_assert (NM_IS_DEVICE (device)); - nm_assert (out_is_user_config); - - setting = NM_SETTING_INFINIBAND (nm_device_get_applied_setting (device, NM_TYPE_SETTING_INFINIBAND)); - if (!setting) - g_return_val_if_reached (0); - - mtu = nm_setting_infiniband_get_mtu (setting); - if (mtu == 0) { - mtu_default = nm_device_get_configured_mtu_from_connection_default (device, "infiniband.mtu"); - if (mtu_default >= 0) { - *out_is_user_config = TRUE; - return (guint32) mtu_default; - } - } - *out_is_user_config = (mtu != 0); - return mtu; + return nm_device_get_configured_mtu_from_connection (device, + NM_TYPE_SETTING_INFINIBAND, + out_source); } static gboolean diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c index 59ca9ed5..2e266bb9 100644 --- a/src/devices/nm-device-ip-tunnel.c +++ b/src/devices/nm-device-ip-tunnel.c @@ -741,33 +741,15 @@ create_and_realize (NMDevice *device, } static guint32 -get_configured_mtu (NMDevice *self, gboolean *out_is_user_config) +get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) { - NMSettingIPTunnel *setting; - gint64 mtu_default; - guint32 mtu; - - nm_assert (NM_IS_DEVICE (self)); - nm_assert (out_is_user_config); - - setting = NM_SETTING_IP_TUNNEL (nm_device_get_applied_setting (self, NM_TYPE_SETTING_IP_TUNNEL)); - if (!setting) - g_return_val_if_reached (0); - - mtu = nm_setting_ip_tunnel_get_mtu (setting); - if (mtu == 0) { - mtu_default = nm_device_get_configured_mtu_from_connection_default (self, "ip-tunnel.mtu"); - if (mtu_default >= 0) { - *out_is_user_config = TRUE; - return (guint32) mtu_default; - } - } - *out_is_user_config = (mtu != 0); - return mtu; + return nm_device_get_configured_mtu_from_connection (device, + NM_TYPE_SETTING_IP_TUNNEL, + out_source); } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities (NMDevice *device) { return NM_DEVICE_CAP_IS_SOFTWARE; } diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index c76debff..ba28e9e4 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -120,7 +120,11 @@ gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const gint64 nm_device_get_configured_mtu_from_connection_default (NMDevice *self, const char *property_name); -guint32 nm_device_get_configured_mtu_for_wired (NMDevice *self, gboolean *out_is_user_config); +guint32 nm_device_get_configured_mtu_from_connection (NMDevice *device, + GType setting_type, + NMDeviceMtuSource *out_source); + +guint32 nm_device_get_configured_mtu_for_wired (NMDevice *self, NMDeviceMtuSource *out_source); void nm_device_commit_mtu (NMDevice *self); diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index a7f4c4bc..b0e746a8 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -534,19 +534,21 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) } static guint32 -get_configured_mtu (NMDevice *self, gboolean *out_is_user_config) +get_configured_mtu (NMDevice *self, NMDeviceMtuSource *out_source) { guint32 mtu = 0; int ifindex; - mtu = nm_device_get_configured_mtu_for_wired (self, out_is_user_config); - if (*out_is_user_config) + mtu = nm_device_get_configured_mtu_for_wired (self, out_source); + if (*out_source != NM_DEVICE_MTU_SOURCE_NONE) return mtu; /* Inherit the MTU from parent device, if any */ ifindex = nm_device_parent_get_ifindex (self); - if (ifindex > 0) + if (ifindex > 0) { mtu = nm_platform_link_get_mtu (nm_device_get_platform (NM_DEVICE (self)), ifindex); + *out_source = NM_DEVICE_MTU_SOURCE_PARENT; + } return mtu; } diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 9df41410..5a5cb50e 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -280,11 +280,6 @@ typedef struct _NMDevicePrivate { bool real:1; - /* there was a IP config change, but no idle action was scheduled because device - * is still not platform-init */ - bool queued_ip4_config_pending:1; - bool queued_ip6_config_pending:1; - bool update_ip_config_completed_v4:1; bool update_ip_config_completed_v6:1; @@ -349,8 +344,9 @@ typedef struct _NMDevicePrivate { gulong config_changed_id; guint32 mtu; guint32 ip6_mtu; - guint32 mtu_initial; - guint32 ip6_mtu_initial; + guint32 mtu_initial; + guint32 ip6_mtu_initial; + NMDeviceMtuSource mtu_source; guint32 v4_route_table; guint32 v6_route_table; @@ -366,8 +362,6 @@ typedef struct _NMDevicePrivate { bool carrier:1; bool ignore_carrier:1; - bool mtu_initialized:1; - bool up:1; /* IFF_UP */ bool v4_commit_first_time:1; @@ -735,6 +729,14 @@ NM_UTILS_LOOKUP_STR_DEFINE (nm_device_state_reason_to_str, NMDeviceStateReason, #define reason_to_string(reason) \ NM_UTILS_LOOKUP_STR (nm_device_state_reason_to_str, reason) +NM_UTILS_LOOKUP_STR_DEFINE_STATIC (mtu_source_to_str, NMDeviceMtuSource, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT ("unknown"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_MTU_SOURCE_NONE, "none"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_MTU_SOURCE_PARENT, "parent"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_MTU_SOURCE_IP_CONFIG, "ip-config"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_MTU_SOURCE_CONNECTION, "connection"), +); + /*****************************************************************************/ NMSettings * @@ -4001,7 +4003,7 @@ realize_start_setup (NMDevice *self, /* Balanced by a thaw in nm_device_realize_finish() */ g_object_freeze_notify (G_OBJECT (self)); - priv->mtu_initialized = FALSE; + priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE; priv->mtu_initial = 0; priv->ip6_mtu_initial = 0; priv->ip6_mtu = 0; @@ -4063,9 +4065,6 @@ realize_start_setup (NMDevice *self, _notify (self, PROP_UDI); } - priv->queued_ip4_config_pending = TRUE; - priv->queued_ip6_config_pending = TRUE; - nm_device_update_hw_address (self); nm_device_update_initial_hw_address (self); nm_device_update_permanent_hw_address (self, FALSE); @@ -6822,7 +6821,9 @@ static gboolean dhcp4_grace_period_expired (gpointer user_data) { NMDevice *self = user_data; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + priv->dhcp4.grace_id = 0; _LOGI (LOGD_DHCP4, "DHCPv4: grace period expired"); nm_device_ip_method_failed (self, AF_INET, @@ -7553,7 +7554,9 @@ static gboolean dhcp6_grace_period_expired (gpointer user_data) { NMDevice *self = user_data; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + priv->dhcp6.grace_id = 0; _LOGI (LOGD_DHCP6, "DHCPv6: grace period expired"); nm_device_ip_method_failed (self, AF_INET6, @@ -7828,7 +7831,7 @@ generate_duid_from_machine_id (void) } static GBytes * -dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, NMDhcpDuidEnforce *out_enforce) +dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, gboolean *out_enforce) { NMSettingIPConfig *s_ip6; const char *duid; @@ -7837,7 +7840,7 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, NMDhcp GBytes *duid_out; guint8 sha256_digest[32]; gsize len = sizeof (sha256_digest); - NMDhcpDuidEnforce duid_enforce = NM_DHCP_DUID_ENFORCE_ALWAYS; + gboolean duid_enforce = TRUE; gs_free char *logstr1 = NULL; s_ip6 = nm_connection_get_setting_ip6_config (connection); @@ -7852,7 +7855,7 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, NMDhcp } if (nm_streq (duid, "lease")) { - duid_enforce = NM_DHCP_DUID_ENFORCE_NEVER; + duid_enforce = FALSE; duid_out = generate_duid_from_machine_id (); if (!duid_out) { duid_error = "failure to read machine-id"; @@ -7972,7 +7975,7 @@ out_good: "ipv6.dhcp-duid: generate %s DUID '%s' (%s)", duid, (logstr1 = nm_dhcp_utils_duid_to_string (duid_out)), - (duid_enforce == NM_DHCP_DUID_ENFORCE_ALWAYS) ? "enforcing" : "fallback"); + duid_enforce ? "enforcing" : "prefer lease"); NM_SET_OUT (out_enforce, duid_enforce); return duid_out; @@ -7985,7 +7988,7 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) NMSettingIPConfig *s_ip6; gs_unref_bytes GBytes *hwaddr = NULL; gs_unref_bytes GBytes *duid = NULL; - NMDhcpDuidEnforce enforce_duid = NM_DHCP_DUID_ENFORCE_NEVER; + gboolean enforce_duid = FALSE; const NMPlatformIP6Address *ll_addr = NULL; @@ -8371,40 +8374,68 @@ nm_device_get_configured_mtu_from_connection_default (NMDevice *self, } guint32 -nm_device_get_configured_mtu_for_wired (NMDevice *self, gboolean *out_is_user_config) +nm_device_get_configured_mtu_from_connection (NMDevice *self, + GType setting_type, + NMDeviceMtuSource *out_source) { + const char *global_property_name; NMConnection *connection; - NMSettingWired *setting; + NMSetting *setting; gint64 mtu_default; - guint32 mtu; + guint32 mtu = 0; nm_assert (NM_IS_DEVICE (self)); - nm_assert (out_is_user_config); + nm_assert (out_source); connection = nm_device_get_applied_connection (self); if (!connection) g_return_val_if_reached (0); - setting = nm_connection_get_setting_wired (connection); + setting = nm_connection_get_setting (connection, setting_type); + + if (setting_type == NM_TYPE_SETTING_WIRED) { + if (setting) + mtu = nm_setting_wired_get_mtu (NM_SETTING_WIRED (setting)); + global_property_name = "ethernet.mtu"; + } else if (setting_type == NM_TYPE_SETTING_WIRELESS) { + if (setting) + mtu = nm_setting_wireless_get_mtu (NM_SETTING_WIRELESS (setting)); + global_property_name = "wifi.mtu"; + } else if (setting_type == NM_TYPE_SETTING_INFINIBAND) { + if (setting) + mtu = nm_setting_infiniband_get_mtu (NM_SETTING_INFINIBAND (setting)); + global_property_name = "infiniband.mtu"; + } else if (setting_type == NM_TYPE_SETTING_IP_TUNNEL) { + if (setting) + mtu = nm_setting_ip_tunnel_get_mtu (NM_SETTING_IP_TUNNEL (setting)); + global_property_name = "ip-tunnel.mtu"; + } else + g_return_val_if_reached (0); - if (setting) { - mtu = nm_setting_wired_get_mtu (setting); - if (mtu) { - *out_is_user_config = TRUE; - return mtu; - } + + if (mtu) { + *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; + return mtu; } - mtu_default = nm_device_get_configured_mtu_from_connection_default (self, "ethernet.mtu"); + mtu_default = nm_device_get_configured_mtu_from_connection_default (self, global_property_name); if (mtu_default >= 0) { - *out_is_user_config = TRUE; + *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; return (guint32) mtu_default; } - *out_is_user_config = FALSE; + *out_source = NM_DEVICE_MTU_SOURCE_NONE; return 0; } +guint32 +nm_device_get_configured_mtu_for_wired (NMDevice *self, NMDeviceMtuSource *out_source) +{ + return nm_device_get_configured_mtu_from_connection (self, + NM_TYPE_SETTING_WIRED, + out_source); +} + /*****************************************************************************/ static void @@ -8431,6 +8462,7 @@ static void _commit_mtu (NMDevice *self, const NMIP4Config *config) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDeviceMtuSource source = NM_DEVICE_MTU_SOURCE_NONE; guint32 ip6_mtu, ip6_mtu_orig; guint32 mtu_desired, mtu_desired_orig; guint32 mtu_plat; @@ -8440,6 +8472,7 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config) } ip6_mtu_sysctl = { 0, }; int ifindex; char sbuf[64], sbuf1[64], sbuf2[64]; + gboolean success = TRUE; ifindex = nm_device_get_ip_ifindex (self); if (ifindex <= 0) @@ -8453,7 +8486,6 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config) } { - gboolean mtu_is_user_config = FALSE; guint32 mtu = 0; /* preferably, get the MTU from explict user-configuration. @@ -8461,23 +8493,30 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config) * MTUs from DHCP/PPP) or maybe fallback to a device-specific MTU. */ if (NM_DEVICE_GET_CLASS (self)->get_configured_mtu) - mtu = NM_DEVICE_GET_CLASS (self)->get_configured_mtu (self, &mtu_is_user_config); + mtu = NM_DEVICE_GET_CLASS (self)->get_configured_mtu (self, &source); + + if ( config + && source < NM_DEVICE_MTU_SOURCE_IP_CONFIG + && nm_ip4_config_get_mtu (config)) { + mtu = nm_ip4_config_get_mtu (config); + source = NM_DEVICE_MTU_SOURCE_IP_CONFIG; + } + + if (mtu != 0) { + _LOGT (LOGD_DEVICE, + "mtu: value %u from source '%s' (%u), current source '%s' (%u)", + (guint) mtu, + mtu_source_to_str (source), (guint) source, + mtu_source_to_str (priv->mtu_source), (guint) priv->mtu_source); + } - if (mtu_is_user_config) + if ( mtu != 0 + && ( source > priv->mtu_source + || (priv->mtu_source == NM_DEVICE_MTU_SOURCE_PARENT && source == priv->mtu_source))) mtu_desired = mtu; else { - if (config) - mtu_desired = nm_ip4_config_get_mtu (config); - else - mtu_desired = 0; - if (!mtu_desired && !priv->mtu_initialized) { - /* there is no MTU specified, and this is the first commit of the MTU. - * Reset a per-device MTU default, as returned from get_configured_mtu(). - * - * The device might choose not to return a default MTU via get_configured_mtu() - * to suppress this behavior. */ - mtu_desired = mtu; - } + mtu_desired = 0; + source = NM_DEVICE_MTU_SOURCE_NONE; } } @@ -8499,7 +8538,7 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config) } ip6_mtu = priv->ip6_mtu; - if (!ip6_mtu && !priv->mtu_initialized) { + if (!ip6_mtu && priv->mtu_source == NM_DEVICE_MTU_SOURCE_NONE) { /* initially, if the IPv6 MTU is not specified, grow it as large as the * link MTU @mtu_desired. Only exception is, if @mtu_desired is so small * to disable IPv6. */ @@ -8507,8 +8546,6 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config) ip6_mtu = mtu_desired; } - priv->mtu_initialized = TRUE; - if (!ip6_mtu && !mtu_desired) return; @@ -8560,6 +8597,7 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config) if (mtu_desired && mtu_desired != mtu_plat) { if (nm_platform_link_set_mtu (nm_device_get_platform (self), ifindex, mtu_desired) == NM_PLATFORM_ERROR_CANT_SET_MTU) { anticipated_failure = TRUE; + success = FALSE; _LOGW (LOGD_DEVICE, "mtu: failure to set MTU. %s", NM_IS_DEVICE_VLAN (self) ? "Is the parent's MTU size large enough?" @@ -8581,10 +8619,15 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config) anticipated_failure && errsv == EINVAL ? ": Is the underlying MTU value successfully set?" : ""); + success = FALSE; } priv->carrier_wait_until_ms = nm_utils_get_monotonic_timestamp_ms () + CARRIER_WAIT_TIME_AFTER_MTU_MS; } } + + if (success && source != NM_DEVICE_MTU_SOURCE_NONE) + priv->mtu_source = source; + #undef _IP6_MTU_SYS } @@ -10178,13 +10221,13 @@ _cleanup_ip_pre (NMDevice *self, int addr_family, CleanupType cleanup_type) } if (IS_IPv4) { - priv->queued_ip4_config_pending = FALSE; dhcp4_cleanup (self, cleanup_type, FALSE); arp_cleanup (self); dnsmasq_cleanup (self); ipv4ll_cleanup (self); } else { - priv->queued_ip6_config_pending = FALSE; + g_slist_free_full (priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref); + priv->dad6_failed_addrs = NULL; g_clear_object (&priv->dad6_ip6_config); dhcp6_cleanup (self, cleanup_type, FALSE); nm_clear_g_source (&priv->linklocal6_timeout_id); @@ -12185,22 +12228,16 @@ static gboolean queued_ip_config_change (NMDevice *self, int addr_family) { NMDevicePrivate *priv; - gboolean need_ipv6ll = FALSE; const gboolean IS_IPv4 = (addr_family == AF_INET); - NMPlatform *platform; g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE); priv = NM_DEVICE_GET_PRIVATE (self); - nm_assert (IS_IPv4 ? !priv->queued_ip4_config_pending : !priv->queued_ip6_config_pending); - /* Wait for any queued state changes */ if (priv->queued_state.id) return G_SOURCE_CONTINUE; - priv->queued_ip_config_id_x[IS_IPv4] = 0; - /* If a commit is scheduled, this function would potentially interfere with * it changing IP configurations before they are applied. Postpone the * update in such case. @@ -12209,39 +12246,39 @@ queued_ip_config_change (NMDevice *self, int addr_family) IS_IPv4 ? activate_stage5_ip4_config_result : activate_stage5_ip6_config_commit, - addr_family)) { - if (IS_IPv4) { - priv->queued_ip4_config_pending = FALSE; - priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self); - } else { - priv->queued_ip6_config_pending = FALSE; - priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self); - } - _LOGT (LOGD_DEVICE, "IP%c update was postponed", - nm_utils_addr_family_to_char (addr_family)); - } else { - update_ip_config (self, addr_family); + addr_family)) + return G_SOURCE_CONTINUE; - if (!IS_IPv4) { - /* Check whether we need to complete waiting for link-local. - * We are also called from an idle handler, so no problem doing state transitions - * now. */ - linklocal6_check_complete (self); - } + priv->queued_ip_config_id_x[IS_IPv4] = 0; + + update_ip_config (self, addr_family); + + if (!IS_IPv4) { + /* Check whether we need to complete waiting for link-local. + * We are also called from an idle handler, so no problem doing state transitions + * now. */ + linklocal6_check_complete (self); } if (!IS_IPv4) { - if ( priv->state < NM_DEVICE_STATE_DEACTIVATING + NMPlatform *platform; + GSList *dad6_failed_addrs, *iter; + + dad6_failed_addrs = g_steal_pointer (&priv->dad6_failed_addrs); + + if ( priv->state > NM_DEVICE_STATE_DISCONNECTED + && priv->state < NM_DEVICE_STATE_DEACTIVATING + && !nm_device_sys_iface_state_is_external (self) && (platform = nm_device_get_platform (self)) && nm_platform_link_get (platform, priv->ifindex)) { + gboolean need_ipv6ll = FALSE; + NMNDiscConfigMap ndisc_config_changed = NM_NDISC_CONFIG_NONE; + /* Handle DAD failures */ - while (priv->dad6_failed_addrs) { - nm_auto_nmpobj const NMPObject *obj = NULL; + for (iter = dad6_failed_addrs; iter; iter = iter->next) { + const NMPObject *obj = iter->data; const NMPlatformIP6Address *addr; - obj = priv->dad6_failed_addrs->data; - priv->dad6_failed_addrs = g_slist_delete_link (priv->dad6_failed_addrs, priv->dad6_failed_addrs); - if (!nm_ndisc_dad_addr_is_fail_candidate (platform, obj)) continue; @@ -12253,9 +12290,12 @@ queued_ip_config_change (NMDevice *self, int addr_family) if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) need_ipv6ll = TRUE; else if (priv->ndisc) - nm_ndisc_dad_failed (priv->ndisc, &addr->address); + ndisc_config_changed |= nm_ndisc_dad_failed (priv->ndisc, &addr->address, FALSE); } + if (ndisc_config_changed != NM_NDISC_CONFIG_NONE) + nm_ndisc_emit_config_change (priv->ndisc, ndisc_config_changed); + /* If no IPv6 link-local address exists but other addresses do then we * must add the LL address to remain conformant with RFC 3513 chapter 2.1 * ("Addressing Model"): "All interfaces are required to have at least @@ -12264,14 +12304,14 @@ queued_ip_config_change (NMDevice *self, int addr_family) if ( priv->ip_config_6 && nm_ip6_config_get_num_addresses (priv->ip_config_6)) need_ipv6ll = TRUE; - if (need_ipv6ll) check_and_add_ipv6ll_addr (self); - } else { - g_slist_free_full (priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref); - priv->dad6_failed_addrs = NULL; } + g_slist_free_full (dad6_failed_addrs, (GDestroyNotify) nmp_object_unref); + } + + if (!IS_IPv4) { /* Check if DAD is still pending */ if ( priv->ip6_state == IP_CONF && priv->dad6_ip6_config @@ -12327,16 +12367,20 @@ device_ipx_changed (NMPlatform *platform, if (nm_device_get_ip_ifindex (self) != ifindex) return; + if (!nm_device_is_real (self)) + return; + + if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { + /* ignore all platform signals until the link is initialized in platform. */ + return; + } + priv = NM_DEVICE_GET_PRIVATE (self); switch (obj_type) { case NMP_OBJECT_TYPE_IP4_ADDRESS: case NMP_OBJECT_TYPE_IP4_ROUTE: - if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { - priv->queued_ip4_config_pending = TRUE; - nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_4)); - } else if (!priv->queued_ip_config_id_4) { - priv->queued_ip4_config_pending = FALSE; + if (!priv->queued_ip_config_id_4) { priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self); _LOGD (LOGD_DEVICE, "queued IP4 config change"); } @@ -12350,13 +12394,10 @@ device_ipx_changed (NMPlatform *platform, priv->dad6_failed_addrs = g_slist_prepend (priv->dad6_failed_addrs, (gpointer) nmp_object_ref (NMP_OBJECT_UP_CAST (addr))); } + /* fall through */ case NMP_OBJECT_TYPE_IP6_ROUTE: - if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { - priv->queued_ip6_config_pending = TRUE; - nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_6)); - } else if (!priv->queued_ip_config_id_6) { - priv->queued_ip6_config_pending = FALSE; + if (!priv->queued_ip_config_id_6) { priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self); _LOGD (LOGD_DEVICE, "queued IP6 config change"); } @@ -12623,17 +12664,11 @@ _set_unmanaged_flags (NMDevice *self, !!unmanaged); } - if (priv->queued_ip4_config_pending) { - priv->queued_ip4_config_pending = FALSE; - nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_4)); - priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self); - } - - if (priv->queued_ip6_config_pending) { - priv->queued_ip6_config_pending = FALSE; - nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_6)); - priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self); - } + /* trigger an initial update of IP configuration. */ + nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_4)); + nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_6)); + priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self); + priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self); if (!priv->pending_actions) { do_notify_has_pending_actions = TRUE; @@ -13623,7 +13658,7 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType clean NM_DEVICE_GET_CLASS (self)->deactivate_reset_hw_addr (self); } - priv->mtu_initialized = FALSE; + priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE; if (priv->mtu_initial || priv->ip6_mtu_initial) { ifindex = nm_device_get_ip_ifindex (self); @@ -13709,12 +13744,10 @@ nm_device_spawn_iface_helper (NMDevice *self) g_ptr_array_add (argv, g_strdup_printf ("%d %s", (int) stable_type, stable_id)); } - logging_backend = nm_config_get_is_debug (nm_config_get ()) - ? g_strdup ("debug") - : nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG, - NM_CONFIG_KEYFILE_GROUP_LOGGING, - NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND, - NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY); + logging_backend = nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG, + NM_CONFIG_KEYFILE_GROUP_LOGGING, + NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND, + NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY); if (logging_backend) { g_ptr_array_add (argv, g_strdup ("--logging-backend")); g_ptr_array_add (argv, logging_backend); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 0d4d5cf8..010a0521 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -44,6 +44,13 @@ typedef enum { NM_DEVICE_SYS_IFACE_STATE_REMOVED, } NMDeviceSysIfaceState; +typedef enum { + NM_DEVICE_MTU_SOURCE_NONE, + NM_DEVICE_MTU_SOURCE_PARENT, + NM_DEVICE_MTU_SOURCE_IP_CONFIG, + NM_DEVICE_MTU_SOURCE_CONNECTION, +} NMDeviceMtuSource; + static inline NMDeviceStateReason nm_device_state_reason_check (NMDeviceStateReason reason) { @@ -287,7 +294,7 @@ typedef struct _NMDeviceClass { NMConnection *connection, char **specific_object); - guint32 (*get_configured_mtu) (NMDevice *self, gboolean *out_is_user_config); + guint32 (*get_configured_mtu) (NMDevice *self, NMDeviceMtuSource *out_source); /* Checks whether the connection is compatible with the device using * only the devices type and characteristics. Does not use any live diff --git a/src/devices/ovs/nm-ovs-factory.c b/src/devices/ovs/nm-ovs-factory.c index 830f94fc..766c650b 100644 --- a/src/devices/ovs/nm-ovs-factory.c +++ b/src/devices/ovs/nm-ovs-factory.c @@ -80,14 +80,14 @@ new_device_from_type (const char *name, NMDeviceType device_type) if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE) { type = NM_TYPE_DEVICE_OVS_INTERFACE; - type_desc = "OpenVSwitch Interface"; + type_desc = "Open vSwitch Interface"; link_type = NM_LINK_TYPE_OPENVSWITCH; } else if (device_type == NM_DEVICE_TYPE_OVS_PORT) { type = NM_TYPE_DEVICE_OVS_PORT; - type_desc = "OpenVSwitch Port"; + type_desc = "Open vSwitch Port"; } else if (device_type == NM_DEVICE_TYPE_OVS_BRIDGE) { type = NM_TYPE_DEVICE_OVS_BRIDGE; - type_desc = "OpenVSwitch Bridge"; + type_desc = "Open vSwitch Bridge"; } else { return NULL; } diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index d28fcdbd..7667816a 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -73,7 +73,6 @@ typedef struct { GCancellable * cancellable; NMDeviceWifiCapabilities capabilities; NMActRequestGetSecretsCallId *wifi_secrets_id; - GDBusMethodInvocation *secrets_request; guint periodic_scan_id; bool enabled:1; bool can_scan:1; @@ -379,14 +378,6 @@ wifi_secrets_cancel (NMDeviceIwd *self) if (priv->wifi_secrets_id) nm_act_request_cancel_secrets (NULL, priv->wifi_secrets_id); nm_assert (!priv->wifi_secrets_id); - - if (priv->secrets_request) { - g_dbus_method_invocation_return_error_literal (priv->secrets_request, NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "NM secrets request cancelled"); - priv->secrets_request = NULL; - } - } static void @@ -545,7 +536,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; mode = nm_setting_wireless_get_mode (s_wireless); - if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_INFRA) != 0) + if (mode && g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_INFRA) != 0) return FALSE; /* 8021x networks can only be used if they've been provisioned on the IWD side and @@ -575,7 +566,7 @@ check_connection_available (NMDevice *device, /* Only Infrastrusture mode at this time */ mode = nm_setting_wireless_get_mode (s_wifi); - if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_INFRA) != 0) + if (mode && g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_INFRA) != 0) return FALSE; /* Hidden SSIDs not supported yet */ @@ -630,7 +621,7 @@ complete_connection (NMDevice *device, mode = s_wifi ? nm_setting_wireless_get_mode (s_wifi) : NULL; - if (s_wifi && !nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_INFRA)) { + if (mode && !nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_INFRA)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, @@ -806,7 +797,7 @@ can_auto_connect (NMDevice *device, /* Only Infrastrusture mode */ mode = nm_setting_wireless_get_mode (s_wifi); - if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_INFRA) != 0) + if (mode && g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_INFRA) != 0) return FALSE; /* Don't autoconnect to networks that have been tried at least once @@ -1001,6 +992,127 @@ scanning_prohibited (NMDeviceIwd *self, gboolean periodic) return !priv->can_scan; } +/* + * try_reply_agent_request + * + * Check if the connection settings already have the secrets corresponding + * to the IWD agent method that was invoked. If they do, send the method reply + * with the appropriate secrets. Otherwise return the missing secret's setting + * name and key so the caller can send a NM secrets request with this data. + * Return TRUE in either case, return FALSE if an error is detected. + */ +static gboolean +try_reply_agent_request (NMDeviceIwd *self, + NMConnection *connection, + GDBusMethodInvocation *invocation, + const gchar **setting_name, + const gchar **setting_key, + gboolean *replied) +{ + const gchar *method_name = g_dbus_method_invocation_get_method_name (invocation); + NMSettingWirelessSecurity *s_wireless_sec; + NMSetting8021x *s_8021x; + + s_wireless_sec = nm_connection_get_setting_wireless_security (connection); + s_8021x = nm_connection_get_setting_802_1x (connection); + + *replied = FALSE; + + if (!strcmp (method_name, "RequestPassphrase")) { + const gchar *psk; + + if (!s_wireless_sec) + return FALSE; + + psk = nm_setting_wireless_security_get_psk (s_wireless_sec); + if (psk) { + _LOGD (LOGD_DEVICE | LOGD_WIFI, + "Returning the PSK to the IWD Agent"); + + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(s)", psk)); + *replied = TRUE; + return TRUE; + } + + *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; + *setting_key = NM_SETTING_WIRELESS_SECURITY_PSK; + return TRUE; + } else if (!strcmp (method_name, "RequestPrivateKeyPassphrase")) { + const gchar *password; + + if (!s_8021x) + return FALSE; + + password = nm_setting_802_1x_get_private_key_password (s_8021x); + if (password) { + _LOGD (LOGD_DEVICE | LOGD_WIFI, + "Returning the private key password to the IWD Agent"); + + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(s)", password)); + *replied = TRUE; + return TRUE; + } + + *setting_name = NM_SETTING_802_1X_SETTING_NAME; + *setting_key = NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD; + return TRUE; + } else if (!strcmp (method_name, "RequestUserNameAndPassword")) { + const gchar *identity, *password; + + if (!s_8021x) + return FALSE; + + identity = nm_setting_802_1x_get_identity (s_8021x); + password = nm_setting_802_1x_get_password (s_8021x); + if (identity && password) { + _LOGD (LOGD_DEVICE | LOGD_WIFI, + "Returning the username and password to the IWD Agent"); + + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(ss)", identity, password)); + *replied = TRUE; + return TRUE; + } + + *setting_name = NM_SETTING_802_1X_SETTING_NAME; + if (!identity) + *setting_key = NM_SETTING_802_1X_IDENTITY; + else + *setting_key = NM_SETTING_802_1X_PASSWORD; + return TRUE; + } else if (!strcmp (method_name, "RequestUserPassword")) { + const gchar *password; + + if (!s_8021x) + return FALSE; + + password = nm_setting_802_1x_get_password (s_8021x); + if (password) { + _LOGD (LOGD_DEVICE | LOGD_WIFI, + "Returning the user password to the IWD Agent"); + + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(s)", password)); + *replied = TRUE; + return TRUE; + } + + *setting_name = NM_SETTING_802_1X_SETTING_NAME; + *setting_key = NM_SETTING_802_1X_PASSWORD; + return TRUE; + } else + return FALSE; +} + +static void +wifi_secrets_get_one (NMDeviceIwd *self, + const char *setting_name, + NMSecretAgentGetSecretsFlags flags, + const char *setting_key, + GDBusMethodInvocation *invocation); + static void wifi_secrets_cb (NMActRequest *req, NMActRequestGetSecretsCallId *call_id, @@ -1008,25 +1120,33 @@ wifi_secrets_cb (NMActRequest *req, GError *error, gpointer user_data) { - NMDevice *device = user_data; - NMDeviceIwd *self = user_data; + NMDeviceIwd *self; NMDeviceIwdPrivate *priv; - NMSettingWirelessSecurity *s_wireless_sec; - const gchar *psk; + NMDevice *device; + GDBusMethodInvocation *invocation; + const gchar *setting_name; + const gchar *setting_key; + gboolean replied; + NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + + nm_utils_user_data_unpack (user_data, &self, &invocation); g_return_if_fail (NM_IS_DEVICE_IWD (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); priv = NM_DEVICE_IWD_GET_PRIVATE (self); + device = NM_DEVICE (self); g_return_if_fail (priv->wifi_secrets_id == call_id); priv->wifi_secrets_id = NULL; - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_dbus_method_invocation_return_error_literal (invocation, NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "NM secrets request cancelled"); return; + } - g_return_if_fail (priv->secrets_request); g_return_if_fail (req == nm_device_get_act_request (device)); g_return_if_fail (nm_act_request_get_settings_connection (req) == s_connection); @@ -1038,32 +1158,30 @@ wifi_secrets_cb (NMActRequest *req, goto secrets_error; } - s_wireless_sec = nm_connection_get_setting_wireless_security (nm_act_request_get_applied_connection (req)); - if (!s_wireless_sec) - goto secrets_error; - - psk = nm_setting_wireless_security_get_psk (s_wireless_sec); - if (!psk) + if (!try_reply_agent_request (self, nm_act_request_get_applied_connection (req), + invocation, &setting_name, &setting_key, + &replied)) goto secrets_error; - _LOGD (LOGD_DEVICE | LOGD_WIFI, - "Returning a new PSK to the IWD Agent"); + if (replied) { + /* Change state back to what it was before NEED_AUTH */ + nm_device_state_changed (device, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); + return; + } - g_dbus_method_invocation_return_value (priv->secrets_request, - g_variant_new ("(s)", psk)); - priv->secrets_request = NULL; + if (nm_settings_connection_get_timestamp (nm_act_request_get_settings_connection (req), + NULL)) + get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - /* Change state back to what it was before NEED_AUTH */ - nm_device_state_changed (device, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); + /* Request further secrets if we still need something */ + wifi_secrets_get_one (self, setting_name, get_secret_flags, + setting_key, invocation); return; secrets_error: - if (priv->secrets_request) { - g_dbus_method_invocation_return_error_literal (priv->secrets_request, NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "NM secrets request failed"); - priv->secrets_request = NULL; - } + g_dbus_method_invocation_return_error_literal (invocation, NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "NM secrets request failed"); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, @@ -1073,9 +1191,11 @@ secrets_error: } static void -wifi_secrets_get_secrets (NMDeviceIwd *self, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags) +wifi_secrets_get_one (NMDeviceIwd *self, + const char *setting_name, + NMSecretAgentGetSecretsFlags flags, + const char *setting_key, + GDBusMethodInvocation *invocation) { NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); NMActRequest *req; @@ -1089,9 +1209,9 @@ wifi_secrets_get_secrets (NMDeviceIwd *self, TRUE, setting_name, flags, - NULL, + setting_key, wifi_secrets_cb, - self); + nm_utils_user_data_pack (self, invocation)); } static void @@ -1219,15 +1339,13 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) ap = ap_path ? nm_wifi_ap_lookup_for_device (NM_DEVICE (self), ap_path) : NULL; if (!ap) { ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection); - - /* TODO: assuming hidden networks aren't supported do we need - * to consider the case of APs that are not in the scan list - * yet, for which nm-device-wifi.c creates the temporary fake - * AP object? - */ + if (!ap) { + NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), - nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); } set_current_ap (self, ap, FALSE); @@ -1316,29 +1434,11 @@ out: } static guint32 -get_configured_mtu (NMDevice *device, gboolean *out_is_user_config) +get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) { - NMSettingWireless *setting; - gint64 mtu_default; - guint32 mtu; - - nm_assert (NM_IS_DEVICE (device)); - nm_assert (out_is_user_config); - - setting = NM_SETTING_WIRELESS (nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRELESS)); - if (!setting) - g_return_val_if_reached (0); - - mtu = nm_setting_wireless_get_mtu (setting); - if (mtu == 0) { - mtu_default = nm_device_get_configured_mtu_from_connection_default (device, "wifi.mtu"); - if (mtu_default >= 0) { - *out_is_user_config = TRUE; - return (guint32) mtu_default; - } - } - *out_is_user_config = (mtu != 0); - return mtu; + return nm_device_get_configured_mtu_from_connection (device, + NM_TYPE_SETTING_WIRELESS, + out_source); } static gboolean @@ -1748,40 +1848,44 @@ nm_device_iwd_set_dbus_object (NMDeviceIwd *self, GDBusObject *object) } gboolean -nm_device_iwd_agent_psk_query (NMDeviceIwd *self, - GDBusMethodInvocation *invocation) +nm_device_iwd_agent_query (NMDeviceIwd *self, + GDBusMethodInvocation *invocation) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); NMActRequest *req; - NMSettingWirelessSecurity *s_wireless_sec; - const gchar *psk; + const gchar *setting_name; + const gchar *setting_key; + gboolean replied; + NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; req = nm_device_get_act_request (NM_DEVICE (self)); if (!req) return FALSE; - s_wireless_sec = nm_connection_get_setting_wireless_security (nm_act_request_get_applied_connection (req)); - if (!s_wireless_sec) + if (!try_reply_agent_request (self, nm_act_request_get_applied_connection (req), + invocation, &setting_name, &setting_key, + &replied)) return FALSE; - psk = nm_setting_wireless_security_get_psk (s_wireless_sec); - if (psk) { - _LOGD (LOGD_DEVICE | LOGD_WIFI, - "Returning the PSK to the IWD Agent"); - - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(s)", psk)); + if (replied) return TRUE; - } + + /* Normally require new secrets every time IWD asks for them. + * IWD only queries us if it has not saved the secrets (e.g. by policy) + * or a previous attempt has failed with current secrets so it wants + * a fresh set. However if this is a new connection it may include + * all of the needed settings already so allow using these, too. + * Connection timestamp is set after activation or after first + * activation failure (to 0). + */ + if (nm_settings_connection_get_timestamp (nm_act_request_get_settings_connection (req), + NULL)) + get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NO_SECRETS); - wifi_secrets_get_secrets (self, - NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION - | NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW); + wifi_secrets_get_one (self, setting_name, get_secret_flags, + setting_key, invocation); - priv->secrets_request = invocation; return TRUE; } diff --git a/src/devices/wifi/nm-device-iwd.h b/src/devices/wifi/nm-device-iwd.h index a4253f52..825123b1 100644 --- a/src/devices/wifi/nm-device-iwd.h +++ b/src/devices/wifi/nm-device-iwd.h @@ -51,8 +51,8 @@ NMDevice *nm_device_iwd_new (const char *iface, NMDeviceWifiCapabilities capabil void nm_device_iwd_set_dbus_object (NMDeviceIwd *device, GDBusObject *object); -gboolean nm_device_iwd_agent_psk_query (NMDeviceIwd *device, - GDBusMethodInvocation *invocation); +gboolean nm_device_iwd_agent_query (NMDeviceIwd *device, + GDBusMethodInvocation *invocation); const CList *_nm_device_iwd_get_aps (NMDeviceIwd *self); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 1a86e13b..6bd06524 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -2786,29 +2786,11 @@ act_stage3_ip6_config_start (NMDevice *device, } static guint32 -get_configured_mtu (NMDevice *device, gboolean *out_is_user_config) +get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) { - NMSettingWireless *setting; - gint64 mtu_default; - guint32 mtu; - - nm_assert (NM_IS_DEVICE (device)); - nm_assert (out_is_user_config); - - setting = NM_SETTING_WIRELESS (nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRELESS)); - if (!setting) - g_return_val_if_reached (0); - - mtu = nm_setting_wireless_get_mtu (setting); - if (mtu == 0) { - mtu_default = nm_device_get_configured_mtu_from_connection_default (device, "wifi.mtu"); - if (mtu_default >= 0) { - *out_is_user_config = TRUE; - return (guint32) mtu_default; - } - } - *out_is_user_config = (mtu != 0); - return mtu; + return nm_device_get_configured_mtu_from_connection (device, + NM_TYPE_SETTING_WIRELESS, + out_source); } static gboolean diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c index 39db3a04..0f95fa08 100644 --- a/src/devices/wifi/nm-iwd-manager.c +++ b/src/devices/wifi/nm-iwd-manager.c @@ -84,27 +84,31 @@ G_DEFINE_TYPE (NMIwdManager, nm_iwd_manager, G_TYPE_OBJECT) /*****************************************************************************/ static void -psk_agent_dbus_method_cb (GDBusConnection *connection, - const gchar *sender, const gchar *object_path, - const gchar *interface_name, const gchar *method_name, - GVariant *parameters, - GDBusMethodInvocation *invocation, - gpointer user_data) +agent_dbus_method_cb (GDBusConnection *connection, + const gchar *sender, const gchar *object_path, + const gchar *interface_name, const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) { NMIwdManager *self = user_data; NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - GDBusObjectManagerClient *omc = G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager); const gchar *network_path, *device_path, *ifname; gs_unref_object GDBusInterface *network = NULL, *device_obj = NULL; gs_unref_variant GVariant *value = NULL; gint ifindex; NMDevice *device; + gs_free char *name_owner = NULL; /* Be paranoid and check the sender address */ - if (!nm_streq0 (g_dbus_object_manager_client_get_name_owner (omc), sender)) + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager)); + if (!nm_streq0 (name_owner, sender)) goto return_error; - g_variant_get (parameters, "(&o)", &network_path); + if (!strcmp (method_name, "RequestUserPassword")) + g_variant_get (parameters, "(&os)", &network_path, NULL); + else + g_variant_get (parameters, "(&o)", &network_path); network = g_dbus_object_manager_get_interface (priv->object_manager, network_path, @@ -113,7 +117,7 @@ psk_agent_dbus_method_cb (GDBusConnection *connection, device_path = g_variant_get_string (value, NULL); if (!device_path) { - _LOGE ("Device not cached for network %s in IWD Agent request", + _LOGD ("agent-request: device not cached for network %s in IWD Agent request", network_path); goto return_error; } @@ -126,103 +130,99 @@ psk_agent_dbus_method_cb (GDBusConnection *connection, ifname = g_variant_get_string (value, NULL); if (!ifname) { - _LOGE ("Name not cached for device %s in IWD Agent request", + _LOGD ("agent-request: name not cached for device %s in IWD Agent request", device_path); goto return_error; } ifindex = if_nametoindex (ifname); if (!ifindex) { - _LOGE ("if_nametoindex failed for Name %s for Device at %s: %i", + _LOGD ("agent-request: if_nametoindex failed for Name %s for Device at %s: %i", ifname, device_path, errno); goto return_error; } device = nm_manager_get_device_by_ifindex (priv->manager, ifindex); if (!NM_IS_DEVICE_IWD (device)) { - _LOGE ("IWD device named %s is not a Wifi device in IWD Agent request", - ifname); + _LOGD ("agent-request: IWD device named %s is not a Wifi device in IWD Agent request", + ifname); goto return_error; } - if (nm_device_iwd_agent_psk_query (NM_DEVICE_IWD (device), invocation)) + if (nm_device_iwd_agent_query (NM_DEVICE_IWD (device), invocation)) return; - _LOGE ("Device %s did not handle the IWD Agent request", ifname); + _LOGD ("agent-request: device %s did not handle the IWD Agent request", ifname); return_error: /* IWD doesn't look at the specific error */ g_dbus_method_invocation_return_error_literal (invocation, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "No PSK available for this connection"); + "Secrets not available for this connection"); } +static const GDBusInterfaceInfo iwd_agent_iface_info = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + "net.connman.iwd.Agent", + .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( + NM_DEFINE_GDBUS_METHOD_INFO ( + "RequestPassphrase", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("network", "o"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("passphrase", "s"), + ), + ), + NM_DEFINE_GDBUS_METHOD_INFO ( + "RequestPrivateKeyPassphrase", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("network", "o"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("passphrase", "s"), + ), + ), + NM_DEFINE_GDBUS_METHOD_INFO ( + "RequestUserNameAndPassword", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("network", "o"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("user", "s"), + NM_DEFINE_GDBUS_ARG_INFO ("password", "s"), + ), + ), + NM_DEFINE_GDBUS_METHOD_INFO ( + "RequestUserPassword", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("network", "o"), + NM_DEFINE_GDBUS_ARG_INFO ("user", "s"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("password", "s"), + ), + ), + ), +); + static guint -psk_agent_export (GDBusConnection *connection, gpointer user_data, +iwd_agent_export (GDBusConnection *connection, gpointer user_data, gchar **agent_path, GError **error) { - static const GDBusArgInfo request_passphrase_arg_network = { - -1, - (gchar *) "network", - (gchar *) "o", - NULL, - }; - static const GDBusArgInfo *const request_passphrase_in_args[] = { - &request_passphrase_arg_network, - NULL, - }; - static const GDBusArgInfo request_passphrase_arg_passphrase = { - -1, - (gchar *) "passphrase", - (gchar *) "s", - NULL, - }; - static const GDBusArgInfo *const request_passphrase_out_args[] = { - &request_passphrase_arg_passphrase, - NULL, + static const GDBusInterfaceVTable vtable = { + .method_call = agent_dbus_method_cb, }; - static const GDBusMethodInfo request_passphrase_info = { - -1, - (gchar *) "RequestPassphrase", - (GDBusArgInfo **) &request_passphrase_in_args, - (GDBusArgInfo **) &request_passphrase_out_args, - NULL, - }; - static const GDBusMethodInfo *const method_info[] = { - &request_passphrase_info, - NULL, - }; - static GDBusInterfaceInfo interface_info = { - -1, - (gchar *) "net.connman.iwd.Agent", - (GDBusMethodInfo **) &method_info, - NULL, - NULL, - NULL, - }; - static GDBusInterfaceVTable vtable = { - psk_agent_dbus_method_cb, - NULL, - NULL, - }; - gchar path[50]; unsigned int rnd; guint id; - if (!nm_utils_random_bytes (&rnd, sizeof (rnd))) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "Can't read urandom."); - return 0; - } + nm_utils_random_bytes (&rnd, sizeof (rnd)); nm_sprintf_buf (path, "/agent/%u", rnd); id = g_dbus_connection_register_object (connection, path, - &interface_info, &vtable, - user_data, NULL, error); + NM_UNCONST_PTR (GDBusInterfaceInfo, &iwd_agent_iface_info), + &vtable, user_data, NULL, error); if (id) *agent_path = g_strdup (path); @@ -549,7 +549,7 @@ got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) connection = g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (object_manager)); - priv->agent_id = psk_agent_export (connection, self, + priv->agent_id = iwd_agent_export (connection, self, &priv->agent_path, &error); if (!priv->agent_id) { _LOGE ("failed to export the IWD Agent: PSK/8021x WiFi networks will not work: %s", diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index ff1579d1..617d5c4a 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -859,7 +859,7 @@ nm_modem_stage3_ip6_config_start (NMModem *self, } guint32 -nm_modem_get_configured_mtu (NMDevice *self, gboolean *out_is_user_config) +nm_modem_get_configured_mtu (NMDevice *self, NMDeviceMtuSource *out_source) { NMConnection *connection; NMSetting *setting; @@ -868,7 +868,7 @@ nm_modem_get_configured_mtu (NMDevice *self, gboolean *out_is_user_config) const char *property_name; nm_assert (NM_IS_DEVICE (self)); - nm_assert (out_is_user_config); + nm_assert (out_source); connection = nm_device_get_applied_connection (self); if (!connection) @@ -881,19 +881,19 @@ nm_modem_get_configured_mtu (NMDevice *self, gboolean *out_is_user_config) if (setting) { g_object_get (setting, "mtu", &mtu, NULL); if (mtu) { - *out_is_user_config = TRUE; + *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; return mtu; } property_name = NM_IS_SETTING_GSM (setting) ? "gsm.mtu" : "cdma.mtu"; mtu_default = nm_device_get_configured_mtu_from_connection_default (self, property_name); if (mtu_default >= 0) { - *out_is_user_config = TRUE; + *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; return (guint32) mtu_default; } } - *out_is_user_config = FALSE; + *out_source = NM_DEVICE_MTU_SOURCE_NONE; return 0; } diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h index 6e78d2d5..cad9ece4 100644 --- a/src/devices/wwan/nm-modem.h +++ b/src/devices/wwan/nm-modem.h @@ -275,6 +275,6 @@ void nm_modem_emit_ip6_config_result (NMModem *self, const gchar *nm_modem_ip_type_to_string (NMModemIPType ip_type); -guint32 nm_modem_get_configured_mtu (NMDevice *self, gboolean *out_is_user_config); +guint32 nm_modem_get_configured_mtu (NMDevice *self, NMDeviceMtuSource *out_source); #endif /* __NETWORKMANAGER_MODEM_H__ */ diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c index 390b7054..360bd367 100644 --- a/src/dhcp/nm-dhcp-client.c +++ b/src/dhcp/nm-dhcp-client.c @@ -513,7 +513,7 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self, } static GBytes * -get_duid (NMDhcpClient *self, gboolean global) +get_duid (NMDhcpClient *self) { return NULL; } @@ -521,7 +521,7 @@ get_duid (NMDhcpClient *self, gboolean global) gboolean nm_dhcp_client_start_ip6 (NMDhcpClient *self, GBytes *client_id, - NMDhcpDuidEnforce enforce_duid, + gboolean enforce_duid, const char *dhcp_anycast_addr, const struct in6_addr *ll_addr, const char *hostname, @@ -541,12 +541,9 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self, nm_assert (!priv->duid); nm_assert (client_id); - if (enforce_duid == NM_DHCP_DUID_ENFORCE_NEVER) - priv->duid = NM_DHCP_CLIENT_GET_CLASS (self)->get_duid (self, TRUE); - else if (enforce_duid == NM_DHCP_DUID_ENFORCE_LEASE_FALLBACK) - priv->duid = NM_DHCP_CLIENT_GET_CLASS (self)->get_duid (self, FALSE); + if (!enforce_duid) + priv->duid = NM_DHCP_CLIENT_GET_CLASS (self)->get_duid (self); - /* NM_DHCP_DUID_ENFORCE_ALWAYS and fallback */ if (!priv->duid) priv->duid = g_bytes_ref (client_id); diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h index 98c3ed26..f3d0b7d1 100644 --- a/src/dhcp/nm-dhcp-client.h +++ b/src/dhcp/nm-dhcp-client.h @@ -96,15 +96,13 @@ typedef struct { /** * get_duid: * @self: the #NMDhcpClient - * @global: if set to #true, the duid should be searched also in the - * DHCP client's system-wide persistent configuration. * * Attempts to find an existing DHCPv6 DUID for this client in the DHCP * client's persistent configuration. Returned DUID should be the binary * representation of the DUID. If no DUID is found, %NULL should be * returned. */ - GBytes *(*get_duid) (NMDhcpClient *self, gboolean global); + GBytes *(*get_duid) (NMDhcpClient *self); /* Signals */ void (*state_changed) (NMDhcpClient *self, @@ -153,7 +151,7 @@ gboolean nm_dhcp_client_start_ip4 (NMDhcpClient *self, gboolean nm_dhcp_client_start_ip6 (NMDhcpClient *self, GBytes *client_id, - NMDhcpDuidEnforce enforce_duid, + gboolean enforce_duid, const char *dhcp_anycast_addr, const struct in6_addr *ll_addr, const char *hostname, diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c index 43746dd3..3bd14ebe 100644 --- a/src/dhcp/nm-dhcp-dhclient.c +++ b/src/dhcp/nm-dhcp-dhclient.c @@ -582,7 +582,7 @@ state_changed (NMDhcpClient *client, } static GBytes * -get_duid (NMDhcpClient *client, gboolean global) +get_duid (NMDhcpClient *client) { NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client); NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self); @@ -607,7 +607,7 @@ get_duid (NMDhcpClient *client, gboolean global) g_free (leasefile); } - if (!duid && global) { + if (!duid) { /* Otherwise read the default machine-wide DUID */ _LOGD ("looking for default DUID in '%s'", priv->def_leasefile); duid = nm_dhcp_dhclient_read_duid (priv->def_leasefile, &error); diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c index 2d85c73a..67254323 100644 --- a/src/dhcp/nm-dhcp-manager.c +++ b/src/dhcp/nm-dhcp-manager.c @@ -164,7 +164,7 @@ client_start (NMDhcpManager *self, guint32 route_metric, const struct in6_addr *ipv6_ll_addr, GBytes *dhcp_client_id, - NMDhcpDuidEnforce enforce_duid, + gboolean enforce_duid, guint32 timeout, const char *dhcp_anycast_addr, const char *hostname, @@ -299,7 +299,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, gboolean send_hostname, const char *dhcp_hostname, GBytes *duid, - NMDhcpDuidEnforce enforce_duid, + gboolean enforce_duid, guint32 timeout, const char *dhcp_anycast_addr, gboolean info_only, diff --git a/src/dhcp/nm-dhcp-manager.h b/src/dhcp/nm-dhcp-manager.h index ed8ee742..7eb32c37 100644 --- a/src/dhcp/nm-dhcp-manager.h +++ b/src/dhcp/nm-dhcp-manager.h @@ -73,7 +73,7 @@ NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager, gboolean send_hostname, const char *dhcp_hostname, GBytes *duid, - NMDhcpDuidEnforce enforce_duid, + gboolean enforce_duid, guint32 timeout, const char *dhcp_anycast_addr, gboolean info_only, diff --git a/src/dhcp/nm-dhcp-utils.h b/src/dhcp/nm-dhcp-utils.h index afb87c1a..5c127bd1 100644 --- a/src/dhcp/nm-dhcp-utils.h +++ b/src/dhcp/nm-dhcp-utils.h @@ -24,12 +24,6 @@ #include "nm-ip4-config.h" #include "nm-ip6-config.h" -typedef enum { - NM_DHCP_DUID_ENFORCE_NEVER = 0, - NM_DHCP_DUID_ENFORCE_LEASE_FALLBACK, - NM_DHCP_DUID_ENFORCE_ALWAYS, -} NMDhcpDuidEnforce; - NMIP4Config *nm_dhcp_utils_ip4_config_from_options (struct _NMDedupMultiIndex *multi_idx, int ifindex, const char *iface, diff --git a/src/main.c b/src/main.c index c1267b27..7da0c3c2 100644 --- a/src/main.c +++ b/src/main.c @@ -227,11 +227,12 @@ main (int argc, char *argv[]) gboolean success = FALSE; NMManager *manager = NULL; NMConfig *config; - GError *error = NULL; + gs_free_error GError *error = NULL; gboolean wrote_pidfile = FALSE; char *bad_domains = NULL; NMConfigCmdLineOptions *config_cli; guint sd_id = 0; + GError *error_invalid_logging_config = NULL; /* Known to cause a possible deadlock upon GDBus initialization: * https://bugzilla.gnome.org/show_bug.cgi?id=674885 */ @@ -304,11 +305,6 @@ main (int argc, char *argv[]) _("%s. Please use --help to see a list of valid options.\n"), error->message); exit (1); - } else if (bad_domains) { - fprintf (stderr, - _("Ignoring unrecognized log domain(s) '%s' passed on command line.\n"), - bad_domains); - g_clear_pointer (&bad_domains, g_free); } /* Read the config file and CLI overrides */ @@ -330,15 +326,9 @@ main (int argc, char *argv[]) if (!nm_logging_setup (nm_config_get_log_level (config), nm_config_get_log_domains (config), &bad_domains, - &error)) { - fprintf (stderr, _("Error in configuration file: %s.\n"), - error->message); - exit (1); - } else if (bad_domains) { - fprintf (stderr, - _("Ignoring unrecognized log domain(s) '%s' from config files.\n"), - bad_domains); - g_clear_pointer (&bad_domains, g_free); + &error_invalid_logging_config)) { + /* ignore error, and print the failure reason below. + * Likewise, print about bad_domains below. */ } } @@ -374,6 +364,19 @@ main (int argc, char *argv[]) nm_log_info (LOGD_CORE, "Read config: %s", nm_config_data_get_config_description (nm_config_get_data (config))); nm_config_data_log (nm_config_get_data (config), "CONFIG: ", " ", NULL); + if (error_invalid_logging_config) { + nm_log_warn (LOGD_CORE, "config: invalid logging configuration: %s", error_invalid_logging_config->message); + g_clear_error (&error_invalid_logging_config); + } + if (bad_domains) { + nm_log_warn (LOGD_CORE, "config: invalid logging domains '%s' from %s", + bad_domains, + (global_opt.opt_log_level == NULL && global_opt.opt_log_domains == NULL) + ? "config file" + : "command line"); + nm_clear_g_free (&bad_domains); + } + /* the first access to State causes the file to be read (and possibly print a warning) */ nm_config_state_get (config); diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c index ba61cb11..04f86312 100644 --- a/src/ndisc/nm-ndisc.c +++ b/src/ndisc/nm-ndisc.c @@ -231,8 +231,8 @@ _data_complete (NMNDiscDataInternal *data) return &data->public; } -static void -_emit_config_change (NMNDisc *self, NMNDiscConfigMap changed) +void +nm_ndisc_emit_config_change (NMNDisc *self, NMNDiscConfigMap changed) { _config_changed_log (self, changed); g_signal_emit (self, signals[CONFIG_RECEIVED], 0, @@ -743,7 +743,7 @@ nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid) if (rdata->addresses->len) { _LOGD ("IPv6 interface identifier changed, flushing addresses"); g_array_remove_range (rdata->addresses, 0, rdata->addresses->len); - _emit_config_change (ndisc, NM_NDISC_CONFIG_ADDRESSES); + nm_ndisc_emit_config_change (ndisc, NM_NDISC_CONFIG_ADDRESSES); solicit_routers (ndisc); } return TRUE; @@ -796,8 +796,8 @@ nm_ndisc_start (NMNDisc *ndisc) } } -void -nm_ndisc_dad_failed (NMNDisc *ndisc, const struct in6_addr *address) +NMNDiscConfigMap +nm_ndisc_dad_failed (NMNDisc *ndisc, const struct in6_addr *address, gboolean emit_changed_signal) { NMNDiscDataInternal *rdata; guint i; @@ -819,8 +819,10 @@ nm_ndisc_dad_failed (NMNDisc *ndisc, const struct in6_addr *address) i++; } - if (changed) - _emit_config_change (ndisc, NM_NDISC_CONFIG_ADDRESSES); + if (emit_changed_signal && changed) + nm_ndisc_emit_config_change (ndisc, NM_NDISC_CONFIG_ADDRESSES); + + return changed ? NM_NDISC_CONFIG_ADDRESSES : NM_NDISC_CONFIG_NONE; } #define CONFIG_MAP_MAX_STR 7 @@ -1131,7 +1133,7 @@ check_timestamps (NMNDisc *ndisc, gint32 now, NMNDiscConfigMap changed) clean_dns_domains (ndisc, now, &changed, &nextevent); if (changed) - _emit_config_change (ndisc, changed); + nm_ndisc_emit_config_change (ndisc, changed); if (nextevent != G_MAXINT32) { if (nextevent <= now) diff --git a/src/ndisc/nm-ndisc.h b/src/ndisc/nm-ndisc.h index 9a8a27d7..fdc5615f 100644 --- a/src/ndisc/nm-ndisc.h +++ b/src/ndisc/nm-ndisc.h @@ -100,6 +100,7 @@ typedef struct { } NMNDiscDNSDomain; typedef enum { + NM_NDISC_CONFIG_NONE = 0, NM_NDISC_CONFIG_DHCP_LEVEL = 1 << 0, NM_NDISC_CONFIG_GATEWAYS = 1 << 1, NM_NDISC_CONFIG_ADDRESSES = 1 << 2, @@ -171,13 +172,17 @@ typedef struct { GType nm_ndisc_get_type (void); +void nm_ndisc_emit_config_change (NMNDisc *self, NMNDiscConfigMap changed); + int nm_ndisc_get_ifindex (NMNDisc *self); const char *nm_ndisc_get_ifname (NMNDisc *self); NMNDiscNodeType nm_ndisc_get_node_type (NMNDisc *self); gboolean nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid); void nm_ndisc_start (NMNDisc *ndisc); -void nm_ndisc_dad_failed (NMNDisc *ndisc, const struct in6_addr *address); +NMNDiscConfigMap nm_ndisc_dad_failed (NMNDisc *ndisc, + const struct in6_addr *address, + gboolean emit_changed_signal); void nm_ndisc_set_config (NMNDisc *ndisc, const GArray *addresses, const GArray *dns_servers, diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index 58d766c1..308c9e1f 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -339,7 +339,8 @@ dad_failed_handle_idle (gpointer user_data) if (nm_ndisc_dad_addr_is_fail_candidate (data->platform, obj)) { nm_ndisc_dad_failed (data->ndisc, - &NMP_OBJECT_CAST_IP6_ADDRESS (obj)->address); + &NMP_OBJECT_CAST_IP6_ADDRESS (obj)->address, + TRUE); } } diff --git a/src/nm-logging.c b/src/nm-logging.c index 11e05c31..c5553791 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -98,6 +98,12 @@ static struct Global { const char *prefix; const char *syslog_identifier; enum { + /* before we setup syslog (during start), the backend defaults to GLIB, meaning: + * we use g_log() for all logging. At that point, the application is not yet supposed + * to do any logging and doing so indicates a bug. + * + * Afterwards, the backend is either SYSLOG or JOURNAL. From that point, also + * g_log() is redirected to this backend via a logging handler. */ LOG_BACKEND_GLIB, LOG_BACKEND_SYSLOG, LOG_BACKEND_JOURNAL, @@ -832,21 +838,36 @@ nm_logging_set_prefix (const char *format, ...) void nm_logging_syslog_openlog (const char *logging_backend, gboolean debug) { + gboolean fetch_monotonic_timestamp = FALSE; + gboolean obsolete_debug_backend = FALSE; + + nm_assert (NM_IN_STRSET (""NM_CONFIG_DEFAULT_LOGGING_BACKEND, + NM_LOG_CONFIG_BACKEND_JOURNAL, + NM_LOG_CONFIG_BACKEND_SYSLOG)); + if (global.log_backend != LOG_BACKEND_GLIB) g_return_if_reached (); if (!logging_backend) logging_backend = ""NM_CONFIG_DEFAULT_LOGGING_BACKEND; + if (nm_streq (logging_backend, NM_LOG_CONFIG_BACKEND_DEBUG)) { + /* "debug" was wrongly documented as a valid logging backend. It makes no sense however, + * because printing to stderr only makes sense when not demonizing. Whether to daemonize + * is only controlled via command line arguments (--no-daemon, --debug) and not via the + * logging backend from configuration. + * + * Fall back to the default. */ + logging_backend = ""NM_CONFIG_DEFAULT_LOGGING_BACKEND; + obsolete_debug_backend = TRUE; + } + #if SYSTEMD_JOURNAL - if (strcmp (logging_backend, "syslog") != 0) { + if (!nm_streq (logging_backend, NM_LOG_CONFIG_BACKEND_SYSLOG)) { global.log_backend = LOG_BACKEND_JOURNAL; global.uses_syslog = TRUE; global.debug_stderr = debug; - - /* ensure we read a monotonic timestamp. Reading the timestamp the first - * time causes a logging message. We don't want to do that during _nm_log_impl. */ - nm_utils_get_monotonic_timestamp_ns (); + fetch_monotonic_timestamp = TRUE; } else #endif { @@ -860,5 +881,30 @@ nm_logging_syslog_openlog (const char *logging_backend, gboolean debug) G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, nm_log_handler, NULL); -} + if (fetch_monotonic_timestamp) { + /* ensure we read a monotonic timestamp. Reading the timestamp the first + * time causes a logging message. We don't want to do that during _nm_log_impl. */ + nm_utils_get_monotonic_timestamp_ns (); + } + + if (obsolete_debug_backend) + nm_log_dbg (LOGD_CORE, "config: ignore deprecated logging backend 'debug', fallback to '%s'", logging_backend); + + if (nm_streq (logging_backend, NM_LOG_CONFIG_BACKEND_SYSLOG)) { + /* good */ + } else if (nm_streq (logging_backend, NM_LOG_CONFIG_BACKEND_JOURNAL)) { +#if !SYSTEMD_JOURNAL + nm_log_warn (LOGD_CORE, "config: logging backend 'journal' is not available, fallback to 'syslog'"); +#endif + } else { + nm_log_warn (LOGD_CORE, "config: invalid logging backend '%s', fallback to '%s'", + logging_backend, +#if SYSTEMD_JOURNAL + NM_LOG_CONFIG_BACKEND_JOURNAL +#else + NM_LOG_CONFIG_BACKEND_SYSLOG +#endif + ); + } +} diff --git a/src/nm-logging.h b/src/nm-logging.h index 069d1d0d..70c14a5e 100644 --- a/src/nm-logging.h +++ b/src/nm-logging.h @@ -28,6 +28,10 @@ #error nm-test-utils.h must be included as last header #endif +#define NM_LOG_CONFIG_BACKEND_DEBUG "debug" +#define NM_LOG_CONFIG_BACKEND_SYSLOG "syslog" +#define NM_LOG_CONFIG_BACKEND_JOURNAL "journal" + /* Log domains */ typedef enum { /*< skip >*/ LOGD_NONE = 0LL, diff --git a/src/nm-manager.c b/src/nm-manager.c index c6d82c9d..0fea13de 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1210,9 +1210,11 @@ nm_manager_get_device_by_ifindex (NMManager *self, int ifindex) NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMDevice *device; - c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { - if (nm_device_get_ifindex (device) == ifindex) - return device; + if (ifindex > 0) { + c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { + if (nm_device_get_ifindex (device) == ifindex) + return device; + } } return NULL; @@ -7440,7 +7442,7 @@ static const NMDBusInterfaceInfoExtended interface_info_manager = { NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("WimaxHardwareEnabled", "b", NM_MANAGER_WIMAX_HARDWARE_ENABLED), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ActiveConnections", "ao", NM_MANAGER_ACTIVE_CONNECTIONS), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PrimaryConnection", "o", NM_MANAGER_PRIMARY_CONNECTION), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PrimartConnectionType", "s", NM_MANAGER_PRIMARY_CONNECTION_TYPE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PrimaryConnectionType", "s", NM_MANAGER_PRIMARY_CONNECTION_TYPE), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Metered", "u", NM_MANAGER_METERED), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ActivatingConnection", "o", NM_MANAGER_ACTIVATING_CONNECTION), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Startup", "b", NM_MANAGER_STARTUP), diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 06dd7e13..f8f4627e 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -482,7 +482,7 @@ link_changed (NMPlatform *platform, if (!IN6_IS_ADDR_UNSPECIFIED (&device->ip6_lladdr)) { if (device->obj->link.connected) - ip6_address_add (platform, device->obj->link.ifindex, in6addr_any, 64, device->ip6_lladdr, NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0); + ip6_address_add (platform, device->obj->link.ifindex, device->ip6_lladdr, 64, in6addr_any, NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0); else ip6_address_delete (platform, device->obj->link.ifindex, device->ip6_lladdr, 64); } diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c index a213b31f..8b8c87d8 100644 --- a/src/platform/tests/test-cleanup.c +++ b/src/platform/tests/test-cleanup.c @@ -59,6 +59,22 @@ test_cleanup_internal (void) ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); g_assert (ifindex > 0); + /* wait for kernel to add the IPv6 link local address... it takes a bit. */ + NMTST_WAIT_ASSERT (100, { + gs_unref_array GArray *addrs = NULL; + const NMPlatformIP6Address *a; + + if (nmtst_wait_iteration > 0) { + nmtstp_wait_for_signal (NM_PLATFORM_GET, nmtst_wait_remaining_us / 1000); + nm_platform_process_events (NM_PLATFORM_GET); + } + addrs = nmtstp_platform_ip6_address_get_all (NM_PLATFORM_GET, ifindex); + if ( addrs->len == 1 + && (a = &g_array_index (addrs, NMPlatformIP6Address, 0)) + && IN6_IS_ADDR_LINKLOCAL (&a->address)) + break; + }); + /* Add routes and addresses */ g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr4, plen4, addr4, lifetime, preferred, 0, NULL)); g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr6, plen6, in6addr_any, lifetime, preferred, flags)); diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 50cc1427..c09f6804 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -1033,7 +1033,7 @@ get_secrets_done_cb (NMAgentManager *manager, NMSettingsConnectionPrivate *priv; NMConnection *applied_connection; gs_free_error GError *local = NULL; - GVariant *dict; + GVariant *dict = NULL; gboolean agent_had_system = FALSE; ForEachSecretFlags cmp_flags = { NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAG_NONE }; @@ -1096,7 +1096,8 @@ get_secrets_done_cb (NMAgentManager *manager, setting_name, call_id); - dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (priv->system_secrets) + dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); /* Update the connection with our existing secrets from backing storage */ nm_connection_clear_secrets (NM_CONNECTION (self)); @@ -1240,7 +1241,7 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, gpointer callback_data) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - GVariant *existing_secrets; + GVariant *existing_secrets = NULL; NMAgentManagerCallId call_id_a; gs_free char *joined_hints = NULL; NMSettingsConnectionCallId *call_id; @@ -1262,15 +1263,6 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, call_id->callback_data = callback_data; c_list_link_tail (&priv->call_ids_lst_head, &call_id->call_ids_lst); - /* Use priv->secrets to work around the fact that nm_connection_clear_secrets() - * will clear secrets on this object's settings. - */ - if (!priv->system_secrets) { - g_set_error_literal (&local, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "secrets cache invalid"); - goto schedule_dummy; - } - /* Make sure the request actually requests something we can return */ if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) { g_set_error (&local, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, @@ -1286,7 +1278,11 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, goto schedule_dummy; } - existing_secrets = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + /* Use priv->system_secrets to work around the fact that nm_connection_clear_secrets() + * will clear secrets on this object's settings. + */ + if (priv->system_secrets) + existing_secrets = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); if (existing_secrets) g_variant_ref_sink (existing_secrets); |