diff options
Diffstat (limited to 'filter')
-rw-r--r-- | filter/filter.c | 64 | ||||
-rw-r--r-- | filter/filter.h | 3 |
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 */ |