mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-26 12:20:09 +01:00
platform: extend NMPRouteManager to work for routes
(cherry picked from commit 7c27c63bec)
This commit is contained in:
parent
506590ff66
commit
dab70027e6
4 changed files with 126 additions and 65 deletions
|
|
@ -9354,7 +9354,7 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode)
|
|||
keep_deleted_rules = FALSE;
|
||||
if (set_mode == NM_TERNARY_DEFAULT) {
|
||||
/* when exiting NM, we leave the device up and the rules configured.
|
||||
* We just all nmp_route_manager_sync_rules() to forget about the synced rules,
|
||||
* We just call nmp_route_manager_sync() to forget about the synced rules,
|
||||
* but we don't actually delete them.
|
||||
*
|
||||
* FIXME: that is a problem after restart of NetworkManager, because these
|
||||
|
|
@ -9368,7 +9368,7 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode)
|
|||
* file and track them after restart again. */
|
||||
keep_deleted_rules = TRUE;
|
||||
}
|
||||
nmp_route_manager_sync_rules(route_manager, keep_deleted_rules);
|
||||
nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, keep_deleted_rules);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
|||
|
|
@ -1675,14 +1675,14 @@ again:
|
|||
NULL);
|
||||
}
|
||||
if (nmtst_get_rand_uint32() % objs_sync->len == 0) {
|
||||
nmp_route_manager_sync_rules(route_manager, FALSE);
|
||||
nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
|
||||
g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC),
|
||||
==,
|
||||
i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
nmp_route_manager_sync_rules(route_manager, FALSE);
|
||||
nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
|
||||
g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC),
|
||||
==,
|
||||
objs_sync->len);
|
||||
|
|
@ -1713,14 +1713,14 @@ again:
|
|||
break;
|
||||
}
|
||||
if (nmtst_get_rand_uint32() % objs_sync->len == 0) {
|
||||
nmp_route_manager_sync_rules(route_manager, FALSE);
|
||||
nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
|
||||
g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC),
|
||||
==,
|
||||
objs_sync->len - i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
nmp_route_manager_sync_rules(route_manager, FALSE);
|
||||
nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
|
||||
|
||||
} else {
|
||||
for (i = 0; i < objs->len;) {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,10 @@ static void
|
|||
_track_data_assert(const TrackData *track_data, gboolean linked)
|
||||
{
|
||||
nm_assert(track_data);
|
||||
nm_assert(NMP_OBJECT_GET_TYPE(track_data->obj) == NMP_OBJECT_TYPE_ROUTING_RULE);
|
||||
nm_assert(NM_IN_SET(NMP_OBJECT_GET_TYPE(track_data->obj),
|
||||
NMP_OBJECT_TYPE_IP4_ROUTE,
|
||||
NMP_OBJECT_TYPE_IP6_ROUTE,
|
||||
NMP_OBJECT_TYPE_ROUTING_RULE));
|
||||
nm_assert(nmp_object_is_visible(track_data->obj));
|
||||
nm_assert(track_data->user_tag);
|
||||
nm_assert(!linked || !c_list_is_empty(&track_data->obj_lst));
|
||||
|
|
@ -132,9 +135,7 @@ _track_data_hash(gconstpointer data)
|
|||
_track_data_assert(track_data, FALSE);
|
||||
|
||||
nm_hash_init(&h, 269297543u);
|
||||
nm_platform_routing_rule_hash_update(NMP_OBJECT_CAST_ROUTING_RULE(track_data->obj),
|
||||
NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID,
|
||||
&h);
|
||||
nmp_object_id_hash_update(track_data->obj, &h);
|
||||
nm_hash_update_val(&h, track_data->user_tag);
|
||||
return nm_hash_complete(&h);
|
||||
}
|
||||
|
|
@ -149,10 +150,7 @@ _track_data_equal(gconstpointer data_a, gconstpointer data_b)
|
|||
_track_data_assert(track_data_b, FALSE);
|
||||
|
||||
return track_data_a->user_tag == track_data_b->user_tag
|
||||
&& (nm_platform_routing_rule_cmp(NMP_OBJECT_CAST_ROUTING_RULE(track_data_a->obj),
|
||||
NMP_OBJECT_CAST_ROUTING_RULE(track_data_b->obj),
|
||||
NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID)
|
||||
== 0);
|
||||
&& nmp_object_id_equal(track_data_a->obj, track_data_b->obj);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -199,13 +197,8 @@ static guint
|
|||
_track_obj_data_hash(gconstpointer data)
|
||||
{
|
||||
const TrackObjData *obj_data = data;
|
||||
NMHashState h;
|
||||
|
||||
nm_hash_init(&h, 432817559u);
|
||||
nm_platform_routing_rule_hash_update(NMP_OBJECT_CAST_ROUTING_RULE(obj_data->obj),
|
||||
NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID,
|
||||
&h);
|
||||
return nm_hash_complete(&h);
|
||||
return nmp_object_id_hash(obj_data->obj);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -214,10 +207,7 @@ _track_obj_data_equal(gconstpointer data_a, gconstpointer data_b)
|
|||
const TrackObjData *obj_data_a = data_a;
|
||||
const TrackObjData *obj_data_b = data_b;
|
||||
|
||||
return (nm_platform_routing_rule_cmp(NMP_OBJECT_CAST_ROUTING_RULE(obj_data_a->obj),
|
||||
NMP_OBJECT_CAST_ROUTING_RULE(obj_data_b->obj),
|
||||
NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID)
|
||||
== 0);
|
||||
return nmp_object_id_equal(obj_data_a->obj, obj_data_b->obj);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -250,10 +240,15 @@ _track_data_lookup(GHashTable *by_data, const NMPObject *obj, gconstpointer user
|
|||
return g_hash_table_lookup(by_data, &track_data_needle);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nmp_route_manager_track_rule:
|
||||
* nmp_route_manager_track:
|
||||
* @self: the #NMPRouteManager instance
|
||||
* @routing_rule: the #NMPlatformRoutingRule to track or untrack
|
||||
* @obj_type: the NMPObjectType of @obj that we are tracking.
|
||||
* @obj: the NMPlatformObject (of type NMPObjectType) to track. Usually
|
||||
* a #NMPlatformRoutingRule, #NMPlatformIP4Route or #NMPlatformIP6Route
|
||||
* pointer.
|
||||
* @track_priority: the priority for tracking the rule. Note that
|
||||
* negative values indicate a forced absence of the rule. Priorities
|
||||
* are compared with their absolute values (with higher absolute
|
||||
|
|
@ -270,11 +265,12 @@ _track_data_lookup(GHashTable *by_data, const NMPObject *obj, gconstpointer user
|
|||
* The purpose here is to set this to %NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG.
|
||||
*/
|
||||
void
|
||||
nmp_route_manager_track_rule(NMPRouteManager *self,
|
||||
const NMPlatformRoutingRule *routing_rule,
|
||||
gint32 track_priority,
|
||||
gconstpointer user_tag,
|
||||
gconstpointer user_tag_untrack)
|
||||
nmp_route_manager_track(NMPRouteManager *self,
|
||||
NMPObjectType obj_type,
|
||||
gconstpointer obj,
|
||||
gint32 track_priority,
|
||||
gconstpointer user_tag,
|
||||
gconstpointer user_tag_untrack)
|
||||
{
|
||||
NMPObject obj_stack;
|
||||
const NMPObject *p_obj_stack;
|
||||
|
|
@ -286,11 +282,18 @@ nmp_route_manager_track_rule(NMPRouteManager *self,
|
|||
gboolean track_priority_present;
|
||||
|
||||
g_return_if_fail(NMP_IS_ROUTE_MANAGER(self));
|
||||
g_return_if_fail(routing_rule);
|
||||
g_return_if_fail(obj);
|
||||
g_return_if_fail(user_tag);
|
||||
|
||||
/* The route must not be tied to an interface. We can only handle here
|
||||
* blackhole/unreachable/prohibit route types. */
|
||||
g_return_if_fail(obj_type == NMP_OBJECT_TYPE_ROUTING_RULE
|
||||
|| (NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)
|
||||
&& ((const NMPlatformIPRoute *) obj)->ifindex == 0));
|
||||
|
||||
nm_assert(track_priority != G_MININT32);
|
||||
|
||||
p_obj_stack = nmp_object_stackinit(&obj_stack, NMP_OBJECT_TYPE_ROUTING_RULE, routing_rule);
|
||||
p_obj_stack = nmp_object_stackinit(&obj_stack, obj_type, obj);
|
||||
|
||||
nm_assert(nmp_object_is_visible(p_obj_stack));
|
||||
|
||||
|
|
@ -363,12 +366,13 @@ nmp_route_manager_track_rule(NMPRouteManager *self,
|
|||
_track_data_assert(track_data, TRUE);
|
||||
|
||||
if (changed) {
|
||||
_LOGD("routing-rule: track [" NM_HASH_OBFUSCATE_PTR_FMT ",%s%u] \"%s\")",
|
||||
_LOGD("track [" NM_HASH_OBFUSCATE_PTR_FMT ",%s%u] %s \"%s\"",
|
||||
NM_HASH_OBFUSCATE_PTR(track_data->user_tag),
|
||||
(track_data->track_priority_val == 0
|
||||
? ""
|
||||
: (track_data->track_priority_present ? "+" : "-")),
|
||||
(guint) track_data->track_priority_val,
|
||||
NMP_OBJECT_GET_CLASS(track_data->obj)->obj_type_name,
|
||||
nmp_object_to_string(track_data->obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0));
|
||||
}
|
||||
}
|
||||
|
|
@ -386,8 +390,9 @@ _track_data_untrack(NMPRouteManager *self,
|
|||
nm_assert(self->by_data);
|
||||
nm_assert(g_hash_table_lookup(self->by_data, track_data) == track_data);
|
||||
|
||||
_LOGD("routing-rule: untrack [" NM_HASH_OBFUSCATE_PTR_FMT "] \"%s\"",
|
||||
_LOGD("untrack [" NM_HASH_OBFUSCATE_PTR_FMT "] %s \"%s\"",
|
||||
NM_HASH_OBFUSCATE_PTR(track_data->user_tag),
|
||||
NMP_OBJECT_GET_CLASS(track_data->obj)->obj_type_name,
|
||||
nmp_object_to_string(track_data->obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0));
|
||||
|
||||
#if NM_MORE_ASSERTS
|
||||
|
|
@ -425,19 +430,24 @@ _track_data_untrack(NMPRouteManager *self,
|
|||
}
|
||||
|
||||
void
|
||||
nmp_route_manager_untrack_rule(NMPRouteManager *self,
|
||||
const NMPlatformRoutingRule *routing_rule,
|
||||
gconstpointer user_tag)
|
||||
nmp_route_manager_untrack(NMPRouteManager *self,
|
||||
NMPObjectType obj_type,
|
||||
gconstpointer obj,
|
||||
gconstpointer user_tag)
|
||||
{
|
||||
NMPObject obj_stack;
|
||||
const NMPObject *p_obj_stack;
|
||||
TrackData *track_data;
|
||||
|
||||
g_return_if_fail(NMP_IS_ROUTE_MANAGER(self));
|
||||
g_return_if_fail(routing_rule);
|
||||
nm_assert(NM_IN_SET(obj_type,
|
||||
NMP_OBJECT_TYPE_IP4_ROUTE,
|
||||
NMP_OBJECT_TYPE_IP6_ROUTE,
|
||||
NMP_OBJECT_TYPE_ROUTING_RULE));
|
||||
g_return_if_fail(obj);
|
||||
g_return_if_fail(user_tag);
|
||||
|
||||
p_obj_stack = nmp_object_stackinit(&obj_stack, NMP_OBJECT_TYPE_ROUTING_RULE, routing_rule);
|
||||
p_obj_stack = nmp_object_stackinit(&obj_stack, obj_type, obj);
|
||||
|
||||
nm_assert(nmp_object_is_visible(p_obj_stack));
|
||||
|
||||
|
|
@ -490,29 +500,41 @@ nmp_route_manager_untrack_all(NMPRouteManager *self,
|
|||
g_hash_table_remove(self->by_user_tag, user_tag_data);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nmp_route_manager_sync_rules(NMPRouteManager *self, gboolean keep_deleted_rules)
|
||||
nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean keep_deleted)
|
||||
{
|
||||
const NMDedupMultiHeadEntry *pl_head_entry;
|
||||
NMDedupMultiIter pl_iter;
|
||||
const NMPObject *plobj;
|
||||
gs_unref_ptrarray GPtrArray *rules_to_delete = NULL;
|
||||
gs_unref_ptrarray GPtrArray *objs_to_delete = NULL;
|
||||
TrackObjData *obj_data;
|
||||
GHashTableIter h_iter;
|
||||
guint i;
|
||||
const TrackData *td_best;
|
||||
|
||||
g_return_if_fail(NMP_IS_ROUTE_MANAGER(self));
|
||||
g_return_if_fail(NM_IN_SET(obj_type,
|
||||
NMP_OBJECT_TYPE_IP4_ROUTE,
|
||||
NMP_OBJECT_TYPE_IP6_ROUTE,
|
||||
NMP_OBJECT_TYPE_ROUTING_RULE));
|
||||
|
||||
_LOGD("sync%s", keep_deleted_rules ? " (don't remove any rules)" : "");
|
||||
_LOGD("sync %s%s",
|
||||
nmp_class_from_type(obj_type)->obj_type_name,
|
||||
keep_deleted ? " (don't remove any)" : "");
|
||||
|
||||
if (obj_type == NMP_OBJECT_TYPE_ROUTING_RULE)
|
||||
pl_head_entry = nm_platform_lookup_obj_type(self->platform, obj_type);
|
||||
else
|
||||
pl_head_entry = nm_platform_lookup_object(self->platform, obj_type, 0);
|
||||
|
||||
pl_head_entry = nm_platform_lookup_obj_type(self->platform, NMP_OBJECT_TYPE_ROUTING_RULE);
|
||||
if (pl_head_entry) {
|
||||
nmp_cache_iter_for_each (&pl_iter, pl_head_entry, &plobj) {
|
||||
obj_data = g_hash_table_lookup(self->by_obj, &plobj);
|
||||
|
||||
if (!obj_data) {
|
||||
/* this rule is not tracked. It was externally added, hence we
|
||||
/* this obj is not tracked. It was externally added, hence we
|
||||
* ignore it. */
|
||||
continue;
|
||||
}
|
||||
|
|
@ -535,28 +557,36 @@ nmp_route_manager_sync_rules(NMPRouteManager *self, gboolean keep_deleted_rules)
|
|||
}
|
||||
}
|
||||
|
||||
if (keep_deleted_rules) {
|
||||
_LOGD("forget/leak rule added by us: %s",
|
||||
if (keep_deleted) {
|
||||
_LOGD("forget/leak object added by us: %s \"%s\"",
|
||||
NMP_OBJECT_GET_CLASS(plobj)->obj_type_name,
|
||||
nmp_object_to_string(plobj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!rules_to_delete)
|
||||
rules_to_delete = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref);
|
||||
if (!objs_to_delete)
|
||||
objs_to_delete = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref);
|
||||
|
||||
g_ptr_array_add(rules_to_delete, (gpointer) nmp_object_ref(plobj));
|
||||
g_ptr_array_add(objs_to_delete, (gpointer) nmp_object_ref(plobj));
|
||||
|
||||
obj_data->config_state = CONFIG_STATE_REMOVED_BY_US;
|
||||
}
|
||||
}
|
||||
|
||||
if (rules_to_delete) {
|
||||
for (i = 0; i < rules_to_delete->len; i++)
|
||||
nm_platform_object_delete(self->platform, rules_to_delete->pdata[i]);
|
||||
if (objs_to_delete) {
|
||||
for (i = 0; i < objs_to_delete->len; i++)
|
||||
nm_platform_object_delete(self->platform, objs_to_delete->pdata[i]);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init(&h_iter, self->by_obj);
|
||||
while (g_hash_table_iter_next(&h_iter, (gpointer *) &obj_data, NULL)) {
|
||||
if (NMP_OBJECT_GET_TYPE(obj_data->obj) != obj_type) {
|
||||
/* Here we need to iterate over all objects (rules and ip4/ip6 routes)
|
||||
* and skip over the non-interesting ones. It might be better to
|
||||
* track 3 separate CList by object type. */
|
||||
continue;
|
||||
}
|
||||
|
||||
td_best = _track_obj_data_get_best_data(obj_data);
|
||||
|
||||
if (!td_best) {
|
||||
|
|
@ -585,12 +615,18 @@ nmp_route_manager_sync_rules(NMPRouteManager *self, gboolean keep_deleted_rules)
|
|||
continue;
|
||||
|
||||
obj_data->config_state = CONFIG_STATE_ADDED_BY_US;
|
||||
nm_platform_routing_rule_add(self->platform,
|
||||
NMP_NLM_FLAG_ADD,
|
||||
NMP_OBJECT_CAST_ROUTING_RULE(obj_data->obj));
|
||||
|
||||
if (obj_type == NMP_OBJECT_TYPE_ROUTING_RULE) {
|
||||
nm_platform_routing_rule_add(self->platform,
|
||||
NMP_NLM_FLAG_ADD,
|
||||
NMP_OBJECT_CAST_ROUTING_RULE(obj_data->obj));
|
||||
} else
|
||||
nm_platform_ip_route_add(self->platform, NMP_NLM_FLAG_APPEND, obj_data->obj);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nmp_route_manager_track_rule_from_platform(NMPRouteManager *self,
|
||||
NMPlatform *platform,
|
||||
|
|
|
|||
|
|
@ -19,11 +19,27 @@ void nmp_route_manager_unref(NMPRouteManager *self);
|
|||
#define nm_auto_unref_route_manager nm_auto(_nmp_route_manager_unref)
|
||||
NM_AUTO_DEFINE_FCN0(NMPRouteManager *, _nmp_route_manager_unref, nmp_route_manager_unref);
|
||||
|
||||
void nmp_route_manager_track_rule(NMPRouteManager *self,
|
||||
const NMPlatformRoutingRule *routing_rule,
|
||||
gint32 track_priority,
|
||||
gconstpointer user_tag,
|
||||
gconstpointer user_tag_untrack);
|
||||
void nmp_route_manager_track(NMPRouteManager *self,
|
||||
NMPObjectType obj_type,
|
||||
gconstpointer obj,
|
||||
gint32 track_priority,
|
||||
gconstpointer user_tag,
|
||||
gconstpointer user_tag_untrack);
|
||||
|
||||
static inline void
|
||||
nmp_route_manager_track_rule(NMPRouteManager *self,
|
||||
const NMPlatformRoutingRule *routing_rule,
|
||||
gint32 track_priority,
|
||||
gconstpointer user_tag,
|
||||
gconstpointer user_tag_untrack)
|
||||
{
|
||||
nmp_route_manager_track(self,
|
||||
NMP_OBJECT_TYPE_ROUTING_RULE,
|
||||
routing_rule,
|
||||
track_priority,
|
||||
user_tag,
|
||||
user_tag_untrack);
|
||||
}
|
||||
|
||||
void nmp_route_manager_track_rule_default(NMPRouteManager *self,
|
||||
int addr_family,
|
||||
|
|
@ -36,9 +52,18 @@ void nmp_route_manager_track_rule_from_platform(NMPRouteManager *self,
|
|||
gint32 tracking_priority,
|
||||
gconstpointer user_tag);
|
||||
|
||||
void nmp_route_manager_untrack_rule(NMPRouteManager *self,
|
||||
const NMPlatformRoutingRule *routing_rule,
|
||||
gconstpointer user_tag);
|
||||
void nmp_route_manager_untrack(NMPRouteManager *self,
|
||||
NMPObjectType obj_type,
|
||||
gconstpointer obj,
|
||||
gconstpointer user_tag);
|
||||
|
||||
static inline void
|
||||
nmp_route_manager_untrack_rule(NMPRouteManager *self,
|
||||
const NMPlatformRoutingRule *routing_rule,
|
||||
gconstpointer user_tag)
|
||||
{
|
||||
nmp_route_manager_untrack(self, NMP_OBJECT_TYPE_ROUTING_RULE, routing_rule, user_tag);
|
||||
}
|
||||
|
||||
void nmp_route_manager_set_dirty(NMPRouteManager *self, gconstpointer user_tag);
|
||||
|
||||
|
|
@ -46,7 +71,7 @@ void nmp_route_manager_untrack_all(NMPRouteManager *self,
|
|||
gconstpointer user_tag,
|
||||
gboolean all /* or only dirty */);
|
||||
|
||||
void nmp_route_manager_sync_rules(NMPRouteManager *self, gboolean keep_deleted_rules);
|
||||
void nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean keep_deleted);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue