summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-05-30 12:03:03 +0200
committerMaria Matejka <mq@ucw.cz>2022-05-30 14:39:09 +0200
commit938742decc6e1d6d3a0375dd012b75172e747bbc (patch)
treea10d9eb2811af43075c2c5272ece7b3dbbb38cdf /filter
parent950775f6fa3d569a9d7cd05e33538d35e895d688 (diff)
Squashing the route attribute structure into one level.
For now, all route attributes are stored as eattrs in ea_list. This should make route manipulation easier and it also allows for a layered approach of route attributes where updates from filters will be stored as an overlay over the previous version.
Diffstat (limited to 'filter')
-rw-r--r--filter/f-inst.c8
-rw-r--r--filter/filter.c41
2 files changed, 11 insertions, 38 deletions
diff --git a/filter/f-inst.c b/filter/f-inst.c
index c2abd5aa..65a0b011 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -212,7 +212,7 @@
* m4_dnl NEVER_CONSTANT-> don't generate pre-interpretation code at all
* m4_dnl ACCESS_RTE -> check that route is available, also NEVER_CONSTANT
* m4_dnl ACCESS_EATTRS -> pre-cache the eattrs; use only with ACCESS_RTE
- * m4_dnl f_rta_cow(fs) -> function to call before any change to route should be done
+ * m4_dnl f_rte_cow(fs) -> function to call before any change to route should be done
*
* m4_dnl If you are stymied, see FI_CALL or FI_CONSTANT or just search for
* m4_dnl the mentioned macros in this file to see what is happening there in wild.
@@ -578,7 +578,7 @@
STATIC_ATTR;
ARG_TYPE(1, sa.type);
- f_rta_cow(fs);
+ f_rte_cow(fs);
{
union {
struct nexthop_adata nha;
@@ -741,7 +741,7 @@
if (da->type >= EAF_TYPE__MAX)
bug("Unsupported attribute type");
- f_rta_cow(fs);
+ f_rte_cow(fs);
switch (da->type) {
case T_OPAQUE:
@@ -770,7 +770,7 @@
ACCESS_RTE;
ACCESS_EATTRS;
- f_rta_cow(fs);
+ f_rte_cow(fs);
ea_unset_attr(fs->eattrs, 1, da);
}
diff --git a/filter/filter.c b/filter/filter.c
index 9bedb938..ff6a3419 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -76,9 +76,6 @@ struct filter_state {
/* The route we are processing. This may be NULL to indicate no route available. */
struct rte **rte;
- /* The old rta to be freed after filters are done. */
- struct rta *old_rta;
-
/* Cached pointer to ea_list */
struct ea_list **eattrs;
@@ -99,7 +96,7 @@ void (*bt_assert_hook)(int result, const struct f_line_item *assert);
static inline void f_cache_eattrs(struct filter_state *fs)
{
- fs->eattrs = &((*fs->rte)->attrs->eattrs);
+ fs->eattrs = &((*fs->rte)->attrs);
}
static inline void f_rte_cow(struct filter_state *fs)
@@ -110,33 +107,6 @@ static inline void f_rte_cow(struct filter_state *fs)
*fs->rte = rte_cow(*fs->rte);
}
-/*
- * rta_cow - prepare rta for modification by filter
- */
-static void
-f_rta_cow(struct filter_state *fs)
-{
- if (!rta_is_cached((*fs->rte)->attrs))
- return;
-
- /* Prepare to modify rte */
- f_rte_cow(fs);
-
- /* Store old rta to free it later, it stores reference from rte_cow() */
- fs->old_rta = (*fs->rte)->attrs;
-
- /*
- * Get shallow copy of rta. Fields eattrs and nexthops of rta are shared
- * with fs->old_rta (they will be copied when the cached rta will be obtained
- * at the end of f_run()), also the lock of hostentry is inherited (we
- * suppose hostentry is not changed by filters).
- */
- (*fs->rte)->attrs = rta_do_cow((*fs->rte)->attrs, tmp_linpool);
-
- /* Re-cache the ea_list */
- f_cache_eattrs(fs);
-}
-
static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS;
/**
@@ -289,7 +259,7 @@ f_run(const struct filter *filter, struct rte **rte, int flags)
/* Run the interpreter itself */
enum filter_return fret = interpret(&filter_state, filter->root, NULL);
- if (filter_state.old_rta) {
+ if (filter_state.eattrs && !ea_is_cached(*filter_state.eattrs)) {
/*
* Cached rta was modified and filter_state->rte contains now an uncached one,
* sharing some part with the cached one. The cached rta should
@@ -302,6 +272,10 @@ f_run(const struct filter *filter, struct rte **rte, int flags)
* This is not the problem if rte was COW, because original rte
* also holds the same rta.
*/
+ ea_list *cached = *filter_state.eattrs;
+ while (cached && !ea_is_cached(cached))
+ cached = cached->next;
+
if (!rte_cow) {
/* Cache the new attrs */
(*filter_state.rte)->attrs = rta_lookup((*filter_state.rte)->attrs);
@@ -311,8 +285,7 @@ f_run(const struct filter *filter, struct rte **rte, int flags)
}
/* Uncache the old attrs and drop the pointer as it is invalid now. */
- rta_free(filter_state.old_rta);
- filter_state.old_rta = NULL;
+ rta_free(cached);
}
/* Process the filter output, log it and return */