summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-08-03 17:19:27 +0200
committerThomas Haller <thaller@redhat.com>2020-08-05 12:47:56 +0200
commit79db3972d734d16785b451ab93e25291eb620d33 (patch)
tree80c5c82062686c3009a9893f08504daea0efbb57 /src
parent25d404dadb049cfd1c1cc40f5e24a75b39218b43 (diff)
l3cfg: rework merging NML3ConfigData to give more control over how to merge
NML3Cfg will need more control about how to merge the NML3ConfigData instances. For example, it will need to intercept IPv4 addresses to perform ACD. For that, move the bulk of the merging code to NML3Cfg and expose the low-level function nm_l3_config_data_merge(). Also, add a callback function to nm_l3_config_data_merge(), to give control over how to merge.
Diffstat (limited to 'src')
-rw-r--r--src/nm-l3-config-data.c43
-rw-r--r--src/nm-l3-config-data.h26
-rw-r--r--src/nm-l3cfg.c140
3 files changed, 95 insertions, 114 deletions
diff --git a/src/nm-l3-config-data.c b/src/nm-l3-config-data.c
index b34ddbdd8b..412c5aa3a6 100644
--- a/src/nm-l3-config-data.c
+++ b/src/nm-l3-config-data.c
@@ -1894,11 +1894,13 @@ nm_l3_config_data_new_from_platform (NMDedupMultiIndex *multi_idx,
/*****************************************************************************/
-static void
-_init_merge (NML3ConfigData *self,
- const NML3ConfigData *src,
- NML3ConfigMergeFlags merge_flags,
- const guint32 *default_route_penalty_x /* length 2, for IS_IPv4 */)
+void
+nm_l3_config_data_merge (NML3ConfigData *self,
+ const NML3ConfigData *src,
+ NML3ConfigMergeFlags merge_flags,
+ const guint32 *default_route_penalty_x /* length 2, for IS_IPv4 */,
+ NML3ConfigMergeHookAddObj hook_add_addr,
+ gpointer hook_user_data)
{
NMDedupMultiIter iter;
const NMPObject *obj;
@@ -1915,6 +1917,11 @@ _init_merge (NML3ConfigData *self,
src,
obj,
NMP_OBJECT_TYPE_IP_ADDRESS (IS_IPv4)) {
+
+ if ( hook_add_addr
+ && !hook_add_addr (src, obj, hook_user_data))
+ continue;
+
if ( NM_FLAGS_HAS (merge_flags, NM_L3_CONFIG_MERGE_FLAGS_EXTERNAL)
&& !NMP_OBJECT_CAST_IP_ADDRESS (obj)->external) {
NMPlatformIPXAddress a;
@@ -2043,30 +2050,6 @@ nm_l3_config_data_new_clone (const NML3ConfigData *src,
ifindex = src->ifindex;
self = nm_l3_config_data_new (src->multi_idx, ifindex);
- _init_merge (self, src, NM_L3_CONFIG_MERGE_FLAGS_NONE, NULL);
- return self;
-}
-
-NML3ConfigData *
-nm_l3_config_data_new_combined (NMDedupMultiIndex *multi_idx,
- int ifindex,
- const NML3ConfigDatMergeInfo *const*merge_infos,
- guint merge_infos_len)
-{
- NML3ConfigData *self;
- guint i;
-
- nm_assert (multi_idx);
- nm_assert (ifindex > 0);
-
- self = nm_l3_config_data_new (multi_idx, ifindex);
-
- for (i = 0; i < merge_infos_len; i++) {
- _init_merge (self,
- merge_infos[i]->l3cd,
- merge_infos[i]->merge_flags,
- merge_infos[i]->default_route_penalty_x);
- }
-
+ nm_l3_config_data_merge (self, src, NM_L3_CONFIG_MERGE_FLAGS_NONE, NULL, NULL, NULL);
return self;
}
diff --git a/src/nm-l3-config-data.h b/src/nm-l3-config-data.h
index d30f7bef50..fde82b99a1 100644
--- a/src/nm-l3-config-data.h
+++ b/src/nm-l3-config-data.h
@@ -63,18 +63,6 @@ typedef enum {
/*****************************************************************************/
-typedef struct {
- const NML3ConfigData *l3cd;
- NML3ConfigMergeFlags merge_flags;
- union {
- struct {
- guint32 default_route_penalty_6;
- guint32 default_route_penalty_4;
- };
- guint32 default_route_penalty_x[2];
- };
-} NML3ConfigDatMergeInfo;
-
NML3ConfigData *nm_l3_config_data_new (NMDedupMultiIndex *multi_idx,
int ifindex);
const NML3ConfigData *nm_l3_config_data_ref (const NML3ConfigData *self);
@@ -106,10 +94,16 @@ NML3ConfigData *nm_l3_config_data_new_from_platform (NMDedupMultiIndex *multi_id
NMPlatform *platform,
NMSettingIP6ConfigPrivacy ipv6_privacy_rfc4941);
-NML3ConfigData *nm_l3_config_data_new_combined (NMDedupMultiIndex *multi_idx,
- int ifindex,
- const NML3ConfigDatMergeInfo *const*merge_infos,
- guint merge_infos_len);
+typedef gboolean (*NML3ConfigMergeHookAddObj) (const NML3ConfigData *l3cd,
+ const NMPObject *obj,
+ gpointer user_data);
+
+void nm_l3_config_data_merge (NML3ConfigData *self,
+ const NML3ConfigData *src,
+ NML3ConfigMergeFlags merge_flags,
+ const guint32 *default_route_penalty_x /* length 2, for IS_IPv4 */,
+ NML3ConfigMergeHookAddObj hook_add_addr,
+ gpointer hook_user_data);
void nm_l3_config_data_add_dependent_routes (NML3ConfigData *self,
int addr_family,
diff --git a/src/nm-l3cfg.c b/src/nm-l3cfg.c
index 7966be2c1a..b26f7bab8c 100644
--- a/src/nm-l3cfg.c
+++ b/src/nm-l3cfg.c
@@ -11,7 +11,15 @@
/*****************************************************************************/
typedef struct {
- NML3ConfigDatMergeInfo merge_info;
+ const NML3ConfigData *l3cd;
+ NML3ConfigMergeFlags merge_flags;
+ union {
+ struct {
+ guint32 default_route_penalty_6;
+ guint32 default_route_penalty_4;
+ };
+ guint32 default_route_penalty_x[2];
+ };
gconstpointer tag;
guint64 pseudo_timestamp;
int priority;
@@ -525,7 +533,7 @@ _l3_config_datas_find_next (GArray *l3_config_datas,
const L3ConfigData *l3_config_data = _l3_config_datas_at (l3_config_datas, i);
if ( NM_IN_SET (needle_tag, NULL, l3_config_data->tag)
- && NM_IN_SET (needle_l3cd, NULL, l3_config_data->merge_info.l3cd))
+ && NM_IN_SET (needle_l3cd, NULL, l3_config_data->l3cd))
return i;
}
return -1;
@@ -542,7 +550,7 @@ _l3_config_datas_remove_index_fast (GArray *arr,
l3_config_data = _l3_config_datas_at (arr, idx);
- nm_l3_config_data_unref (l3_config_data->merge_info.l3cd);
+ nm_l3_config_data_unref (l3_config_data->l3cd);
g_array_remove_index_fast (arr, idx);
}
@@ -611,7 +619,7 @@ nm_l3cfg_add_config (NML3Cfg *self,
while (TRUE) {
l3_config_data = _l3_config_datas_at (l3_config_datas, idx2);
- if (l3_config_data->merge_info.l3cd == l3cd) {
+ if (l3_config_data->l3cd == l3cd) {
nm_assert (idx == -1);
idx = idx2;
continue;
@@ -629,35 +637,35 @@ nm_l3cfg_add_config (NML3Cfg *self,
if (idx < 0) {
l3_config_data = nm_g_array_append_new (l3_config_datas, L3ConfigData);
*l3_config_data = (L3ConfigData) {
- .tag = tag,
- .merge_info.l3cd = nm_l3_config_data_ref_and_seal (l3cd),
- .merge_info.merge_flags = merge_flags,
- .merge_info.default_route_penalty_4 = default_route_penalty_4,
- .merge_info.default_route_penalty_6 = default_route_penalty_6,
- .priority = priority,
- .pseudo_timestamp = ++self->priv.p->pseudo_timestamp_counter,
- .dirty = FALSE,
+ .tag = tag,
+ .l3cd = nm_l3_config_data_ref_and_seal (l3cd),
+ .merge_flags = merge_flags,
+ .default_route_penalty_4 = default_route_penalty_4,
+ .default_route_penalty_6 = default_route_penalty_6,
+ .priority = priority,
+ .pseudo_timestamp = ++self->priv.p->pseudo_timestamp_counter,
+ .dirty = FALSE,
};
changed = TRUE;
} else {
l3_config_data = _l3_config_datas_at (l3_config_datas, idx);
l3_config_data->dirty = FALSE;
nm_assert (l3_config_data->tag == tag);
- nm_assert (l3_config_data->merge_info.l3cd == l3cd);
+ nm_assert (l3_config_data->l3cd == l3cd);
if (l3_config_data->priority != priority) {
l3_config_data->priority = priority;
changed = TRUE;
}
- if (l3_config_data->merge_info.merge_flags != merge_flags) {
- l3_config_data->merge_info.merge_flags = merge_flags;
+ if (l3_config_data->merge_flags != merge_flags) {
+ l3_config_data->merge_flags = merge_flags;
changed = TRUE;
}
- if (l3_config_data->merge_info.default_route_penalty_4 != default_route_penalty_4) {
- l3_config_data->merge_info.default_route_penalty_4 = default_route_penalty_4;
+ if (l3_config_data->default_route_penalty_4 != default_route_penalty_4) {
+ l3_config_data->default_route_penalty_4 = default_route_penalty_4;
changed = TRUE;
}
- if (l3_config_data->merge_info.default_route_penalty_6 != default_route_penalty_6) {
- l3_config_data->merge_info.default_route_penalty_6 = default_route_penalty_6;
+ if (l3_config_data->default_route_penalty_6 != default_route_penalty_6) {
+ l3_config_data->default_route_penalty_6 = default_route_penalty_6;
changed = TRUE;
}
}
@@ -734,7 +742,7 @@ _l3_config_combine_sort_fcn (gconstpointer p_a,
nm_assert (a);
nm_assert (b);
- nm_assert (nm_l3_config_data_get_ifindex (a->merge_info.l3cd) == nm_l3_config_data_get_ifindex (b->merge_info.l3cd));
+ nm_assert (nm_l3_config_data_get_ifindex (a->l3cd) == nm_l3_config_data_get_ifindex (b->l3cd));
/* we sort the entries with higher priority (more important, lower numerical value)
* first. */
@@ -747,70 +755,66 @@ _l3_config_combine_sort_fcn (gconstpointer p_a,
return nm_assert_unreachable_val (0);
}
-static const NML3ConfigData *
-_l3cfg_combine_config (GArray *l3_config_datas,
- NMDedupMultiIndex *multi_idx,
- int ifindex)
+static gboolean
+_l3cfg_update_combined_config (NML3Cfg *self,
+ const NML3ConfigData **out_old /* transfer reference */)
{
+ nm_auto_unref_l3cd const NML3ConfigData *l3cd_old = NULL;
+ nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
+ NMDedupMultiIndex *multi_idx;
gs_free L3ConfigData **infos_heap = NULL;
- NML3ConfigData *l3cd;
L3ConfigData **infos;
+ GArray *l3_config_datas;
guint i;
- if ( !l3_config_datas
- || l3_config_datas->len == 0)
- return NULL;
-
- if (l3_config_datas->len == 1)
- return nm_l3_config_data_ref (_l3_config_datas_at (l3_config_datas, 0)->merge_info.l3cd);
-
- if (l3_config_datas->len < 300 / sizeof (infos[0]))
- infos = g_alloca (l3_config_datas->len * sizeof (infos[0]));
- else {
- infos_heap = g_new (L3ConfigData *, l3_config_datas->len);
- infos = infos_heap;
- }
+ nm_assert (NM_IS_L3CFG (self));
+ nm_assert (!out_old || !*out_old);
- for (i = 0; i < l3_config_datas->len; i++)
- infos[i] = _l3_config_datas_at (l3_config_datas, i);
+ if (!self->priv.changed_configs)
+ return FALSE;
- g_qsort_with_data (infos,
- l3_config_datas->len,
- sizeof (infos[0]),
- _l3_config_combine_sort_fcn,
- NULL);
+ self->priv.changed_configs = FALSE;
- nm_assert (&infos[0]->merge_info == (NML3ConfigDatMergeInfo *) infos[0]);
+ multi_idx = nm_platform_get_multi_idx (self->priv.platform);
- l3cd = nm_l3_config_data_new_combined (multi_idx,
- ifindex,
- (const NML3ConfigDatMergeInfo *const*) infos,
- l3_config_datas->len);
+ l3_config_datas = self->priv.p->l3_config_datas;
- nm_assert (l3cd);
- nm_assert (nm_l3_config_data_get_ifindex (l3cd) == ifindex);
+ if ( l3_config_datas
+ && l3_config_datas->len > 0) {
- return nm_l3_config_data_seal (l3cd);
-}
+ l3cd = nm_l3_config_data_new (multi_idx, self->priv.ifindex);
-static gboolean
-_l3cfg_update_combined_config (NML3Cfg *self,
- const NML3ConfigData **out_old /* transfer reference */)
-{
- nm_auto_unref_l3cd const NML3ConfigData *l3cd_old = NULL;
- nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL;
+ if (l3_config_datas->len < 300 / sizeof (infos[0]))
+ infos = g_alloca (l3_config_datas->len * sizeof (infos[0]));
+ else {
+ infos_heap = g_new (L3ConfigData *, l3_config_datas->len);
+ infos = infos_heap;
+ }
- nm_assert (NM_IS_L3CFG (self));
- nm_assert (!out_old || !*out_old);
+ for (i = 0; i < l3_config_datas->len; i++)
+ infos[i] = _l3_config_datas_at (l3_config_datas, i);
+
+ g_qsort_with_data (infos,
+ l3_config_datas->len,
+ sizeof (infos[0]),
+ _l3_config_combine_sort_fcn,
+ NULL);
+
+ for (i = 0; i < l3_config_datas->len; i++) {
+ nm_l3_config_data_merge (l3cd,
+ infos[i]->l3cd,
+ infos[i]->merge_flags,
+ infos[i]->default_route_penalty_x,
+ NULL,
+ NULL);
+ }
- if (!self->priv.changed_configs)
- return FALSE;
+ nm_assert (l3cd);
+ nm_assert (nm_l3_config_data_get_ifindex (l3cd) == self->priv.ifindex);
- self->priv.changed_configs = FALSE;
+ nm_l3_config_data_seal (l3cd);
+ }
- l3cd = _l3cfg_combine_config (self->priv.p->l3_config_datas,
- nm_platform_get_multi_idx (self->priv.platform),
- self->priv.ifindex);
if (nm_l3_config_data_equal (l3cd, self->priv.p->combined_l3cd))
return FALSE;