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.
This commit is contained in:
Beniamino Galvani 2023-08-31 14:06:09 +02:00
parent 01c103c879
commit abccde6038
3 changed files with 26 additions and 11 deletions

View file

@ -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;

View file

@ -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,

View file

@ -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);