From b4aa35e72d57bea413f8073e304665fe76c36937 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 23 Sep 2020 15:55:28 +0200 Subject: [PATCH] l3cfg: extend nm_l3cfg_add_config() to accept default route table and metric Now that NMPlatformIP[46]Route can contain a wildcard table/metric, we can set the effectivey table/metric per NML3ConfigData that we merge. Pass it to nm_l3cfg_add_config(). --- src/nm-l3-config-data.c | 80 +++++++++++++++++++++++++++++------------ src/nm-l3-config-data.h | 2 ++ src/nm-l3cfg.c | 48 +++++++++++++++++++++++++ src/nm-l3cfg.h | 4 +++ src/tests/test-l3cfg.c | 4 +++ 5 files changed, 115 insertions(+), 23 deletions(-) diff --git a/src/nm-l3-config-data.c b/src/nm-l3-config-data.c index c73036ebd8..3cc5d67041 100644 --- a/src/nm-l3-config-data.c +++ b/src/nm-l3-config-data.c @@ -2514,17 +2514,34 @@ void nm_l3_config_data_merge(NML3ConfigData * self, const NML3ConfigData *src, NML3ConfigMergeFlags merge_flags, + const guint32 * default_route_table_x /* length 2, for IS_IPv4 */, + const guint32 * default_route_metric_x /* length 2, for IS_IPv4 */, const guint32 * default_route_penalty_x /* length 2, for IS_IPv4 */, NML3ConfigMergeHookAddObj hook_add_addr, gpointer hook_user_data) { - NMDedupMultiIter iter; - const NMPObject *obj; - int IS_IPv4; + static const guint32 x_default_route_table_x[2] = {RT_TABLE_MAIN, RT_TABLE_MAIN}; + static const guint32 x_default_route_metric_x[2] = {NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6, + NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4}; + static const guint32 x_default_route_penalty_x[2] = {0, 0}; + NMDedupMultiIter iter; + const NMPObject * obj; + int IS_IPv4; nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE)); nm_assert(_NM_IS_L3_CONFIG_DATA(src, TRUE)); + if (!default_route_table_x) + default_route_table_x = x_default_route_table_x; + if (!default_route_metric_x) + default_route_metric_x = x_default_route_metric_x; + if (!default_route_penalty_x) + default_route_penalty_x = x_default_route_penalty_x; + + nm_assert(default_route_table_x[0] != 0); + nm_assert(default_route_table_x[1] != 0); + nm_assert(default_route_metric_x[0] != 0); /* IPv6 route metric cannot be zero. */ + for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) { const int addr_family = IS_IPv4 ? AF_INET : AF_INET6; const NML3ConfigDatFlags has_dns_priority_flag = @@ -2546,41 +2563,58 @@ nm_l3_config_data_merge(NML3ConfigData * self, if (!NM_FLAGS_HAS(merge_flags, NM_L3_CONFIG_MERGE_FLAGS_NO_ROUTES)) { nm_l3_config_data_iter_obj_for_each(&iter, src, &obj, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4)) { - if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(NMP_OBJECT_CAST_IP_ROUTE(obj))) { + const NMPlatformIPRoute *r_src = NMP_OBJECT_CAST_IP_ROUTE(obj); + NMPlatformIPXRoute r; + +#define _ensure_r() \ + G_STMT_START \ + { \ + if (r_src != &r.rx) { \ + r_src = &r.rx; \ + if (IS_IPv4) \ + r.r4 = *NMP_OBJECT_CAST_IP4_ROUTE(obj); \ + else \ + r.r6 = *NMP_OBJECT_CAST_IP6_ROUTE(obj); \ + r.rx.ifindex = self->ifindex; \ + } \ + } \ + G_STMT_END + + if (r_src->table_any) { + _ensure_r(); + r.rx.table_any = FALSE; + r.rx.table_coerced = default_route_table_x[IS_IPv4]; + } + + if (r_src->metric_any) { + _ensure_r(); + r.rx.metric_any = FALSE; + r.rx.metric_any = default_route_metric_x[IS_IPv4]; + } + + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r_src)) { if (NM_FLAGS_HAS(merge_flags, NM_L3_CONFIG_MERGE_FLAGS_NO_DEFAULT_ROUTES) && !NM_FLAGS_HAS(src->flags, NM_L3_CONFIG_DAT_FLAGS_IGNORE_MERGE_NO_DEFAULT_ROUTES)) continue; - if (default_route_penalty_x && default_route_penalty_x[IS_IPv4] > 0) { - NMPlatformIPXRoute r; - - if (IS_IPv4) - r.r4 = *NMP_OBJECT_CAST_IP4_ROUTE(obj); - else - r.r6 = *NMP_OBJECT_CAST_IP6_ROUTE(obj); - r.rx.ifindex = self->ifindex; + _ensure_r(); r.rx.metric = nm_utils_ip_route_metric_penalize(r.rx.metric, default_route_penalty_x[IS_IPv4]); - nm_l3_config_data_add_route_full(self, - addr_family, - NULL, - &r.rx, - NM_L3_CONFIG_ADD_FLAGS_EXCLUSIVE, - NULL, - NULL); - continue; } } + nm_l3_config_data_add_route_full(self, addr_family, - obj, - NULL, + r_src == &r.rx ? NULL : obj, + r_src == &r.rx ? r_src : NULL, NM_L3_CONFIG_ADD_FLAGS_EXCLUSIVE, NULL, NULL); } + +#undef _ensure_r } if (!NM_FLAGS_HAS(merge_flags, NM_L3_CONFIG_MERGE_FLAGS_NO_DNS)) @@ -2666,6 +2700,6 @@ nm_l3_config_data_new_clone(const NML3ConfigData *src, int ifindex) ifindex = src->ifindex; self = nm_l3_config_data_new(src->multi_idx, ifindex); - nm_l3_config_data_merge(self, src, NM_L3_CONFIG_MERGE_FLAGS_NONE, NULL, NULL, NULL); + nm_l3_config_data_merge(self, src, NM_L3_CONFIG_MERGE_FLAGS_NONE, NULL, NULL, NULL, NULL, NULL); return self; } diff --git a/src/nm-l3-config-data.h b/src/nm-l3-config-data.h index a91b0dc2d5..f374cf33db 100644 --- a/src/nm-l3-config-data.h +++ b/src/nm-l3-config-data.h @@ -136,6 +136,8 @@ typedef gboolean (*NML3ConfigMergeHookAddObj)(const NML3ConfigData *l3cd, void nm_l3_config_data_merge(NML3ConfigData * self, const NML3ConfigData *src, NML3ConfigMergeFlags merge_flags, + const guint32 *default_route_table_x /* length 2, for IS_IPv4 */, + const guint32 *default_route_metric_x /* length 2, for IS_IPv4 */, const guint32 *default_route_penalty_x /* length 2, for IS_IPv4 */, NML3ConfigMergeHookAddObj hook_add_addr, gpointer hook_user_data); diff --git a/src/nm-l3cfg.c b/src/nm-l3cfg.c index c54db03dce..2dac480836 100644 --- a/src/nm-l3cfg.c +++ b/src/nm-l3cfg.c @@ -6,6 +6,7 @@ #include #include +#include #include "platform/nm-platform.h" #include "platform/nmp-object.h" @@ -111,6 +112,20 @@ struct _NML3CfgCommitTypeHandle { typedef struct { const NML3ConfigData *l3cd; NML3ConfigMergeFlags merge_flags; + union { + struct { + guint32 default_route_table_6; + guint32 default_route_table_4; + }; + guint32 default_route_table_x[2]; + }; + union { + struct { + guint32 default_route_metric_6; + guint32 default_route_metric_4; + }; + guint32 default_route_metric_x[2]; + }; union { struct { guint32 default_route_penalty_6; @@ -2342,6 +2357,10 @@ nm_l3cfg_add_config(NML3Cfg * self, gboolean replace_same_tag, const NML3ConfigData *l3cd, int priority, + guint32 default_route_table_4, + guint32 default_route_table_6, + guint32 default_route_metric_4, + guint32 default_route_metric_6, guint32 default_route_penalty_4, guint32 default_route_penalty_6, guint32 acd_timeout_msec, @@ -2356,6 +2375,13 @@ nm_l3cfg_add_config(NML3Cfg * self, nm_assert(l3cd); nm_assert(nm_l3_config_data_get_ifindex(l3cd) == self->priv.ifindex); + nm_assert(default_route_metric_6 != 0u); /* IPv6 default route metric cannot be zero. */ + + if (default_route_table_4 == 0u) + default_route_table_4 = RT_TABLE_MAIN; + if (default_route_table_6 == 0u) + default_route_table_6 = RT_TABLE_MAIN; + if (!self->priv.p->l3_config_datas) { self->priv.p->l3_config_datas = g_array_new(FALSE, FALSE, sizeof(L3ConfigData)); g_object_ref(self); @@ -2396,6 +2422,10 @@ nm_l3cfg_add_config(NML3Cfg * self, .tag = tag, .l3cd = nm_l3_config_data_ref_and_seal(l3cd), .merge_flags = merge_flags, + .default_route_table_4 = default_route_table_4, + .default_route_table_6 = default_route_table_6, + .default_route_metric_4 = default_route_metric_4, + .default_route_metric_6 = default_route_metric_6, .default_route_penalty_4 = default_route_penalty_4, .default_route_penalty_6 = default_route_penalty_6, .acd_timeout_msec = acd_timeout_msec, @@ -2417,6 +2447,22 @@ nm_l3cfg_add_config(NML3Cfg * self, l3_config_data->merge_flags = merge_flags; changed = TRUE; } + if (l3_config_data->default_route_table_4 != default_route_table_4) { + l3_config_data->default_route_table_4 = default_route_table_4; + changed = TRUE; + } + if (l3_config_data->default_route_table_6 != default_route_table_6) { + l3_config_data->default_route_table_6 = default_route_table_6; + changed = TRUE; + } + if (l3_config_data->default_route_metric_4 != default_route_metric_4) { + l3_config_data->default_route_metric_4 = default_route_metric_4; + changed = TRUE; + } + if (l3_config_data->default_route_metric_6 != default_route_metric_6) { + l3_config_data->default_route_metric_6 = default_route_metric_6; + changed = TRUE; + } 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; @@ -2573,6 +2619,8 @@ _l3cfg_update_combined_config(NML3Cfg * self, nm_l3_config_data_merge(l3cd, l3_config_datas_sorted[i]->l3cd, l3_config_datas_sorted[i]->merge_flags, + l3_config_datas_sorted[i]->default_route_table_x, + l3_config_datas_sorted[i]->default_route_metric_x, l3_config_datas_sorted[i]->default_route_penalty_x, _l3_hook_add_addr_cb, &hook_data); diff --git a/src/nm-l3cfg.h b/src/nm-l3cfg.h index 0c377c9425..06048352e9 100644 --- a/src/nm-l3cfg.h +++ b/src/nm-l3cfg.h @@ -186,6 +186,10 @@ gboolean nm_l3cfg_add_config(NML3Cfg * self, gboolean replace_same_tag, const NML3ConfigData *l3cd, int priority, + guint32 default_route_table_4, + guint32 default_route_table_6, + guint32 default_route_metric_4, + guint32 default_route_metric_6, guint32 default_route_penalty_4, guint32 default_route_penalty_6, guint32 acd_timeout_msec, diff --git a/src/tests/test-l3cfg.c b/src/tests/test-l3cfg.c index 74a4dcc523..4ee9b7d666 100644 --- a/src/tests/test-l3cfg.c +++ b/src/tests/test-l3cfg.c @@ -276,6 +276,10 @@ test_l3cfg(gconstpointer test_data) 'a', 0, 0, + NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4, + NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6, + 0, + 0, acd_timeout_msec, NM_L3_CONFIG_MERGE_FLAGS_NONE); }