diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index e3f2d4c71b..51c15bcc16 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -12262,7 +12262,6 @@ queued_ip_config_change (NMDevice *self, int addr_family) if (!IS_IPv4) { NMPlatform *platform; - gboolean need_ipv6ll = FALSE; GSList *dad6_failed_addrs, *iter; dad6_failed_addrs = g_steal_pointer (&priv->dad6_failed_addrs); @@ -12270,6 +12269,9 @@ queued_ip_config_change (NMDevice *self, int addr_family) if ( priv->state < NM_DEVICE_STATE_DEACTIVATING && (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 */ for (iter = dad6_failed_addrs; iter; iter = iter->next) { const NMPObject *obj = iter->data; @@ -12286,9 +12288,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 @@ -12297,7 +12302,6 @@ 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); } diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c index ba61cb1125..04f8631298 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 9a8a27d7af..fdc5615f54 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 58d766c124..308c9e1f5a 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); } }