core: return conflicting addresses from nm_l3cfg_check_ready()

It can be useful to know which addresses are conflicting, return them
from nm_l3cfg_check_ready().
This commit is contained in:
Beniamino Galvani 2022-09-08 15:34:19 +02:00
parent 19c0018f58
commit afa208c862
3 changed files with 40 additions and 8 deletions

View file

@ -10079,7 +10079,7 @@ _dev_ipmanual_check_ready(NMDevice *self)
gboolean has_carrier;
NML3CfgCheckReadyFlags flags;
gboolean ready;
gboolean acd_used = FALSE;
gs_unref_array GArray *conflicts = NULL;
int IS_IPv4;
if (priv->ipmanual_data.state_4 != NM_DEVICE_IP_STATE_PENDING
@ -10122,8 +10122,8 @@ _dev_ipmanual_check_ready(NMDevice *self)
priv->l3cds[L3_CONFIG_DATA_TYPE_MANUALIP].d,
addr_family,
flags,
&acd_used);
if (acd_used) {
&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) {

View file

@ -2990,7 +2990,7 @@ nm_l3cfg_check_ready(NML3Cfg *self,
const NML3ConfigData *l3cd,
int addr_family,
NML3CfgCheckReadyFlags flags,
gboolean *acd_used)
GArray **conflicts)
{
NMDedupMultiIter iter;
const NMPObject *obj;
@ -2998,8 +2998,7 @@ nm_l3cfg_check_ready(NML3Cfg *self,
nm_assert(NM_IS_L3CFG(self));
nm_assert_addr_family(addr_family);
NM_SET_OUT(acd_used, FALSE);
nm_assert(!conflicts || !*conflicts);
if (!l3cd)
return TRUE;
@ -3019,7 +3018,13 @@ nm_l3cfg_check_ready(NML3Cfg *self,
/* Still probing. Not ready. */
ready = FALSE;
} else if (addr_info->state == NM_L3_ACD_ADDR_STATE_USED) {
NM_SET_OUT(acd_used, TRUE);
if (conflicts) {
if (!*conflicts)
*conflicts = g_array_new(FALSE,
FALSE,
nm_utils_addr_family_to_size(addr_family));
g_array_append_val(*conflicts, addr_info->addr);
}
}
}
/* we only care that we don't have ACD still pending. Otherwise we are ready,
@ -3033,6 +3038,7 @@ nm_l3cfg_check_ready(NML3Cfg *self,
if (NM_FLAGS_HAS(flags, NM_L3CFG_CHECK_READY_FLAGS_IP6_DAD_READY)) {
nm_l3_config_data_iter_obj_for_each (&iter, l3cd, &obj, NMP_OBJECT_TYPE_IP6_ADDRESS) {
ObjStateData *obj_state;
gboolean dadfailed = FALSE;
obj_state = g_hash_table_lookup(self->priv.p->obj_state_hash, &obj);
@ -3049,6 +3055,32 @@ nm_l3cfg_check_ready(NML3Cfg *self,
continue;
}
if (obj_state->os_plobj
&& NM_FLAGS_HAS(NMP_OBJECT_CAST_IP6_ADDRESS(obj_state->os_plobj)->n_ifa_flags,
IFA_F_DADFAILED)) {
/* The address is still present with DADFAILED flag. */
dadfailed = TRUE;
} else if (obj_state->os_nm_configured && !obj_state->os_plobj
&& nm_platform_ip6_dadfailed_check(
self->priv.platform,
self->priv.ifindex,
&NMP_OBJECT_CAST_IP6_ADDRESS(obj_state->obj)->address)) {
/* We configured the address and kernel removed it with DADFAILED flag. */
dadfailed = TRUE;
}
if (dadfailed) {
if (conflicts) {
if (!*conflicts) {
*conflicts =
g_array_new(FALSE, FALSE, nm_utils_addr_family_to_size(addr_family));
}
g_array_append_val(*conflicts,
NMP_OBJECT_CAST_IP6_ADDRESS(obj_state->obj)->address);
}
continue;
}
if (obj_state->os_plobj
&& NM_FLAGS_HAS(NMP_OBJECT_CAST_IP6_ADDRESS(obj_state->os_plobj)->n_ifa_flags,
IFA_F_TENTATIVE)) {

View file

@ -400,7 +400,7 @@ gboolean nm_l3cfg_check_ready(NML3Cfg *self,
const NML3ConfigData *l3cd,
int addr_family,
NML3CfgCheckReadyFlags flags,
gboolean *acd_used);
GArray **conflicts);
gboolean nm_l3cfg_has_temp_not_available_obj(NML3Cfg *self, int addr_family);