From abccde6038914d34adf492485786fdd6069535f5 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 31 Aug 2023 14:06:09 +0200 Subject: [PATCH] core: don't fail if at least one static address passes DAD It seems more useful to have a best effort approach and configure everything we can; in that way we achieve at least some connectivity, and then sysadmin can check the logs in case something is missing. Currently instead, the whole activation fails (so, no address is configured) if just one of the addresses fails DAD. Ideally, we should have a way to make this configurable; but for now, implement the more useful behavior as default. --- src/core/devices/nm-device.c | 29 ++++++++++++++++++++--------- src/core/nm-l3cfg.c | 5 ++++- src/core/nm-l3cfg.h | 3 ++- 3 files changed, 26 insertions(+), 11 deletions(-) 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);