diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 2b5f15e22c..4239ecd834 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -4319,7 +4319,8 @@ _dev_l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, N priv->ipac6_data.l3cd, AF_INET6, NM_L3CFG_CHECK_READY_FLAGS_IP6_DAD_READY, - &conflicts); + &conflicts, + NULL); if (conflicts) { /* nm_ndisc_dad_failed() will emit a new "NDisc:config-received" * signal; _dev_ipac6_ndisc_config_changed() will be called @@ -10397,18 +10398,26 @@ _dev_ipmanual_check_ready(NMDevice *self) for (IS_IPv4 = 0; IS_IPv4 < 2; IS_IPv4++) { const int addr_family = IS_IPv4 ? AF_INET : AF_INET6; + gboolean valid_addr = FALSE; ready = nm_l3cfg_check_ready(priv->l3cfg, priv->l3cds[L3_CONFIG_DATA_TYPE_MANUALIP].d, addr_family, flags, - &conflicts); - if (conflicts) { - _dev_ipmanual_set_state(self, addr_family, NM_DEVICE_IP_STATE_FAILED); - _dev_ip_state_check_async(self, AF_UNSPEC); - } else if (ready) { - _dev_ipmanual_set_state(self, addr_family, NM_DEVICE_IP_STATE_READY); - _dev_ip_state_check_async(self, AF_UNSPEC); + &conflicts, + &valid_addr); + if (ready) { + if (conflicts && !valid_addr) { + _LOGD_ipmanual(addr_family, "all manual addresses failed DAD, failing"); + _dev_ipmanual_set_state(self, addr_family, NM_DEVICE_IP_STATE_FAILED); + _dev_ip_state_check_async(self, AF_UNSPEC); + } else { + if (conflicts) { + _LOGD_ipmanual(addr_family, "some manual addresses passed DAD, continuing"); + } + _dev_ipmanual_set_state(self, addr_family, NM_DEVICE_IP_STATE_READY); + _dev_ip_state_check_async(self, AF_UNSPEC); + } } } } @@ -11750,6 +11759,7 @@ _dev_ipac6_ndisc_config_changed(NMNDisc *ndisc, l3cd, AF_INET6, NM_L3CFG_CHECK_READY_FLAGS_IP6_DAD_READY, + NULL, NULL); if (ready) { _dev_ipac6_set_state(self, NM_DEVICE_IP_STATE_READY); @@ -12740,7 +12750,8 @@ _dev_ipshared4_spawn_dnsmasq(NMDevice *self) priv->l3cds[L3_CONFIG_DATA_TYPE_SHARED_4].d, AF_INET, NM_L3CFG_CHECK_READY_FLAGS_IP4_ACD_READY, - &conflicts); + &conflicts, + NULL); if (!ready) { _LOGT_ipshared(AF_INET, "address not ready, wait"); return; diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c index 1e54f39677..dec6d4242a 100644 --- a/src/core/nm-l3cfg.c +++ b/src/core/nm-l3cfg.c @@ -3120,7 +3120,8 @@ nm_l3cfg_check_ready(NML3Cfg *self, const NML3ConfigData *l3cd, int addr_family, NML3CfgCheckReadyFlags flags, - GArray **conflicts) + GArray **conflicts, + gboolean *valid_addr) { NMDedupMultiIter iter; const NMPObject *obj; @@ -3155,6 +3156,8 @@ nm_l3cfg_check_ready(NML3Cfg *self, nm_utils_addr_family_to_size(addr_family)); g_array_append_val(*conflicts, addr_info->addr); } + } else { + NM_SET_OUT(valid_addr, TRUE); } } /* we only care that we don't have ACD still pending. Otherwise we are ready, diff --git a/src/core/nm-l3cfg.h b/src/core/nm-l3cfg.h index 9b8ec67f02..3994fb6633 100644 --- a/src/core/nm-l3cfg.h +++ b/src/core/nm-l3cfg.h @@ -405,7 +405,8 @@ gboolean nm_l3cfg_check_ready(NML3Cfg *self, const NML3ConfigData *l3cd, int addr_family, NML3CfgCheckReadyFlags flags, - GArray **conflicts); + GArray **conflicts, + gboolean *valid_addr); gboolean nm_l3cfg_has_failedobj_pending(NML3Cfg *self, int addr_family);