summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
Diffstat (limited to 'filter')
-rw-r--r--filter/filter.c64
-rw-r--r--filter/filter.h3
2 files changed, 29 insertions, 38 deletions
diff --git a/filter/filter.c b/filter/filter.c
index 6381550e..6290e74a 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -538,14 +538,23 @@ val_format(struct f_val v, buffer *buf)
static struct rte **f_rte;
static struct rta *f_old_rta;
-static struct ea_list **f_tmp_attrs;
+static struct ea_list **f_eattrs;
static struct linpool *f_pool;
static struct buffer f_buf;
static int f_flags;
+static inline void f_cache_eattrs(void)
+{
+ f_eattrs = &((*f_rte)->attrs->eattrs);
+}
+
static inline void f_rte_cow(void)
{
- *f_rte = rte_cow(*f_rte);
+ if (!((*f_rte)->flags & REF_COW))
+ return;
+
+ *f_rte = rte_do_cow(*f_rte);
+ f_eattrs = NULL;
}
/*
@@ -570,6 +579,9 @@ f_rta_cow(void)
* suppose hostentry is not changed by filters).
*/
(*f_rte)->attrs = rta_do_cow((*f_rte)->attrs, f_pool);
+
+ /* Re-cache the ea_list */
+ f_cache_eattrs();
}
static char *
@@ -603,7 +615,10 @@ static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS;
return val;
#define ACCESS_RTE \
- do { if (!f_rte) runtime("No route to access"); } while (0)
+ do { if (!f_rte) runtime("No route to access"); else f_cache_eattrs(); } while (0)
+
+#define ACCESS_EATTRS \
+ do { if (!f_eattrs) f_cache_eattrs(); } while (0)
#define BITFIELD_MASK(what) \
(1u << (what->a2.i >> 24))
@@ -995,17 +1010,11 @@ interpret(struct f_inst *what)
break;
case FI_EA_GET: /* Access to extended attributes */
ACCESS_RTE;
+ ACCESS_EATTRS;
{
- eattr *e = NULL;
u16 code = what->a2.i;
int f_type = what->aux >> 8;
-
- if (!(f_flags & FF_FORCE_TMPATTR))
- e = ea_find((*f_rte)->attrs->eattrs, code);
- if (!e)
- e = ea_find((*f_tmp_attrs), code);
- if ((!e) && (f_flags & FF_FORCE_TMPATTR))
- e = ea_find((*f_rte)->attrs->eattrs, code);
+ eattr *e = ea_find(*f_eattrs, code);
if (!e) {
/* A special case: undefined as_path looks like empty as_path */
@@ -1089,6 +1098,7 @@ interpret(struct f_inst *what)
break;
case FI_EA_SET:
ACCESS_RTE;
+ ACCESS_EATTRS;
ARG_ANY(1);
{
struct ea_list *l = lp_alloc(f_pool, sizeof(struct ea_list) + sizeof(eattr));
@@ -1143,13 +1153,7 @@ interpret(struct f_inst *what)
runtime( "Setting bit in bitfield attribute to non-bool value" );
{
/* First, we have to find the old value */
- eattr *e = NULL;
- if (!(f_flags & FF_FORCE_TMPATTR))
- e = ea_find((*f_rte)->attrs->eattrs, code);
- if (!e)
- e = ea_find((*f_tmp_attrs), code);
- if ((!e) && (f_flags & FF_FORCE_TMPATTR))
- e = ea_find((*f_rte)->attrs->eattrs, code);
+ eattr *e = ea_find(*f_eattrs, code);
u32 data = e ? e->u.data : 0;
if (v1.val.i)
@@ -1181,14 +1185,9 @@ interpret(struct f_inst *what)
default: bug("Unknown type in e,S");
}
- if (!(what->aux & EAF_TEMP) && (!(f_flags & FF_FORCE_TMPATTR))) {
- f_rta_cow();
- l->next = (*f_rte)->attrs->eattrs;
- (*f_rte)->attrs->eattrs = l;
- } else {
- l->next = (*f_tmp_attrs);
- (*f_tmp_attrs) = l;
- }
+ f_rta_cow();
+ l->next = *f_eattrs;
+ *f_eattrs = l;
}
break;
case FI_PREF_GET:
@@ -1518,11 +1517,12 @@ interpret(struct f_inst *what)
else
{
ACCESS_RTE;
+ ACCESS_EATTRS;
v1.val.net = (*f_rte)->net->n.addr;
/* We ignore temporary attributes, probably not a problem here */
/* 0x02 is a value of BA_AS_PATH, we don't want to include BGP headers */
- eattr *e = ea_find((*f_rte)->attrs->eattrs, EA_CODE(PROTOCOL_BGP, 0x02));
+ eattr *e = ea_find(*f_eattrs, EA_CODE(PROTOCOL_BGP, 0x02));
if (!e || e->type != EAF_TYPE_AS_PATH)
runtime("Missing AS_PATH attribute");
@@ -1720,7 +1720,6 @@ i_same(struct f_inst *f1, struct f_inst *f2)
* f_run - run a filter for a route
* @filter: filter to run
* @rte: route being filtered, may be modified
- * @tmp_attrs: temporary attributes, prepared by caller or generated by f_run()
* @tmp_pool: all filter allocations go from this pool
* @flags: flags
*
@@ -1742,7 +1741,7 @@ i_same(struct f_inst *f1, struct f_inst *f2)
* modified in place, old cached rta is possibly freed.
*/
int
-f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags)
+f_run(struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags)
{
if (filter == FILTER_ACCEPT)
return F_ACCEPT;
@@ -1755,7 +1754,6 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc
f_rte = rte;
f_old_rta = NULL;
- f_tmp_attrs = tmp_attrs;
f_pool = tmp_pool;
f_flags = flags;
@@ -1797,11 +1795,9 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc
struct f_val
f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool)
{
- struct ea_list *tmp_attrs = NULL;
f_rte = rte;
f_old_rta = NULL;
- f_tmp_attrs = &tmp_attrs;
f_pool = tmp_pool;
f_flags = 0;
@@ -1810,9 +1806,6 @@ f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool)
/* Note that in this function we assume that rte->attrs is private / uncached */
struct f_val res = interpret(expr);
- /* Hack to include EAF_TEMP attributes to the main list */
- (*rte)->attrs->eattrs = ea_append(tmp_attrs, (*rte)->attrs->eattrs);
-
return res;
}
@@ -1820,7 +1813,6 @@ struct f_val
f_eval(struct f_inst *expr, struct linpool *tmp_pool)
{
f_flags = 0;
- f_tmp_attrs = NULL;
f_rte = NULL;
f_pool = tmp_pool;
diff --git a/filter/filter.h b/filter/filter.h
index 909d09b1..febfdc65 100644
--- a/filter/filter.h
+++ b/filter/filter.h
@@ -175,7 +175,7 @@ void trie_format(struct f_trie *t, buffer *buf);
struct ea_list;
struct rte;
-int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags);
+int f_run(struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags);
struct f_val f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool);
struct f_val f_eval(struct f_inst *expr, struct linpool *tmp_pool);
uint f_eval_int(struct f_inst *expr);
@@ -285,7 +285,6 @@ struct f_trie
#define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val));
-#define FF_FORCE_TMPATTR 1 /* Force all attributes to be temporary */
#define FF_SILENT 2 /* Silent filter execution */
/* Bird Tests */