summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
Diffstat (limited to 'filter')
-rw-r--r--filter/filter.c36
1 files changed, 16 insertions, 20 deletions
diff --git a/filter/filter.c b/filter/filter.c
index 3b14fc0c..3f8968aa 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -471,26 +471,22 @@ static inline void f_rte_cow(void)
static void
f_rta_cow(void)
{
- if ((*f_rte)->attrs->aflags & RTAF_CACHED) {
-
- /* Prepare to modify rte */
- f_rte_cow();
-
- /* Store old rta to free it later */
- f_old_rta = (*f_rte)->attrs;
-
- /*
- * Alloc new rta, do shallow copy and update rte. Fields eattrs
- * and nexthops of rta are shared with f_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).
- */
- rta *ra = lp_alloc(f_pool, sizeof(rta));
- memcpy(ra, f_old_rta, sizeof(rta));
- ra->aflags = 0;
- (*f_rte)->attrs = ra;
- }
+ if (!rta_is_cached((*f_rte)->attrs))
+ return;
+
+ /* Prepare to modify rte */
+ f_rte_cow();
+
+ /* Store old rta to free it later, it stores reference from rte_cow() */
+ f_old_rta = (*f_rte)->attrs;
+
+ /*
+ * Get shallow copy of rta. Fields eattrs and nexthops of rta are shared
+ * with f_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).
+ */
+ (*f_rte)->attrs = rta_do_cow((*f_rte)->attrs, f_pool);
}
static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS;