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().
This commit is contained in:
Thomas Haller 2020-09-23 15:55:28 +02:00
parent 9cf49804d8
commit b4aa35e72d
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
5 changed files with 115 additions and 23 deletions

View file

@ -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;
}

View file

@ -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);

View file

@ -6,6 +6,7 @@
#include <net/if.h>
#include <linux/if_addr.h>
#include <linux/rtnetlink.h>
#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);

View file

@ -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,

View file

@ -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);
}