From b40c0f028f37086991fefa9197708ba8c7b3d571 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Tue, 2 Jul 2019 10:45:53 +0200 Subject: [PATCH] Filter: Pre-evaluation of constant expressions --- conf/cf-lex.l | 1 + filter/Makefile | 3 +- filter/data.c | 9 ++++ filter/data.h | 3 +- filter/decl.m4 | 109 +++++++++++++++++++++++++++++----------------- filter/f-inst.c | 113 ++++++++++++++++++++++++++++++------------------ filter/filter.c | 13 +++--- lib/resource.h | 10 +++-- 8 files changed, 165 insertions(+), 96 deletions(-) diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 0aa9273f..38250d90 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -757,6 +757,7 @@ cf_pop_scope(void) { conf_this_scope->active = 0; conf_this_scope = conf_this_scope->next; + ASSERT(conf_this_scope); } diff --git a/filter/Makefile b/filter/Makefile index b2f8d96d..c2062534 100644 --- a/filter/Makefile +++ b/filter/Makefile @@ -3,7 +3,8 @@ obj := $(src-o-files) $(all-daemon) $(cf-local) -M4FLAGS_FILTERS=$(filter-out -s,$(M4FLAGS)) +#M4FLAGS_FILTERS=$(filter-out -s,$(M4FLAGS)) +M4FLAGS_FILTERS=$(M4FLAGS) $(o)inst-gen.h: $(s)decl.m4 $(s)f-inst.c $(objdir)/.dir-stamp $(M4) $(M4FLAGS_FILTERS) -DTARGET=H -P $^ >$@ diff --git a/filter/data.c b/filter/data.c index 912e2b00..db55070f 100644 --- a/filter/data.c +++ b/filter/data.c @@ -514,6 +514,15 @@ val_format(const struct f_val *v, buffer *buf) } } +char * +val_format_str(struct linpool *lp, const struct f_val *v) { + buffer b; + LOG_BUFFER_INIT(b); + val_format(v, &b); + return lp_strdup(lp, b.start); +} + + static char val_dump_buffer[1024]; const char * val_dump(const struct f_val *v) { diff --git a/filter/data.h b/filter/data.h index 6973008f..083595f4 100644 --- a/filter/data.h +++ b/filter/data.h @@ -119,7 +119,7 @@ enum f_lval_type { struct f_lval { enum f_lval_type type; union { - const struct symbol *sym; + struct symbol *sym; struct f_dynamic_attr da; struct f_static_attr sa; }; @@ -169,6 +169,7 @@ void trie_format(const struct f_trie *t, buffer *buf); int val_same(const struct f_val *v1, const struct f_val *v2); int val_compare(const struct f_val *v1, const struct f_val *v2); void val_format(const struct f_val *v, buffer *buf); +char *val_format_str(struct linpool *lp, const struct f_val *v); const char *val_dump(const struct f_val *v); static inline int val_is_ip4(const struct f_val *v) diff --git a/filter/decl.m4 b/filter/decl.m4 index 786fee31..cc069485 100644 --- a/filter/decl.m4 +++ b/filter/decl.m4 @@ -53,7 +53,12 @@ m4_define(FID_LINE_IN, `m4_divert(107)') m4_define(FID_INTERPRET_BODY, `m4_divert(108)') m4_define(FID_ALL, `FID_INTERPRET_BODY'); -m4_define(FID_HIC, `m4_ifelse(TARGET, [[H]], $1, TARGET, [[I]], $2, TARGET, [[C]], $3)') +m4_define(FID_HIC, `m4_ifelse(TARGET, [[H]], [[$1]], TARGET, [[I]], [[$2]], TARGET, [[C]], [[$3]])') + +m4_define(FID_INTERPRET_EXEC, `FID_HIC(,[[FID_INTERPRET_BODY()]],[[m4_divert(-1)]])') +m4_define(FID_INTERPRET_NEW, `FID_HIC(,[[m4_divert(-1)]],[[FID_INTERPRET_BODY()]])') +m4_define(NEVER_CONSTANT, `m4_define([[INST_NEVER_CONSTANT]])') +m4_define(FID_IFCONST, `m4_ifdef([[INST_NEVER_CONSTANT]],[[$2]],[[$1]])') m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[ FID_ENUM @@ -72,26 +77,29 @@ FID_NEW FID_HIC( [[ struct f_inst *f_new_inst_]]INST_NAME()[[(enum f_instruction_code fi_code -[[m4_undivert(102)]] +m4_undivert(102) );]], [[ case INST_NAME(): #define whati (&(what->i_]]INST_NAME()[[)) m4_ifelse(m4_eval(INST_INVAL() > 0), 1, [[if (fstk->vcnt < INST_INVAL()) runtime("Stack underflow"); fstk->vcnt -= INST_INVAL(); ]]) - [[m4_undivert(108)]] + m4_undivert(108) #undef whati break; ]], [[ struct f_inst *f_new_inst_]]INST_NAME()[[(enum f_instruction_code fi_code -[[m4_undivert(102)]] +m4_undivert(102) ) { struct f_inst *what = fi_new(fi_code); + FID_IFCONST([[uint constargs = 1;]]) #define whati (&(what->i_]]INST_NAME()[[)) - [[m4_undivert(103)]] + m4_undivert(103) + FID_IFCONST([[if (!constargs)]]) + return what; + FID_IFCONST([[m4_undivert(108)]]) #undef whati - return what; } ]]) @@ -130,13 +138,14 @@ m4_undivert(106) #undef f1 #undef f2 break; - +m4_divert(-1)FID_FLUSH(101,200) ]])') m4_define(INST, `m4_dnl INST_FLUSH()m4_dnl m4_define([[INST_NAME]], [[$1]])m4_dnl m4_define([[INST_INVAL]], [[$2]])m4_dnl +m4_undefine([[INST_NEVER_CONSTANT]])m4_dnl FID_ALL() m4_dnl ') @@ -149,22 +158,18 @@ FID_NEW_ARGS , $1 $2 FID_NEW_BODY whati->$2 = $2; -m4_ifelse($3,,,[[ FID_LINEARIZE_BODY -item->$3 = whati->$2; +item->$2 = whati->$2; +m4_ifelse($3,,,[[ +FID_SAME_BODY +if ($3) return 0; ]]) m4_ifelse($4,,,[[ -FID_SAME_BODY -if ($4) return 0; -]]) -m4_ifelse($5,,,[[ FID_DUMP_BODY -debug("%s$5\n", INDENT, $6); -]]) -m4_ifelse($7,,,[[ -FID_INTERPRET_BODY -$7 +debug("%s$4\n", INDENT, $5); ]]) +FID_INTERPRET_EXEC +const $1 $2 = whati->$2 FID_ALL') m4_define(ARG_ANY, ` @@ -174,34 +179,39 @@ FID_NEW_ARGS , struct f_inst * f$1 FID_NEW_BODY whati->f$1 = f$1; -for (const struct f_inst *child = f$1; child; child = child->next) what->size += child->size; +for (const struct f_inst *child = f$1; child; child = child->next) { + what->size += child->size; +FID_IFCONST([[ + if (child->fi_code != FI_CONSTANT) + constargs = 0; +]]) +} FID_LINEARIZE_BODY -pos = linearize(dest, whati->f$1, pos);m4_dnl +pos = linearize(dest, whati->f$1, pos); FID_ALL()') m4_define(ARG, `ARG_ANY($1) -FID_INTERPRET_BODY +FID_INTERPRET_EXEC() if (v$1.type != $2) runtime("Argument $1 of instruction %s must be of type $2, got 0x%02x", f_instruction_name(what->fi_code), v$1.type)m4_dnl FID_ALL()') -m4_define(LINEX, `FID_INTERPRET_BODY -do { +m4_define(LINEX, `FID_INTERPRET_EXEC()LINEX_($1)FID_INTERPRET_NEW()return $1 FID_ALL()') +m4_define(LINEX_, `do { fstk->estk[fstk->ecnt].pos = 0; fstk->estk[fstk->ecnt].line = $1; fstk->estk[fstk->ecnt].ventry = fstk->vcnt; fstk->estk[fstk->ecnt].vbase = fstk->estk[fstk->ecnt-1].vbase; fstk->estk[fstk->ecnt].emask = 0; fstk->ecnt++; -} while (0)m4_dnl -FID_ALL()') +} while (0)') m4_define(LINE, ` FID_LINE_IN const struct f_line * fl$1; FID_STRUCT_IN -const struct f_inst * f$1; +struct f_inst * f$1; FID_NEW_ARGS -, const struct f_inst * f$1 +, struct f_inst * f$1 FID_NEW_BODY whati->f$1 = f$1; FID_DUMP_BODY @@ -210,23 +220,25 @@ FID_LINEARIZE_BODY item->fl$1 = f_linearize(whati->f$1); FID_SAME_BODY if (!f_same(f1->fl$1, f2->fl$1)) return 0; -FID_INTERPRET_BODY +FID_INTERPRET_EXEC do { if (whati->fl$1) { - LINEX(whati->fl$1); -} } while(0)m4_dnl + LINEX_(whati->fl$1); +} } while(0) +FID_INTERPRET_NEW +return whati->f$1 FID_ALL()') m4_define(RESULT, `RESULT_VAL([[ (struct f_val) { .type = $1, .val.$2 = $3 } ]])') -m4_define(RESULT_VAL, `FID_INTERPRET_BODY()do { res = $1; fstk->vcnt++; } while (0)FID_ALL()') +m4_define(RESULT_VAL, `FID_HIC(, [[do { res = $1; fstk->vcnt++; } while (0)]], +[[return fi_constant(what, $1)]])') m4_define(RESULT_VOID, `RESULT_VAL([[ (struct f_val) { .type = T_VOID } ]])') -m4_define(SYMBOL, `FID_MEMBER(const struct symbol *, sym, sym, -[[strcmp(f1->sym->name, f2->sym->name) || (f1->sym->class != f2->sym->class)]], symbol %s, item->sym->name, const struct symbol *sym = whati->sym)') -m4_define(FRET, `') -m4_define(ECS, `FID_MEMBER(enum ec_subtype, ecs, ecs, f1->ecs != f2->ecs, ec subtype %s, ec_subtype_str(item->ecs), enum ec_subtype ecs = whati->ecs)') -m4_define(RTC, `FID_MEMBER(const struct rtable_config *, rtc, rtc, [[strcmp(f1->rtc->name, f2->rtc->name)]], route table %s, item->rtc->name, struct rtable *table = whati->rtc->table)') -m4_define(STATIC_ATTR, `FID_MEMBER(struct f_static_attr, sa, sa, f1->sa.sa_code != f2->sa.sa_code,,, struct f_static_attr sa = whati->sa)') -m4_define(DYNAMIC_ATTR, `FID_MEMBER(struct f_dynamic_attr, da, da, f1->da.ea_code != f2->da.ea_code,,, struct f_dynamic_attr da = whati->da)') +m4_define(SYMBOL, `FID_MEMBER(struct symbol *, sym, +[[strcmp(f1->sym->name, f2->sym->name) || (f1->sym->class != f2->sym->class)]], symbol %s, item->sym->name)') +m4_define(RTC, `FID_MEMBER(struct rtable_config *, rtc, [[strcmp(f1->rtc->name, f2->rtc->name)]], route table %s, item->rtc->name)') +m4_define(STATIC_ATTR, `FID_MEMBER(struct f_static_attr, sa, f1->sa.sa_code != f2->sa.sa_code,,)') +m4_define(DYNAMIC_ATTR, `FID_MEMBER(struct f_dynamic_attr, da, f1->da.ea_code != f2->da.ea_code,,)') +m4_define(ACCESS_RTE, `NEVER_CONSTANT()') m4_define(FID_WR_PUT_LIST) m4_define(FID_WR_PUT_ALSO, `m4_define([[FID_WR_PUT_LIST]],FID_WR_PUT_LIST()[[FID_WR_DPUT(]]FID_WR_DIDX[[)FID_WR_DPUT(]]$1[[)]])m4_define([[FID_WR_DIDX]],m4_eval(FID_WR_DIDX+1))m4_divert(FID_WR_DIDX)') @@ -267,8 +279,25 @@ fi_new(enum f_instruction_code fi_code) return what; } +static inline struct f_inst * +fi_constant(struct f_inst *what, struct f_val val) +{ + what->fi_code = FI_CONSTANT; + what->i_FI_CONSTANT.val = val; + return what; +} + +#define v1 whati->f1->i_FI_CONSTANT.val +#define v2 whati->f2->i_FI_CONSTANT.val +#define v3 whati->f3->i_FI_CONSTANT.val +#define runtime(fmt, ...) cf_error("filter preevaluation, line %d: " fmt, ifs->lino, ##__VA_ARGS__) +#define fpool cfg_mem +#define falloc(size) cfg_alloc(size) /* Instruction constructors */ FID_WR_PUT(3) +#undef v1 +#undef v2 +#undef v3 /* Line dumpers */ #define INDENT (((const char *) f_dump_line_indent_str) + sizeof(f_dump_line_indent_str) - (indent) - 1) @@ -387,9 +416,9 @@ FID_WR_PUT(3) m4_divert(-1) m4_changequote(`,') -m4_define(FID_CLEANUP, `m4_ifelse($1,$2,,[[m4_undivert($1)FID_CLEANUP(m4_eval($1+1),$2)]])') +m4_define(FID_FLUSH, `m4_ifelse($1,$2,,[[m4_undivert($1)FID_FLUSH(m4_eval($1+1),$2)]])') m4_define(FID_WR_DPUT, `m4_undivert($1)') -m4_m4wrap(`INST_FLUSH()m4_divert(0)FID_WR_PUT_LIST()m4_divert(-1)FID_CLEANUP(1,200)') +m4_m4wrap(`INST_FLUSH()m4_divert(0)FID_WR_PUT_LIST()m4_divert(-1)FID_FLUSH(1,200)') m4_changequote([[,]]) diff --git a/filter/f-inst.c b/filter/f-inst.c index a70a4a92..edc97794 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -37,12 +37,10 @@ * * m4_dnl FID_MEMBER( custom instruction member * m4_dnl C type, for storage in structs - * m4_dnl name in f_inst, how the member is named before linearization - * m4_dnl name in f_line_item, how the member is named afterwards + * m4_dnl name, how the member is named * m4_dnl comparator for same(), if different, this should be TRUE (CAVEAT) * m4_dnl dump format string debug -> format string for bvsnprintf * m4_dnl dump format args appropriate args - * m4_dnl interpreter body how to deal with this on execution * m4_dnl ) * * m4_dnl RESULT(type, union-field, value); putting this on value stack @@ -106,7 +104,7 @@ ARG_ANY(1); ARG(2, T_INT); - FID_MEMBER(enum ec_subtype, ecs, ecs, f1->ecs != f2->ecs, ec subtype %s, ec_subtype_str(item->ecs), enum ec_subtype ecs = whati->ecs); + FID_MEMBER(enum ec_subtype, ecs, f1->ecs != f2->ecs, ec subtype %s, ec_subtype_str(item->ecs)); int check, ipv4_used; u32 key, val; @@ -152,24 +150,37 @@ INST(FI_PATHMASK_CONSTRUCT, 0, 1) { ARG_ANY(1); - FID_MEMBER(uint, count, count, f1->count != f2->count, number of items %u, item->count); + FID_MEMBER(uint, count, f1->count != f2->count, number of items %u, item->count); FID_NEW_BODY uint len = 0; - uint dyn = 0; - for (const struct f_inst *tt = f1; tt; tt = tt->next, len++) - if (tt->fi_code != FI_CONSTANT) - dyn++; + for (const struct f_inst *tt = f1; tt; tt = tt->next, len++); whati->count = len; + struct f_inst **items; + if (constargs) { + items = alloca(len * sizeof(struct f_inst *)); + for (uint i=0; f1; i++) { + items[i] = f1; + f1 = f1->next; + items[i]->next = 0; + } + whati->f1 = NULL; + } FID_ALL + FID_INTERPRET_EXEC if (fstk->vcnt < whati->count) /* TODO: make this check systematic */ runtime("Construction of BGP path mask from %u elements must have at least that number of elements", whati->count); - struct f_path_mask *pm = lp_alloc(fs->pool, sizeof(struct f_path_mask) + whati->count * sizeof(struct f_path_mask_item)); +#define pv fstk->vstk[fstk->vcnt - count + i] + + FID_INTERPRET_NEW +#define pv items[i]->i_FI_CONSTANT.val + + FID_INTERPRET_BODY + struct f_path_mask *pm = falloc(sizeof(struct f_path_mask) + whati->count * sizeof(struct f_path_mask_item)); for (uint i=0; icount; i++) { -#define pv fstk->vstk[fstk->vcnt - whati->count + i] switch (pv.type) { case T_PATH_MASK_ITEM: pm->item[i] = pv.val.pmi; @@ -185,9 +196,11 @@ } } - fstk->vcnt -= whati->count; - pm->len = whati->count; + FID_INTERPRET_EXEC + fstk->vcnt -= whati->count; + FID_ALL + pm->len = whati->count; RESULT(T_PATH_MASK, path_mask, pm); } @@ -270,8 +283,10 @@ /* Set to indirect value prepared in v1 */ INST(FI_VAR_SET, 1, 0) { + NEVER_CONSTANT; ARG_ANY(1); SYMBOL; + if ((sym->class != (SYM_VARIABLE | v1.type)) && (v1.type != T_VOID)) { /* IP->Quad implicit conversion */ @@ -289,6 +304,7 @@ INST(FI_VAR_GET, 0, 1) { SYMBOL; + NEVER_CONSTANT; RESULT_VAL(fstk->vstk[curline.vbase + sym->offset]); } @@ -297,26 +313,27 @@ FID_MEMBER( struct f_val, val, - val, [[ !val_same(&(f1->val), &(f2->val)) ]], value %s, val_dump(&(item->val)) ); - RESULT_VAL(whati->val); + RESULT_VAL(val); } INST(FI_PRINT, 1, 0) { + NEVER_CONSTANT; ARG_ANY(1); val_format(&(v1), &fs->buf); } INST(FI_CONDITION, 1, 0) { ARG(1, T_BOOL); - if (res.val.i) + if (v1.val.i) LINE(2,0); else LINE(3,1); } INST(FI_PRINT_AND_DIE, 0, 0) { + NEVER_CONSTANT; FID_LINEARIZE_BODY { uint opos = pos; @@ -330,7 +347,7 @@ } FID_ALL - FID_MEMBER(enum filter_return, fret, fret, f1->fret != f2->fret, %s, filter_return_str(item->fret), enum filter_return fret = whati->fret); + FID_MEMBER(enum filter_return, fret, f1->fret != f2->fret, %s, filter_return_str(item->fret)); if ((fret == F_NOP || (fret != F_NONL && (what->flags & FIF_PRINTED))) && !(fs->flags & FF_SILENT)) @@ -663,7 +680,7 @@ runtime( "SADR expected" ); net_addr_ip6_sadr *net = (void *) v1.val.net; - net_addr *src = lp_alloc(fs->pool, sizeof(net_addr_ip6)); + net_addr *src = falloc(sizeof(net_addr_ip6)); net_fill_ip6(src, net->src_prefix, net->src_pxlen); RESULT(T_NET, net, src); @@ -721,6 +738,7 @@ } INST(FI_RETURN, 1, 1) { + NEVER_CONSTANT; /* Acquire the return value */ ARG_ANY(1); uint retpos = fstk->vcnt; @@ -748,6 +766,7 @@ } INST(FI_CALL, 0, 1) { + NEVER_CONSTANT; SYMBOL; /* Push the body on stack */ @@ -768,13 +787,14 @@ } INST(FI_DROP_RESULT, 1, 0) { + NEVER_CONSTANT; ARG_ANY(1); } INST(FI_SWITCH, 1, 0) { ARG_ANY(1); - FID_MEMBER(const struct f_tree *, tree, tree, [[!same_tree(f1->tree, f2->tree)]], tree %p, item->tree, const struct f_tree *tree = whati->tree); + FID_MEMBER(struct f_tree *, tree, [[!same_tree(f1->tree, f2->tree)]], tree %p, item->tree); const struct f_tree *t = find_tree(tree, &v1); if (!t) { @@ -782,7 +802,7 @@ t = find_tree(tree, &v1); if (!t) { debug( "No else statement?\n"); - break; + FID_HIC(,break,return NULL); } } /* It is actually possible to have t->data NULL */ @@ -801,7 +821,7 @@ INST(FI_PATH_PREPEND, 2, 1) { /* Path prepend */ ARG(1, T_PATH); ARG(2, T_INT); - RESULT(T_PATH, ad, [[ as_path_prepend(fs->pool, v1.val.ad, v2.val.i) ]]); + RESULT(T_PATH, ad, [[ as_path_prepend(fpool, v1.val.ad, v2.val.i) ]]); } INST(FI_CLIST_ADD, 2, 1) { /* (Extended) Community list add */ @@ -816,14 +836,14 @@ struct f_val dummy; if ((v2.type == T_PAIR) || (v2.type == T_QUAD)) - RESULT(T_CLIST, ad, [[ int_set_add(fs->pool, v1.val.ad, v2.val.i) ]]); + RESULT(T_CLIST, ad, [[ int_set_add(fpool, v1.val.ad, v2.val.i) ]]); /* IP->Quad implicit conversion */ else if (val_is_ip4(&v2)) - RESULT(T_CLIST, ad, [[ int_set_add(fs->pool, v1.val.ad, ipa_to_u32(v2.val.ip)) ]]); + RESULT(T_CLIST, ad, [[ int_set_add(fpool, v1.val.ad, ipa_to_u32(v2.val.ip)) ]]); else if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy)) runtime("Can't add set"); else if (v2.type == T_CLIST) - RESULT(T_CLIST, ad, [[ int_set_union(fs->pool, v1.val.ad, v2.val.ad) ]]); + RESULT(T_CLIST, ad, [[ int_set_union(fpool, v1.val.ad, v2.val.ad) ]]); else runtime("Can't add non-pair"); } @@ -834,11 +854,11 @@ if ((v2.type == T_SET) && eclist_set_type(v2.val.t)) runtime("Can't add set"); else if (v2.type == T_ECLIST) - RESULT(T_ECLIST, ad, [[ ec_set_union(fs->pool, v1.val.ad, v2.val.ad) ]]); + RESULT(T_ECLIST, ad, [[ ec_set_union(fpool, v1.val.ad, v2.val.ad) ]]); else if (v2.type != T_EC) runtime("Can't add non-ec"); else - RESULT(T_ECLIST, ad, [[ ec_set_add(fs->pool, v1.val.ad, v2.val.ec) ]]); + RESULT(T_ECLIST, ad, [[ ec_set_add(fpool, v1.val.ad, v2.val.ec) ]]); } else if (v1.type == T_LCLIST) @@ -847,11 +867,11 @@ if ((v2.type == T_SET) && lclist_set_type(v2.val.t)) runtime("Can't add set"); else if (v2.type == T_LCLIST) - RESULT(T_LCLIST, ad, [[ lc_set_union(fs->pool, v1.val.ad, v2.val.ad) ]]); + RESULT(T_LCLIST, ad, [[ lc_set_union(fpool, v1.val.ad, v2.val.ad) ]]); else if (v2.type != T_LC) runtime("Can't add non-lc"); else - RESULT(T_LCLIST, ad, [[ lc_set_add(fs->pool, v1.val.ad, v2.val.lc) ]]); + RESULT(T_LCLIST, ad, [[ lc_set_add(fpool, v1.val.ad, v2.val.lc) ]]); } @@ -874,7 +894,7 @@ else runtime("Can't delete non-integer (set)"); - RESULT(T_PATH, ad, [[ as_path_filter(fs->pool, v1.val.ad, set, key, 0) ]]); + RESULT(T_PATH, ad, [[ as_path_filter(fpool, v1.val.ad, set, key, 0) ]]); } else if (v1.type == T_CLIST) @@ -883,12 +903,12 @@ struct f_val dummy; if ((v2.type == T_PAIR) || (v2.type == T_QUAD)) - RESULT(T_CLIST, ad, [[ int_set_del(fs->pool, v1.val.ad, v2.val.i) ]]); + RESULT(T_CLIST, ad, [[ int_set_del(fpool, v1.val.ad, v2.val.i) ]]); /* IP->Quad implicit conversion */ else if (val_is_ip4(&v2)) - RESULT(T_CLIST, ad, [[ int_set_del(fs->pool, v1.val.ad, ipa_to_u32(v2.val.ip)) ]]); + RESULT(T_CLIST, ad, [[ int_set_del(fpool, v1.val.ad, ipa_to_u32(v2.val.ip)) ]]); else if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy) || (v2.type == T_CLIST)) - RESULT(T_CLIST, ad, [[ clist_filter(fs->pool, v1.val.ad, &v2, 0) ]]); + RESULT(T_CLIST, ad, [[ clist_filter(fpool, v1.val.ad, &v2, 0) ]]); else runtime("Can't delete non-pair"); } @@ -897,22 +917,22 @@ { /* v2.val is either EC or EC-set */ if ((v2.type == T_SET) && eclist_set_type(v2.val.t) || (v2.type == T_ECLIST)) - RESULT(T_ECLIST, ad, [[ eclist_filter(fs->pool, v1.val.ad, &v2, 0) ]]); + RESULT(T_ECLIST, ad, [[ eclist_filter(fpool, v1.val.ad, &v2, 0) ]]); else if (v2.type != T_EC) runtime("Can't delete non-ec"); else - RESULT(T_ECLIST, ad, [[ ec_set_del(fs->pool, v1.val.ad, v2.val.ec) ]]); + RESULT(T_ECLIST, ad, [[ ec_set_del(fpool, v1.val.ad, v2.val.ec) ]]); } else if (v1.type == T_LCLIST) { /* v2.val is either LC or LC-set */ if ((v2.type == T_SET) && lclist_set_type(v2.val.t) || (v2.type == T_LCLIST)) - RESULT(T_LCLIST, ad, [[ lclist_filter(fs->pool, v1.val.ad, &v2, 0) ]]); + RESULT(T_LCLIST, ad, [[ lclist_filter(fpool, v1.val.ad, &v2, 0) ]]); else if (v2.type != T_LC) runtime("Can't delete non-lc"); else - RESULT(T_LCLIST, ad, [[ lc_set_del(fs->pool, v1.val.ad, v2.val.lc) ]]); + RESULT(T_LCLIST, ad, [[ lc_set_del(fpool, v1.val.ad, v2.val.lc) ]]); } else @@ -927,7 +947,7 @@ u32 key = 0; if ((v2.type == T_SET) && (v2.val.t->from.type == T_INT)) - RESULT(T_PATH, ad, [[ as_path_filter(fs->pool, v1.val.ad, v2.val.t, key, 1) ]]); + RESULT(T_PATH, ad, [[ as_path_filter(fpool, v1.val.ad, v2.val.t, key, 1) ]]); else runtime("Can't filter integer"); } @@ -938,7 +958,7 @@ struct f_val dummy; if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy) || (v2.type == T_CLIST)) - RESULT(T_CLIST, ad, [[ clist_filter(fs->pool, v1.val.ad, &v2, 1) ]]); + RESULT(T_CLIST, ad, [[ clist_filter(fpool, v1.val.ad, &v2, 1) ]]); else runtime("Can't filter pair"); } @@ -947,7 +967,7 @@ { /* v2.val is either EC or EC-set */ if ((v2.type == T_SET) && eclist_set_type(v2.val.t) || (v2.type == T_ECLIST)) - RESULT(T_ECLIST, ad, [[ eclist_filter(fs->pool, v1.val.ad, &v2, 1) ]]); + RESULT(T_ECLIST, ad, [[ eclist_filter(fpool, v1.val.ad, &v2, 1) ]]); else runtime("Can't filter ec"); } @@ -956,7 +976,7 @@ { /* v2.val is either LC or LC-set */ if ((v2.type == T_SET) && lclist_set_type(v2.val.t) || (v2.type == T_LCLIST)) - RESULT(T_LCLIST, ad, [[ lclist_filter(fs->pool, v1.val.ad, &v2, 1) ]]); + RESULT(T_LCLIST, ad, [[ lclist_filter(fpool, v1.val.ad, &v2, 1) ]]); else runtime("Can't filter lc"); } @@ -966,7 +986,9 @@ } INST(FI_ROA_CHECK_IMPLICIT, 0, 1) { /* ROA Check */ + NEVER_CONSTANT; RTC(1); + struct rtable *table = rtc->table; ACCESS_RTE; ACCESS_EATTRS; const net_addr *net = (*fs->rte)->net->n.addr; @@ -994,9 +1016,11 @@ } INST(FI_ROA_CHECK_EXPLICIT, 2, 1) { /* ROA Check */ + NEVER_CONSTANT; ARG(1, T_NET); ARG(2, T_INT); RTC(3); + struct rtable *table = rtc->table; u32 as = v2.val.i; @@ -1015,15 +1039,18 @@ INST(FI_FORMAT, 1, 0) { /* Format */ ARG_ANY(1); - RESULT(T_STRING, s, val_format_str(fs, &v1)); + RESULT(T_STRING, s, val_format_str(fpool, &v1)); } INST(FI_ASSERT, 1, 0) { /* Birdtest Assert */ + NEVER_CONSTANT; ARG(1, T_BOOL); - FID_MEMBER(const char *, s, s, [[strcmp(f1->s, f2->s)]], string \"%s\", item->s); + FID_MEMBER(char *, s, [[strcmp(f1->s, f2->s)]], string \"%s\", item->s); + + ASSERT(s); if (!bt_assert_hook) runtime("No bt_assert hook registered, can't assert"); - bt_assert_hook(res.val.i, what); + bt_assert_hook(v1.val.i, what); } diff --git a/filter/filter.c b/filter/filter.c index ee29522e..ed0b21bc 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -150,14 +150,6 @@ f_rta_cow(struct filter_state *fs) f_cache_eattrs(fs); } -static char * -val_format_str(struct filter_state *fs, struct f_val *v) { - buffer b; - LOG_BUFFER_INIT(b); - val_format(v, &b); - return lp_strdup(fs->pool, b.start); -} - static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS; /** @@ -215,6 +207,9 @@ interpret(struct filter_state *fs, const struct f_line *line, struct f_val *val) return F_ERROR; \ } while(0) +#define falloc(size) lp_alloc(fs->pool, size) +#define fpool fs->pool + #define ACCESS_RTE do { if (!fs->rte) runtime("No route to access"); } while (0) #define ACCESS_EATTRS do { if (!fs->eattrs) f_cache_eattrs(fs); } while (0) @@ -224,6 +219,8 @@ interpret(struct filter_state *fs, const struct f_line *line, struct f_val *val) #undef v2 #undef v3 #undef runtime +#undef falloc +#undef fpool #undef ACCESS_RTE #undef ACCESS_EATTRS } diff --git a/lib/resource.h b/lib/resource.h index d9d4bb8f..ad17d9ed 100644 --- a/lib/resource.h +++ b/lib/resource.h @@ -101,9 +101,13 @@ void buffer_realloc(void **buf, unsigned *size, unsigned need, unsigned item_siz */ #define DMALLOC_DISABLE #include -#define xmalloc(size) _xmalloc_leap(__FILE__, __LINE__, size) -#define xrealloc(size) _xrealloc_leap(__FILE__, __LINE__, size) -#define xfree(ptr) _xfree_leap(__FILE__, __LINE__, ptr) +#define xmalloc(size) \ + dmalloc_malloc(__FILE__, __LINE__, (size), DMALLOC_FUNC_MALLOC, 0, 1) +#define xrealloc(ptr, size) \ + dmalloc_realloc(__FILE__, __LINE__, (ptr), (size), DMALLOC_FUNC_REALLOC, 1) +#define xfree(ptr) \ + dmalloc_free(__FILE__, __LINE__, (ptr), DMALLOC_FUNC_FREE) + #else /* * Unfortunately, several libraries we might want to link to define