diff options
author | Thomas Haller <thaller@redhat.com> | 2020-10-09 19:04:38 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-10-13 13:43:21 +0200 |
commit | 79664aa1064a2c13837fc3d7291bbb95875273f1 (patch) | |
tree | d10983a92d3bbfbceed2705806b0745c4174d0c4 | |
parent | e155e4a153ec900100cef1c49d4481c5a499902a (diff) | |
download | NetworkManager-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.c | 18 | ||||
-rw-r--r-- | src/nm-l3-config-data.h | 1 | ||||
-rw-r--r-- | src/nm-l3cfg.c | 60 |
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, |