mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-08 12:18:42 +00:00
Filter: Pre-evaluation of constant expressions
This commit is contained in:
parent
30667d5041
commit
b40c0f028f
@ -757,6 +757,7 @@ cf_pop_scope(void)
|
|||||||
{
|
{
|
||||||
conf_this_scope->active = 0;
|
conf_this_scope->active = 0;
|
||||||
conf_this_scope = conf_this_scope->next;
|
conf_this_scope = conf_this_scope->next;
|
||||||
|
|
||||||
ASSERT(conf_this_scope);
|
ASSERT(conf_this_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@ obj := $(src-o-files)
|
|||||||
$(all-daemon)
|
$(all-daemon)
|
||||||
$(cf-local)
|
$(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
|
$(o)inst-gen.h: $(s)decl.m4 $(s)f-inst.c $(objdir)/.dir-stamp
|
||||||
$(M4) $(M4FLAGS_FILTERS) -DTARGET=H -P $^ >$@
|
$(M4) $(M4FLAGS_FILTERS) -DTARGET=H -P $^ >$@
|
||||||
|
@ -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];
|
static char val_dump_buffer[1024];
|
||||||
const char *
|
const char *
|
||||||
val_dump(const struct f_val *v) {
|
val_dump(const struct f_val *v) {
|
||||||
|
@ -119,7 +119,7 @@ enum f_lval_type {
|
|||||||
struct f_lval {
|
struct f_lval {
|
||||||
enum f_lval_type type;
|
enum f_lval_type type;
|
||||||
union {
|
union {
|
||||||
const struct symbol *sym;
|
struct symbol *sym;
|
||||||
struct f_dynamic_attr da;
|
struct f_dynamic_attr da;
|
||||||
struct f_static_attr sa;
|
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_same(const struct f_val *v1, const struct f_val *v2);
|
||||||
int val_compare(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);
|
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);
|
const char *val_dump(const struct f_val *v);
|
||||||
|
|
||||||
static inline int val_is_ip4(const struct f_val *v)
|
static inline int val_is_ip4(const struct f_val *v)
|
||||||
|
109
filter/decl.m4
109
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_INTERPRET_BODY, `m4_divert(108)')
|
||||||
|
|
||||||
m4_define(FID_ALL, `FID_INTERPRET_BODY');
|
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]], [[
|
m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[
|
||||||
FID_ENUM
|
FID_ENUM
|
||||||
@ -72,26 +77,29 @@ FID_NEW
|
|||||||
FID_HIC(
|
FID_HIC(
|
||||||
[[
|
[[
|
||||||
struct f_inst *f_new_inst_]]INST_NAME()[[(enum f_instruction_code fi_code
|
struct f_inst *f_new_inst_]]INST_NAME()[[(enum f_instruction_code fi_code
|
||||||
[[m4_undivert(102)]]
|
m4_undivert(102)
|
||||||
);]],
|
);]],
|
||||||
[[
|
[[
|
||||||
case INST_NAME():
|
case INST_NAME():
|
||||||
#define whati (&(what->i_]]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_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
|
#undef whati
|
||||||
break;
|
break;
|
||||||
]],
|
]],
|
||||||
[[
|
[[
|
||||||
struct f_inst *f_new_inst_]]INST_NAME()[[(enum f_instruction_code fi_code
|
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);
|
struct f_inst *what = fi_new(fi_code);
|
||||||
|
FID_IFCONST([[uint constargs = 1;]])
|
||||||
#define whati (&(what->i_]]INST_NAME()[[))
|
#define whati (&(what->i_]]INST_NAME()[[))
|
||||||
[[m4_undivert(103)]]
|
m4_undivert(103)
|
||||||
#undef whati
|
FID_IFCONST([[if (!constargs)]])
|
||||||
return what;
|
return what;
|
||||||
|
FID_IFCONST([[m4_undivert(108)]])
|
||||||
|
#undef whati
|
||||||
}
|
}
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@ -130,13 +138,14 @@ m4_undivert(106)
|
|||||||
#undef f1
|
#undef f1
|
||||||
#undef f2
|
#undef f2
|
||||||
break;
|
break;
|
||||||
|
m4_divert(-1)FID_FLUSH(101,200)
|
||||||
]])')
|
]])')
|
||||||
|
|
||||||
m4_define(INST, `m4_dnl
|
m4_define(INST, `m4_dnl
|
||||||
INST_FLUSH()m4_dnl
|
INST_FLUSH()m4_dnl
|
||||||
m4_define([[INST_NAME]], [[$1]])m4_dnl
|
m4_define([[INST_NAME]], [[$1]])m4_dnl
|
||||||
m4_define([[INST_INVAL]], [[$2]])m4_dnl
|
m4_define([[INST_INVAL]], [[$2]])m4_dnl
|
||||||
|
m4_undefine([[INST_NEVER_CONSTANT]])m4_dnl
|
||||||
FID_ALL() m4_dnl
|
FID_ALL() m4_dnl
|
||||||
')
|
')
|
||||||
|
|
||||||
@ -149,22 +158,18 @@ FID_NEW_ARGS
|
|||||||
, $1 $2
|
, $1 $2
|
||||||
FID_NEW_BODY
|
FID_NEW_BODY
|
||||||
whati->$2 = $2;
|
whati->$2 = $2;
|
||||||
m4_ifelse($3,,,[[
|
|
||||||
FID_LINEARIZE_BODY
|
FID_LINEARIZE_BODY
|
||||||
item->$3 = whati->$2;
|
item->$2 = whati->$2;
|
||||||
|
m4_ifelse($3,,,[[
|
||||||
|
FID_SAME_BODY
|
||||||
|
if ($3) return 0;
|
||||||
]])
|
]])
|
||||||
m4_ifelse($4,,,[[
|
m4_ifelse($4,,,[[
|
||||||
FID_SAME_BODY
|
|
||||||
if ($4) return 0;
|
|
||||||
]])
|
|
||||||
m4_ifelse($5,,,[[
|
|
||||||
FID_DUMP_BODY
|
FID_DUMP_BODY
|
||||||
debug("%s$5\n", INDENT, $6);
|
debug("%s$4\n", INDENT, $5);
|
||||||
]])
|
|
||||||
m4_ifelse($7,,,[[
|
|
||||||
FID_INTERPRET_BODY
|
|
||||||
$7
|
|
||||||
]])
|
]])
|
||||||
|
FID_INTERPRET_EXEC
|
||||||
|
const $1 $2 = whati->$2
|
||||||
FID_ALL')
|
FID_ALL')
|
||||||
|
|
||||||
m4_define(ARG_ANY, `
|
m4_define(ARG_ANY, `
|
||||||
@ -174,34 +179,39 @@ FID_NEW_ARGS
|
|||||||
, struct f_inst * f$1
|
, struct f_inst * f$1
|
||||||
FID_NEW_BODY
|
FID_NEW_BODY
|
||||||
whati->f$1 = f$1;
|
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
|
FID_LINEARIZE_BODY
|
||||||
pos = linearize(dest, whati->f$1, pos);m4_dnl
|
pos = linearize(dest, whati->f$1, pos);
|
||||||
FID_ALL()')
|
FID_ALL()')
|
||||||
|
|
||||||
m4_define(ARG, `ARG_ANY($1)
|
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
|
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()')
|
FID_ALL()')
|
||||||
|
|
||||||
m4_define(LINEX, `FID_INTERPRET_BODY
|
m4_define(LINEX, `FID_INTERPRET_EXEC()LINEX_($1)FID_INTERPRET_NEW()return $1 FID_ALL()')
|
||||||
do {
|
m4_define(LINEX_, `do {
|
||||||
fstk->estk[fstk->ecnt].pos = 0;
|
fstk->estk[fstk->ecnt].pos = 0;
|
||||||
fstk->estk[fstk->ecnt].line = $1;
|
fstk->estk[fstk->ecnt].line = $1;
|
||||||
fstk->estk[fstk->ecnt].ventry = fstk->vcnt;
|
fstk->estk[fstk->ecnt].ventry = fstk->vcnt;
|
||||||
fstk->estk[fstk->ecnt].vbase = fstk->estk[fstk->ecnt-1].vbase;
|
fstk->estk[fstk->ecnt].vbase = fstk->estk[fstk->ecnt-1].vbase;
|
||||||
fstk->estk[fstk->ecnt].emask = 0;
|
fstk->estk[fstk->ecnt].emask = 0;
|
||||||
fstk->ecnt++;
|
fstk->ecnt++;
|
||||||
} while (0)m4_dnl
|
} while (0)')
|
||||||
FID_ALL()')
|
|
||||||
|
|
||||||
m4_define(LINE, `
|
m4_define(LINE, `
|
||||||
FID_LINE_IN
|
FID_LINE_IN
|
||||||
const struct f_line * fl$1;
|
const struct f_line * fl$1;
|
||||||
FID_STRUCT_IN
|
FID_STRUCT_IN
|
||||||
const struct f_inst * f$1;
|
struct f_inst * f$1;
|
||||||
FID_NEW_ARGS
|
FID_NEW_ARGS
|
||||||
, const struct f_inst * f$1
|
, struct f_inst * f$1
|
||||||
FID_NEW_BODY
|
FID_NEW_BODY
|
||||||
whati->f$1 = f$1;
|
whati->f$1 = f$1;
|
||||||
FID_DUMP_BODY
|
FID_DUMP_BODY
|
||||||
@ -210,23 +220,25 @@ FID_LINEARIZE_BODY
|
|||||||
item->fl$1 = f_linearize(whati->f$1);
|
item->fl$1 = f_linearize(whati->f$1);
|
||||||
FID_SAME_BODY
|
FID_SAME_BODY
|
||||||
if (!f_same(f1->fl$1, f2->fl$1)) return 0;
|
if (!f_same(f1->fl$1, f2->fl$1)) return 0;
|
||||||
FID_INTERPRET_BODY
|
FID_INTERPRET_EXEC
|
||||||
do { if (whati->fl$1) {
|
do { if (whati->fl$1) {
|
||||||
LINEX(whati->fl$1);
|
LINEX_(whati->fl$1);
|
||||||
} } while(0)m4_dnl
|
} } while(0)
|
||||||
|
FID_INTERPRET_NEW
|
||||||
|
return whati->f$1
|
||||||
FID_ALL()')
|
FID_ALL()')
|
||||||
|
|
||||||
m4_define(RESULT, `RESULT_VAL([[ (struct f_val) { .type = $1, .val.$2 = $3 } ]])')
|
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(RESULT_VOID, `RESULT_VAL([[ (struct f_val) { .type = T_VOID } ]])')
|
||||||
|
|
||||||
m4_define(SYMBOL, `FID_MEMBER(const struct symbol *, sym, sym,
|
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, const struct symbol *sym = whati->sym)')
|
[[strcmp(f1->sym->name, f2->sym->name) || (f1->sym->class != f2->sym->class)]], symbol %s, item->sym->name)')
|
||||||
m4_define(FRET, `')
|
m4_define(RTC, `FID_MEMBER(struct rtable_config *, rtc, [[strcmp(f1->rtc->name, f2->rtc->name)]], route table %s, item->rtc->name)')
|
||||||
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(STATIC_ATTR, `FID_MEMBER(struct f_static_attr, sa, f1->sa.sa_code != f2->sa.sa_code,,)')
|
||||||
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(DYNAMIC_ATTR, `FID_MEMBER(struct f_dynamic_attr, da, f1->da.ea_code != f2->da.ea_code,,)')
|
||||||
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(ACCESS_RTE, `NEVER_CONSTANT()')
|
||||||
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(FID_WR_PUT_LIST)
|
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)')
|
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;
|
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 */
|
/* Instruction constructors */
|
||||||
FID_WR_PUT(3)
|
FID_WR_PUT(3)
|
||||||
|
#undef v1
|
||||||
|
#undef v2
|
||||||
|
#undef v3
|
||||||
|
|
||||||
/* Line dumpers */
|
/* Line dumpers */
|
||||||
#define INDENT (((const char *) f_dump_line_indent_str) + sizeof(f_dump_line_indent_str) - (indent) - 1)
|
#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_divert(-1)
|
||||||
m4_changequote(`,')
|
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_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([[,]])
|
m4_changequote([[,]])
|
||||||
|
111
filter/f-inst.c
111
filter/f-inst.c
@ -37,12 +37,10 @@
|
|||||||
*
|
*
|
||||||
* m4_dnl FID_MEMBER( custom instruction member
|
* m4_dnl FID_MEMBER( custom instruction member
|
||||||
* m4_dnl C type, for storage in structs
|
* m4_dnl C type, for storage in structs
|
||||||
* m4_dnl name in f_inst, how the member is named before linearization
|
* m4_dnl name, how the member is named
|
||||||
* m4_dnl name in f_line_item, how the member is named afterwards
|
|
||||||
* m4_dnl comparator for same(), if different, this should be TRUE (CAVEAT)
|
* 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 string debug -> format string for bvsnprintf
|
||||||
* m4_dnl dump format args appropriate args
|
* m4_dnl dump format args appropriate args
|
||||||
* m4_dnl interpreter body how to deal with this on execution
|
|
||||||
* m4_dnl )
|
* m4_dnl )
|
||||||
*
|
*
|
||||||
* m4_dnl RESULT(type, union-field, value); putting this on value stack
|
* m4_dnl RESULT(type, union-field, value); putting this on value stack
|
||||||
@ -106,7 +104,7 @@
|
|||||||
ARG_ANY(1);
|
ARG_ANY(1);
|
||||||
ARG(2, T_INT);
|
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;
|
int check, ipv4_used;
|
||||||
u32 key, val;
|
u32 key, val;
|
||||||
@ -152,24 +150,37 @@
|
|||||||
|
|
||||||
INST(FI_PATHMASK_CONSTRUCT, 0, 1) {
|
INST(FI_PATHMASK_CONSTRUCT, 0, 1) {
|
||||||
ARG_ANY(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
|
FID_NEW_BODY
|
||||||
uint len = 0;
|
uint len = 0;
|
||||||
uint dyn = 0;
|
for (const struct f_inst *tt = f1; tt; tt = tt->next, len++);
|
||||||
for (const struct f_inst *tt = f1; tt; tt = tt->next, len++)
|
|
||||||
if (tt->fi_code != FI_CONSTANT)
|
|
||||||
dyn++;
|
|
||||||
|
|
||||||
whati->count = 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_ALL
|
||||||
|
|
||||||
|
FID_INTERPRET_EXEC
|
||||||
if (fstk->vcnt < whati->count) /* TODO: make this check systematic */
|
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);
|
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; i<whati->count; i++) {
|
for (uint i=0; i<whati->count; i++) {
|
||||||
#define pv fstk->vstk[fstk->vcnt - whati->count + i]
|
|
||||||
switch (pv.type) {
|
switch (pv.type) {
|
||||||
case T_PATH_MASK_ITEM:
|
case T_PATH_MASK_ITEM:
|
||||||
pm->item[i] = pv.val.pmi;
|
pm->item[i] = pv.val.pmi;
|
||||||
@ -185,9 +196,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FID_INTERPRET_EXEC
|
||||||
fstk->vcnt -= whati->count;
|
fstk->vcnt -= whati->count;
|
||||||
pm->len = whati->count;
|
FID_ALL
|
||||||
|
|
||||||
|
pm->len = whati->count;
|
||||||
RESULT(T_PATH_MASK, path_mask, pm);
|
RESULT(T_PATH_MASK, path_mask, pm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,8 +283,10 @@
|
|||||||
|
|
||||||
/* Set to indirect value prepared in v1 */
|
/* Set to indirect value prepared in v1 */
|
||||||
INST(FI_VAR_SET, 1, 0) {
|
INST(FI_VAR_SET, 1, 0) {
|
||||||
|
NEVER_CONSTANT;
|
||||||
ARG_ANY(1);
|
ARG_ANY(1);
|
||||||
SYMBOL;
|
SYMBOL;
|
||||||
|
|
||||||
if ((sym->class != (SYM_VARIABLE | v1.type)) && (v1.type != T_VOID))
|
if ((sym->class != (SYM_VARIABLE | v1.type)) && (v1.type != T_VOID))
|
||||||
{
|
{
|
||||||
/* IP->Quad implicit conversion */
|
/* IP->Quad implicit conversion */
|
||||||
@ -289,6 +304,7 @@
|
|||||||
|
|
||||||
INST(FI_VAR_GET, 0, 1) {
|
INST(FI_VAR_GET, 0, 1) {
|
||||||
SYMBOL;
|
SYMBOL;
|
||||||
|
NEVER_CONSTANT;
|
||||||
RESULT_VAL(fstk->vstk[curline.vbase + sym->offset]);
|
RESULT_VAL(fstk->vstk[curline.vbase + sym->offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,26 +313,27 @@
|
|||||||
FID_MEMBER(
|
FID_MEMBER(
|
||||||
struct f_val,
|
struct f_val,
|
||||||
val,
|
val,
|
||||||
val,
|
|
||||||
[[ !val_same(&(f1->val), &(f2->val)) ]],
|
[[ !val_same(&(f1->val), &(f2->val)) ]],
|
||||||
value %s,
|
value %s,
|
||||||
val_dump(&(item->val))
|
val_dump(&(item->val))
|
||||||
);
|
);
|
||||||
|
|
||||||
RESULT_VAL(whati->val);
|
RESULT_VAL(val);
|
||||||
}
|
}
|
||||||
INST(FI_PRINT, 1, 0) {
|
INST(FI_PRINT, 1, 0) {
|
||||||
|
NEVER_CONSTANT;
|
||||||
ARG_ANY(1);
|
ARG_ANY(1);
|
||||||
val_format(&(v1), &fs->buf);
|
val_format(&(v1), &fs->buf);
|
||||||
}
|
}
|
||||||
INST(FI_CONDITION, 1, 0) {
|
INST(FI_CONDITION, 1, 0) {
|
||||||
ARG(1, T_BOOL);
|
ARG(1, T_BOOL);
|
||||||
if (res.val.i)
|
if (v1.val.i)
|
||||||
LINE(2,0);
|
LINE(2,0);
|
||||||
else
|
else
|
||||||
LINE(3,1);
|
LINE(3,1);
|
||||||
}
|
}
|
||||||
INST(FI_PRINT_AND_DIE, 0, 0) {
|
INST(FI_PRINT_AND_DIE, 0, 0) {
|
||||||
|
NEVER_CONSTANT;
|
||||||
FID_LINEARIZE_BODY
|
FID_LINEARIZE_BODY
|
||||||
{
|
{
|
||||||
uint opos = pos;
|
uint opos = pos;
|
||||||
@ -330,7 +347,7 @@
|
|||||||
}
|
}
|
||||||
FID_ALL
|
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))) &&
|
if ((fret == F_NOP || (fret != F_NONL && (what->flags & FIF_PRINTED))) &&
|
||||||
!(fs->flags & FF_SILENT))
|
!(fs->flags & FF_SILENT))
|
||||||
@ -663,7 +680,7 @@
|
|||||||
runtime( "SADR expected" );
|
runtime( "SADR expected" );
|
||||||
|
|
||||||
net_addr_ip6_sadr *net = (void *) v1.val.net;
|
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);
|
net_fill_ip6(src, net->src_prefix, net->src_pxlen);
|
||||||
|
|
||||||
RESULT(T_NET, net, src);
|
RESULT(T_NET, net, src);
|
||||||
@ -721,6 +738,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
INST(FI_RETURN, 1, 1) {
|
INST(FI_RETURN, 1, 1) {
|
||||||
|
NEVER_CONSTANT;
|
||||||
/* Acquire the return value */
|
/* Acquire the return value */
|
||||||
ARG_ANY(1);
|
ARG_ANY(1);
|
||||||
uint retpos = fstk->vcnt;
|
uint retpos = fstk->vcnt;
|
||||||
@ -748,6 +766,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
INST(FI_CALL, 0, 1) {
|
INST(FI_CALL, 0, 1) {
|
||||||
|
NEVER_CONSTANT;
|
||||||
SYMBOL;
|
SYMBOL;
|
||||||
|
|
||||||
/* Push the body on stack */
|
/* Push the body on stack */
|
||||||
@ -768,13 +787,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
INST(FI_DROP_RESULT, 1, 0) {
|
INST(FI_DROP_RESULT, 1, 0) {
|
||||||
|
NEVER_CONSTANT;
|
||||||
ARG_ANY(1);
|
ARG_ANY(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
INST(FI_SWITCH, 1, 0) {
|
INST(FI_SWITCH, 1, 0) {
|
||||||
ARG_ANY(1);
|
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);
|
const struct f_tree *t = find_tree(tree, &v1);
|
||||||
if (!t) {
|
if (!t) {
|
||||||
@ -782,7 +802,7 @@
|
|||||||
t = find_tree(tree, &v1);
|
t = find_tree(tree, &v1);
|
||||||
if (!t) {
|
if (!t) {
|
||||||
debug( "No else statement?\n");
|
debug( "No else statement?\n");
|
||||||
break;
|
FID_HIC(,break,return NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* It is actually possible to have t->data NULL */
|
/* It is actually possible to have t->data NULL */
|
||||||
@ -801,7 +821,7 @@
|
|||||||
INST(FI_PATH_PREPEND, 2, 1) { /* Path prepend */
|
INST(FI_PATH_PREPEND, 2, 1) { /* Path prepend */
|
||||||
ARG(1, T_PATH);
|
ARG(1, T_PATH);
|
||||||
ARG(2, T_INT);
|
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 */
|
INST(FI_CLIST_ADD, 2, 1) { /* (Extended) Community list add */
|
||||||
@ -816,14 +836,14 @@
|
|||||||
struct f_val dummy;
|
struct f_val dummy;
|
||||||
|
|
||||||
if ((v2.type == T_PAIR) || (v2.type == T_QUAD))
|
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 */
|
/* IP->Quad implicit conversion */
|
||||||
else if (val_is_ip4(&v2))
|
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))
|
else if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy))
|
||||||
runtime("Can't add set");
|
runtime("Can't add set");
|
||||||
else if (v2.type == T_CLIST)
|
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
|
else
|
||||||
runtime("Can't add non-pair");
|
runtime("Can't add non-pair");
|
||||||
}
|
}
|
||||||
@ -834,11 +854,11 @@
|
|||||||
if ((v2.type == T_SET) && eclist_set_type(v2.val.t))
|
if ((v2.type == T_SET) && eclist_set_type(v2.val.t))
|
||||||
runtime("Can't add set");
|
runtime("Can't add set");
|
||||||
else if (v2.type == T_ECLIST)
|
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)
|
else if (v2.type != T_EC)
|
||||||
runtime("Can't add non-ec");
|
runtime("Can't add non-ec");
|
||||||
else
|
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)
|
else if (v1.type == T_LCLIST)
|
||||||
@ -847,11 +867,11 @@
|
|||||||
if ((v2.type == T_SET) && lclist_set_type(v2.val.t))
|
if ((v2.type == T_SET) && lclist_set_type(v2.val.t))
|
||||||
runtime("Can't add set");
|
runtime("Can't add set");
|
||||||
else if (v2.type == T_LCLIST)
|
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)
|
else if (v2.type != T_LC)
|
||||||
runtime("Can't add non-lc");
|
runtime("Can't add non-lc");
|
||||||
else
|
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
|
else
|
||||||
runtime("Can't delete non-integer (set)");
|
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)
|
else if (v1.type == T_CLIST)
|
||||||
@ -883,12 +903,12 @@
|
|||||||
struct f_val dummy;
|
struct f_val dummy;
|
||||||
|
|
||||||
if ((v2.type == T_PAIR) || (v2.type == T_QUAD))
|
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 */
|
/* IP->Quad implicit conversion */
|
||||||
else if (val_is_ip4(&v2))
|
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))
|
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
|
else
|
||||||
runtime("Can't delete non-pair");
|
runtime("Can't delete non-pair");
|
||||||
}
|
}
|
||||||
@ -897,22 +917,22 @@
|
|||||||
{
|
{
|
||||||
/* v2.val is either EC or EC-set */
|
/* v2.val is either EC or EC-set */
|
||||||
if ((v2.type == T_SET) && eclist_set_type(v2.val.t) || (v2.type == T_ECLIST))
|
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)
|
else if (v2.type != T_EC)
|
||||||
runtime("Can't delete non-ec");
|
runtime("Can't delete non-ec");
|
||||||
else
|
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)
|
else if (v1.type == T_LCLIST)
|
||||||
{
|
{
|
||||||
/* v2.val is either LC or LC-set */
|
/* v2.val is either LC or LC-set */
|
||||||
if ((v2.type == T_SET) && lclist_set_type(v2.val.t) || (v2.type == T_LCLIST))
|
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)
|
else if (v2.type != T_LC)
|
||||||
runtime("Can't delete non-lc");
|
runtime("Can't delete non-lc");
|
||||||
else
|
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
|
else
|
||||||
@ -927,7 +947,7 @@
|
|||||||
u32 key = 0;
|
u32 key = 0;
|
||||||
|
|
||||||
if ((v2.type == T_SET) && (v2.val.t->from.type == T_INT))
|
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
|
else
|
||||||
runtime("Can't filter integer");
|
runtime("Can't filter integer");
|
||||||
}
|
}
|
||||||
@ -938,7 +958,7 @@
|
|||||||
struct f_val dummy;
|
struct f_val dummy;
|
||||||
|
|
||||||
if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy) || (v2.type == T_CLIST))
|
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
|
else
|
||||||
runtime("Can't filter pair");
|
runtime("Can't filter pair");
|
||||||
}
|
}
|
||||||
@ -947,7 +967,7 @@
|
|||||||
{
|
{
|
||||||
/* v2.val is either EC or EC-set */
|
/* v2.val is either EC or EC-set */
|
||||||
if ((v2.type == T_SET) && eclist_set_type(v2.val.t) || (v2.type == T_ECLIST))
|
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
|
else
|
||||||
runtime("Can't filter ec");
|
runtime("Can't filter ec");
|
||||||
}
|
}
|
||||||
@ -956,7 +976,7 @@
|
|||||||
{
|
{
|
||||||
/* v2.val is either LC or LC-set */
|
/* v2.val is either LC or LC-set */
|
||||||
if ((v2.type == T_SET) && lclist_set_type(v2.val.t) || (v2.type == T_LCLIST))
|
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
|
else
|
||||||
runtime("Can't filter lc");
|
runtime("Can't filter lc");
|
||||||
}
|
}
|
||||||
@ -966,7 +986,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
INST(FI_ROA_CHECK_IMPLICIT, 0, 1) { /* ROA Check */
|
INST(FI_ROA_CHECK_IMPLICIT, 0, 1) { /* ROA Check */
|
||||||
|
NEVER_CONSTANT;
|
||||||
RTC(1);
|
RTC(1);
|
||||||
|
struct rtable *table = rtc->table;
|
||||||
ACCESS_RTE;
|
ACCESS_RTE;
|
||||||
ACCESS_EATTRS;
|
ACCESS_EATTRS;
|
||||||
const net_addr *net = (*fs->rte)->net->n.addr;
|
const net_addr *net = (*fs->rte)->net->n.addr;
|
||||||
@ -994,9 +1016,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
INST(FI_ROA_CHECK_EXPLICIT, 2, 1) { /* ROA Check */
|
INST(FI_ROA_CHECK_EXPLICIT, 2, 1) { /* ROA Check */
|
||||||
|
NEVER_CONSTANT;
|
||||||
ARG(1, T_NET);
|
ARG(1, T_NET);
|
||||||
ARG(2, T_INT);
|
ARG(2, T_INT);
|
||||||
RTC(3);
|
RTC(3);
|
||||||
|
struct rtable *table = rtc->table;
|
||||||
|
|
||||||
u32 as = v2.val.i;
|
u32 as = v2.val.i;
|
||||||
|
|
||||||
@ -1015,15 +1039,18 @@
|
|||||||
|
|
||||||
INST(FI_FORMAT, 1, 0) { /* Format */
|
INST(FI_FORMAT, 1, 0) { /* Format */
|
||||||
ARG_ANY(1);
|
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 */
|
INST(FI_ASSERT, 1, 0) { /* Birdtest Assert */
|
||||||
|
NEVER_CONSTANT;
|
||||||
ARG(1, T_BOOL);
|
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)
|
if (!bt_assert_hook)
|
||||||
runtime("No bt_assert hook registered, can't assert");
|
runtime("No bt_assert hook registered, can't assert");
|
||||||
|
|
||||||
bt_assert_hook(res.val.i, what);
|
bt_assert_hook(v1.val.i, what);
|
||||||
}
|
}
|
||||||
|
@ -150,14 +150,6 @@ f_rta_cow(struct filter_state *fs)
|
|||||||
f_cache_eattrs(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;
|
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; \
|
return F_ERROR; \
|
||||||
} while(0)
|
} 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_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)
|
#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 v2
|
||||||
#undef v3
|
#undef v3
|
||||||
#undef runtime
|
#undef runtime
|
||||||
|
#undef falloc
|
||||||
|
#undef fpool
|
||||||
#undef ACCESS_RTE
|
#undef ACCESS_RTE
|
||||||
#undef ACCESS_EATTRS
|
#undef ACCESS_EATTRS
|
||||||
}
|
}
|
||||||
|
@ -101,9 +101,13 @@ void buffer_realloc(void **buf, unsigned *size, unsigned need, unsigned item_siz
|
|||||||
*/
|
*/
|
||||||
#define DMALLOC_DISABLE
|
#define DMALLOC_DISABLE
|
||||||
#include <dmalloc.h>
|
#include <dmalloc.h>
|
||||||
#define xmalloc(size) _xmalloc_leap(__FILE__, __LINE__, size)
|
#define xmalloc(size) \
|
||||||
#define xrealloc(size) _xrealloc_leap(__FILE__, __LINE__, size)
|
dmalloc_malloc(__FILE__, __LINE__, (size), DMALLOC_FUNC_MALLOC, 0, 1)
|
||||||
#define xfree(ptr) _xfree_leap(__FILE__, __LINE__, ptr)
|
#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
|
#else
|
||||||
/*
|
/*
|
||||||
* Unfortunately, several libraries we might want to link to define
|
* Unfortunately, several libraries we might want to link to define
|
||||||
|
Loading…
Reference in New Issue
Block a user