summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-10-09 19:04:38 +0200
committerThomas Haller <thaller@redhat.com>2020-10-13 13:43:21 +0200
commit79664aa1064a2c13837fc3d7291bbb95875273f1 (patch)
treed10983a92d3bbfbceed2705806b0745c4174d0c4
parente155e4a153ec900100cef1c49d4481c5a499902a (diff)
downloadNetworkManager-79664aa1064a2c13837fc3d7291bbb95875273f1.tar.gz
l3cfg: handle flag "ip4acd_not_ready" for IPv4 addresses
ACD is handled by NML3Cfg and it intercepts the IP addresses when merging the NML3ConfigData. Originally, I thought that in such a case, the merged l3cd instance would simply not contain any addresses that ACD have still pending or which have a conflict. However, I think it's better (clearer and possibly useful), to still merge such addresses, but flag them that they are ignored when syncing the addresses to platform.
-rw-r--r--src/nm-l3-config-data.c18
-rw-r--r--src/nm-l3-config-data.h1
-rw-r--r--src/nm-l3cfg.c60
3 files changed, 56 insertions, 23 deletions
diff --git a/src/nm-l3-config-data.c b/src/nm-l3-config-data.c
index b34afd616a..864924e88d 100644
--- a/src/nm-l3-config-data.c
+++ b/src/nm-l3-config-data.c
@@ -2546,13 +2546,25 @@ nm_l3_config_data_merge(NML3ConfigData * self,
src,
&obj,
NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4)) {
- if (hook_add_addr && !hook_add_addr(src, obj, hook_user_data))
+ NMPlatformIPXAddress addr_stack;
+ const NMPlatformIPAddress *addr = NULL;
+ NMTernary ip4acd_not_ready = NM_TERNARY_DEFAULT;
+
+ if (hook_add_addr && !hook_add_addr(src, obj, &ip4acd_not_ready, hook_user_data))
continue;
+ if (IS_IPv4 && ip4acd_not_ready != NM_TERNARY_DEFAULT
+ && (!!ip4acd_not_ready) != NMP_OBJECT_CAST_IP4_ADDRESS(obj)->ip4acd_not_ready) {
+ addr_stack.a4 = *NMP_OBJECT_CAST_IP4_ADDRESS(obj);
+ addr_stack.a4.ip4acd_not_ready = (!!ip4acd_not_ready);
+ addr = &addr_stack.ax;
+ } else
+ nm_assert(IS_IPv4 || ip4acd_not_ready == NM_TERNARY_DEFAULT);
+
nm_l3_config_data_add_address_full(self,
addr_family,
- obj,
- NULL,
+ addr ? NULL : obj,
+ addr,
NM_L3_CONFIG_ADD_FLAGS_EXCLUSIVE,
NULL);
}
diff --git a/src/nm-l3-config-data.h b/src/nm-l3-config-data.h
index 81dae7dea4..0da98079de 100644
--- a/src/nm-l3-config-data.h
+++ b/src/nm-l3-config-data.h
@@ -141,6 +141,7 @@ NML3ConfigData *nm_l3_config_data_new_from_platform(NMDedupMultiIndex * mu
typedef gboolean (*NML3ConfigMergeHookAddObj)(const NML3ConfigData *l3cd,
const NMPObject * obj,
+ NMTernary * out_ip4acd_not_ready,
gpointer user_data);
void nm_l3_config_data_merge(NML3ConfigData * self,
diff --git a/src/nm-l3cfg.c b/src/nm-l3cfg.c
index 9cb6ca976a..a176d354af 100644
--- a/src/nm-l3cfg.c
+++ b/src/nm-l3cfg.c
@@ -588,7 +588,11 @@ _l3cfg_externally_removed_objs_filter(/* const NMDedupMultiObj * */ gconstpointe
const NMPObject *obj = o;
GHashTable * externally_removed_objs_hash = user_data;
- return !g_hash_table_contains(externally_removed_objs_hash, obj);
+ if (NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_IP4_ADDRESS
+ && NMP_OBJECT_CAST_IP4_ADDRESS(obj)->ip4acd_not_ready)
+ return FALSE;
+
+ return !nm_g_hash_table_contains(externally_removed_objs_hash, obj);
}
/*****************************************************************************/
@@ -2580,13 +2584,18 @@ typedef struct {
} L3ConfigMergeHookAddObjData;
static gboolean
-_l3_hook_add_addr_cb(const NML3ConfigData *l3cd, const NMPObject *obj, gpointer user_data)
+_l3_hook_add_addr_cb(const NML3ConfigData *l3cd,
+ const NMPObject * obj,
+ NMTernary * out_ip4acd_not_ready,
+ gpointer user_data)
{
const L3ConfigMergeHookAddObjData *hook_data = user_data;
NML3Cfg * self = hook_data->self;
AcdData * acd_data;
in_addr_t addr;
+ nm_assert(out_ip4acd_not_ready && *out_ip4acd_not_ready == NM_TERNARY_DEFAULT);
+
if (NMP_OBJECT_GET_TYPE(obj) != NMP_OBJECT_TYPE_IP4_ADDRESS)
return TRUE;
@@ -2914,29 +2923,40 @@ _l3_commit_one(NML3Cfg *self, int addr_family, NML3CfgCommitType commit_type)
}
if (self->priv.p->combined_l3cd_commited) {
+ GHashTable * externally_removed_objs_hash;
NMDedupMultiFcnSelectPredicate predicate;
+ const NMDedupMultiHeadEntry * head_entry;
if (commit_type != NM_L3_CFG_COMMIT_TYPE_REAPPLY
- && self->priv.p->externally_removed_objs_cnt_addresses_x[IS_IPv4] > 0)
- predicate = _l3cfg_externally_removed_objs_filter;
- else
- predicate = NULL;
- addresses = nm_dedup_multi_objs_to_ptr_array_head(
- nm_l3_config_data_lookup_objs(self->priv.p->combined_l3cd_commited,
- NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4)),
- predicate,
- self->priv.p->externally_removed_objs_hash);
+ && self->priv.p->externally_removed_objs_cnt_addresses_x[IS_IPv4] > 0) {
+ predicate = _l3cfg_externally_removed_objs_filter;
+ externally_removed_objs_hash = self->priv.p->externally_removed_objs_hash;
+ } else {
+ if (IS_IPv4)
+ predicate = _l3cfg_externally_removed_objs_filter;
+ else
+ predicate = NULL;
+ externally_removed_objs_hash = NULL;
+ }
+ head_entry = nm_l3_config_data_lookup_objs(self->priv.p->combined_l3cd_commited,
+ NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4));
+ addresses = nm_dedup_multi_objs_to_ptr_array_head(head_entry,
+ predicate,
+ externally_removed_objs_hash);
if (commit_type != NM_L3_CFG_COMMIT_TYPE_REAPPLY
- && self->priv.p->externally_removed_objs_cnt_routes_x[IS_IPv4] > 0)
- predicate = _l3cfg_externally_removed_objs_filter;
- else
- predicate = NULL;
- routes = nm_dedup_multi_objs_to_ptr_array_head(
- nm_l3_config_data_lookup_objs(self->priv.p->combined_l3cd_commited,
- NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4)),
- predicate,
- self->priv.p->externally_removed_objs_hash);
+ && self->priv.p->externally_removed_objs_cnt_routes_x[IS_IPv4] > 0) {
+ predicate = _l3cfg_externally_removed_objs_filter;
+ externally_removed_objs_hash = self->priv.p->externally_removed_objs_hash;
+ } else {
+ predicate = NULL;
+ externally_removed_objs_hash = NULL;
+ }
+ head_entry = nm_l3_config_data_lookup_objs(self->priv.p->combined_l3cd_commited,
+ NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4));
+ routes = nm_dedup_multi_objs_to_ptr_array_head(head_entry,
+ predicate,
+ externally_removed_objs_hash);
route_table_sync =
nm_l3_config_data_get_route_table_sync(self->priv.p->combined_l3cd_commited,