diff --git a/configure.ac b/configure.ac index 33bc9101..850e771f 100644 --- a/configure.ac +++ b/configure.ac @@ -18,6 +18,12 @@ AC_ARG_ENABLE([debug], [enable_debug=no] ) +AC_ARG_ENABLE([debug-generated], + [AS_HELP_STRING([--enable-debug-generated], [enable this to abstain from generating #line @<:@no@:>@])], + [], + [enable_debug_generated=no] +) + AC_ARG_ENABLE([memcheck], [AS_HELP_STRING([--enable-memcheck], [check memory allocations when debugging @<:@yes@:>@])], [], @@ -156,7 +162,7 @@ test -z "$M4" && AC_MSG_ERROR([M4 is missing.]) AC_MSG_CHECKING([bison version]) BIRD_CHECK_BISON_VERSION(BISON_VERSION) AC_MSG_RESULT([$BISON_VERSION]) -if test "$bird_bison_synclines" = yes; then +if test "$bird_bison_synclines" = yes && test "$enable_debug_generated" = no; then M4FLAGS="$M4FLAGS -s" fi diff --git a/filter/Makefile b/filter/Makefile index 15f2c3d0..f5f50045 100644 --- a/filter/Makefile +++ b/filter/Makefile @@ -1,13 +1,10 @@ -src := filter.c f-util.c tree.c trie.c f-inst-new.c +src := filter.c f-util.c tree.c trie.c obj := $(src-o-files) $(all-daemon) $(cf-local) M4FLAGS_FILTERS=$(filter-out -s,$(M4FLAGS)) -$(o)f-inst-line-size.c: $(s)line-size.m4 $(s)f-inst.c $(objdir)/.dir-stamp - $(M4) $(M4FLAGS_FILTERS) -P $^ >$@ - $(o)f-inst-postfixify.c: $(s)postfixify.m4 $(s)f-inst.c $(objdir)/.dir-stamp $(M4) $(M4FLAGS_FILTERS) -P $^ >$@ @@ -17,16 +14,13 @@ $(o)f-inst-interpret.c: $(s)interpret.m4 $(s)f-inst.c $(objdir)/.dir-stamp $(o)f-inst-same.c: $(s)same.m4 $(s)f-inst.c $(objdir)/.dir-stamp $(M4) $(M4FLAGS_FILTERS) -P $^ >$@ -$(o)f-inst-struct.h: $(s)struct.m4 $(s)f-inst.c $(objdir)/.dir-stamp - $(M4) $(M4FLAGS_FILTERS) -P $^ >$@ - -$(o)f-inst-new.c: $(s)new.m4 $(s)f-inst.c $(objdir)/.dir-stamp +$(o)f-inst-decl.h: $(s)decl.m4 $(s)f-inst.c $(objdir)/.dir-stamp $(M4) $(M4FLAGS_FILTERS) -P $^ >$@ $(o)f-inst-dump.c: $(s)dump.m4 $(s)f-inst.c $(objdir)/.dir-stamp $(M4) $(M4FLAGS_FILTERS) -P $^ >$@ -$(o)filter.o: $(o)f-inst-interpret.c $(o)f-inst-line-size.c $(o)f-inst-postfixify.c $(o)f-inst-same.c $(o)f-inst-dump.c $(o)f-inst-struct.h +$(o)filter.o: $(o)f-inst-interpret.c $(o)f-inst-postfixify.c $(o)f-inst-same.c $(o)f-inst-dump.c $(o)f-inst-decl.h tests_src := tree_test.c filter_test.c trie_test.c tests_targets := $(tests_targets) $(tests-target-files) diff --git a/filter/config.Y b/filter/config.Y index 31ceb3f5..42624f44 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -11,7 +11,7 @@ CF_HDR #include "filter/f-inst.h" -#include "filter/f-util.h" +#include "filter/data.h" CF_DEFINES @@ -418,7 +418,7 @@ assert_assign(struct f_lval *lval, struct f_inst *expr, const char *start, const } checker = f_new_inst(FI_EQ, expr, getter); - f_inst_next(setter, checker); + setter->next = checker; return assert_done(setter, start, end); } @@ -550,7 +550,7 @@ one_decl: decls: /* EMPTY */ { $$ = NULL; } | one_decl ';' decls { $$ = $1; - f_inst_next($$, $3); + $$->next = $3; } ; @@ -559,7 +559,7 @@ declsn: one_decl { $$.inst = $1; $$.count = 1; } | one_decl ';' declsn { $$ = $3; $$.count++; - f_inst_next($$.inst, $1); + $$.inst->next = $1; } ; @@ -640,7 +640,7 @@ cmds: /* EMPTY */ { $$ = NULL; } ; cmds_int: cmd { $$[0] = $$[1] = $1; } - | cmds_int cmd { $$[1] = $2; f_inst_next($1[1], $2); $$[0] = $1[0]; } + | cmds_int cmd { $$[1] = $2; $1[1]->next = $2; $$[0] = $1[0]; } ; block: @@ -803,11 +803,11 @@ bgp_path: ; bgp_path_tail: - NUM bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .asn = $1, .kind = PM_ASN, }, }); f_inst_next($$, $2); } - | NUM DDOT NUM bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .from = $1, .to = $3, .kind = PM_ASN_RANGE }, }); f_inst_next($$, $4); } - | '*' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_ASTERISK }, }); f_inst_next($$, $2); } - | '?' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_QUESTION }, }); f_inst_next($$, $2); } - | bgp_path_expr bgp_path_tail { $$ = $1; f_inst_next($$, $2); } + NUM bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .asn = $1, .kind = PM_ASN, }, }); $$->next = $2; } + | NUM DDOT NUM bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .from = $1, .to = $3, .kind = PM_ASN_RANGE }, }); $$->next = $4; } + | '*' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_ASTERISK }, }); $$->next = $2; } + | '?' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_QUESTION }, }); $$->next = $2; } + | bgp_path_expr bgp_path_tail { $$ = $1; $$->next = $2; } | { $$ = NULL; } ; @@ -946,7 +946,7 @@ print_list: /* EMPTY */ { $$ = NULL; } | print_one { $$ = $1; } | print_one ',' print_list { if ($1) { - f_inst_next($1, $3); + $1->next = $3; $$ = $1; } else $$ = $3; } @@ -957,7 +957,7 @@ var_listn: term { } | term ',' var_listn { $$ = $1; - f_inst_next($$, $3); + $$->next = $3; } ; diff --git a/filter/f-util.h b/filter/data.h similarity index 89% rename from filter/f-util.h rename to filter/data.h index a7d77bbd..58db3e44 100644 --- a/filter/f-util.h +++ b/filter/data.h @@ -1,5 +1,5 @@ /* - * BIRD Internet Routing Daemon -- Filter utils + * BIRD Internet Routing Daemon -- Dynamic data structures * * (c) 1999 Pavel Machek * (c) 2018--2019 Maria Matejka @@ -7,14 +7,10 @@ * Can be freely distributed and used under the terms of the GNU GPL. */ -#ifndef _BIRD_F_UTIL_H_ -#define _BIRD_F_UTIL_H_ +#ifndef _BIRD_FILTER_DATA_H_ +#define _BIRD_FILTER_DATA_H_ -/* IP prefix range structure */ -struct f_prefix { - net_addr net; /* The matching prefix must match this net */ - u8 lo, hi; /* And its length must fit between lo and hi */ -}; +#include "nest/bird.h" /* Type numbers must be in 0..0xff range */ #define T_MASK 0xff @@ -84,8 +80,6 @@ struct f_val { } val; }; -#define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val)); - /* Dynamic attribute definition (eattrs) */ struct f_dynamic_attr { u8 type; /* EA type (EAF_*) */ @@ -113,6 +107,30 @@ struct f_static_attr { int readonly:1; /* Don't allow writing */ }; +/* Filter l-value type */ +enum f_lval_type { + F_LVAL_VARIABLE, + F_LVAL_PREFERENCE, + F_LVAL_SA, + F_LVAL_EA, +}; + +/* Filter l-value */ +struct f_lval { + enum f_lval_type type; + union { + const struct symbol *sym; + struct f_dynamic_attr da; + struct f_static_attr sa; + }; +}; + +/* IP prefix range structure */ +struct f_prefix { + net_addr net; /* The matching prefix must match this net */ + u8 lo, hi; /* And its length must fit between lo and hi */ +}; + struct f_tree { struct f_tree *left, *right; struct f_val from, to; diff --git a/filter/decl.m4 b/filter/decl.m4 new file mode 100644 index 00000000..bdbb3e27 --- /dev/null +++ b/filter/decl.m4 @@ -0,0 +1,128 @@ +m4_divert(-1)m4_dnl +# +# BIRD -- Construction of per-instruction structures +# +# (c) 2018 Maria Matejka +# +# Can be freely distributed and used under the terms of the GNU GPL. +# +# +# Global Diversions: +# 4 enum fi_code +# 1 struct f_inst_FI_... +# 2 union in struct f_inst +# 3 constructors +# +# Per-inst Diversions: +# 11 content of struct f_inst_FI_... +# 12 constructor arguments +# 13 constructor body + +# Flush the completed instruction + +m4_define(FID_END, `m4_divert(-1)') + +m4_define(FID_ZONE, `m4_divert($1) /* $2 for INST_NAME() */') +m4_define(FID_STRUCT, `FID_ZONE(1, Per-instruction structure)') +m4_define(FID_UNION, `FID_ZONE(2, Union member)') +m4_define(FID_NEW, `FID_ZONE(3, Constructor)') +m4_define(FID_ENUM, `FID_ZONE(4, Code enum)') + +m4_define(FID_STRUCT_IN, `m4_divert(101)') +m4_define(FID_NEW_ARGS, `m4_divert(102)') +m4_define(FID_NEW_BODY, `m4_divert(103)') + +m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[ +FID_ENUM +INST_NAME(), +FID_STRUCT +struct f_inst_[[]]INST_NAME() { +m4_undivert(101) +}; +FID_UNION +struct f_inst_[[]]INST_NAME() i_[[]]INST_NAME(); +FID_NEW +static inline struct f_inst *f_new_inst_]]INST_NAME()[[(enum f_instruction_code fi_code +m4_undivert(102) +) { + struct f_inst *what_ = cfg_allocz(sizeof(struct f_inst)); + what_->fi_code = fi_code; + what_->lineno = ifs->lino; + what_->size = 1; + struct f_inst_[[]]INST_NAME() *what UNUSED = &(what_->i_[[]]INST_NAME()); +m4_undivert(103) + return what_; +} +FID_END +]])') + +m4_define(INST, `INST_FLUSH()m4_define([[INST_NAME]], [[$1]])') + +m4_define(FID_MEMBER, `m4_dnl +FID_STRUCT_IN +$1 $2; +FID_NEW_ARGS +, $1 $2 +FID_NEW_BODY +what->$2 = $2; +FID_END') + +m4_define(ARG, `FID_MEMBER(const struct f_inst *, f$1) +FID_NEW_BODY +for (const struct f_inst *child = f$1; child; child = child->next) what_->size += child->size; +FID_END') +m4_define(ARG_ANY, `FID_MEMBER(const struct f_inst *, f$1) +FID_NEW_BODY +for (const struct f_inst *child = f$1; child; child = child->next) what_->size += child->size; +FID_END') +m4_define(LINE, `FID_MEMBER(const struct f_inst *, f$1)') +m4_define(LINEP, `FID_STRUCT_IN +const struct f_line *fl$1; +FID_END') +m4_define(SYMBOL, `FID_MEMBER(const struct symbol *, sym)') +m4_define(VALI, `FID_MEMBER(struct f_val, vali)') +m4_define(VALP, `FID_MEMBER(const struct f_val *, valp)') +m4_define(VAR, `m4_dnl +FID_STRUCT_IN +const struct f_val *valp; +const struct symbol *sym; +FID_NEW_ARGS +, const struct symbol *sym +FID_NEW_BODY +what->valp = (what->sym = sym)->def; +FID_END') +m4_define(FRET, `FID_MEMBER(enum filter_return, fret)') +m4_define(ECS, `FID_MEMBER(enum ec_subtype, ecs)') +m4_define(RTC, `FID_MEMBER(const struct rtable_config *, rtc)') +m4_define(STATIC_ATTR, `FID_MEMBER(struct f_static_attr, sa)') +m4_define(DYNAMIC_ATTR, `FID_MEMBER(struct f_dynamic_attr, da)') +m4_define(COUNT, `FID_MEMBER(uint, count)') +m4_define(TREE, `FID_MEMBER(const struct f_tree *, tree)') +m4_define(STRING, `FID_MEMBER(const char *, s)') + +m4_m4wrap(` +INST_FLUSH() +m4_divert(0) +/* Filter instruction codes */ +enum f_instruction_code { +m4_undivert(4) +}; + +/* Per-instruction structures */ +m4_undivert(1) + +struct f_inst { + const struct f_inst *next; /* Next instruction */ + enum f_instruction_code fi_code; /* Instruction code */ + int size; /* How many instructions are underneath */ + int lineno; /* Line number */ + union { + m4_undivert(2) + }; +}; + +/* Instruction constructors */ +m4_undivert(3) +') + +m4_changequote([[,]]) diff --git a/filter/f-inst.c b/filter/f-inst.c index 0dd9f9f6..afb895c5 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -109,15 +109,15 @@ ARG_ANY(1); COUNT(2); - NEW(, [[ - 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++; + 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++; - WHAT().count = len; - ]]); + what->count = len; + FID_END if (vstk.cnt < what->count) /* TODO: make this check systematic */ runtime("Construction of BGP path mask from %u elements must have at least that number of elements", what->count); @@ -719,17 +719,17 @@ /* Then push the arguments */ LINE(1,1); - NEW(, [[ - if (sym->class != SYM_FUNCTION) - cf_error("You can't call something which is not a function. Really."); + FID_NEW_BODY + if (sym->class != SYM_FUNCTION) + cf_error("You can't call something which is not a function. Really."); - uint count = 0; - for (const struct f_inst *inst = f1; inst; inst = inst->next) - count++; - - if (count != sym->aux2) - cf_error("Function %s takes %u arguments, got %u.", sym->name, sym->aux2, count); - ]]); + uint count = 0; + for (const struct f_inst *inst = f1; inst; inst = inst->next) + count++; + + if (count != sym->aux2) + cf_error("Function %s takes %u arguments, got %u.", sym->name, sym->aux2, count); + FID_END } INST(FI_DROP_RESULT, 1, 0) { diff --git a/filter/f-inst.h b/filter/f-inst.h index 63124aa1..1423e685 100644 --- a/filter/f-inst.h +++ b/filter/f-inst.h @@ -10,137 +10,21 @@ #ifndef _BIRD_F_INST_H_ #define _BIRD_F_INST_H_ +#include "nest/bird.h" +#include "conf/conf.h" #include "filter/filter.h" -#include "filter/f-util.h" +#include "filter/data.h" -/* Filter l-value type */ -enum f_lval_type { - F_LVAL_VARIABLE, - F_LVAL_PREFERENCE, - F_LVAL_SA, - F_LVAL_EA, -}; +/* Include generated filter instruction declarations */ +#include "filter/f-inst-decl.h" -/* Filter l-value */ -struct f_lval { - enum f_lval_type type; - union { - const struct symbol *sym; - struct f_dynamic_attr da; - struct f_static_attr sa; - }; -}; - -/* Filter instruction declarations */ -#define FI__LIST \ - F(FI_NOP) \ - F(FI_ADD, ARG, ARG) \ - F(FI_SUBTRACT, ARG, ARG) \ - F(FI_MULTIPLY, ARG, ARG) \ - F(FI_DIVIDE, ARG, ARG) \ - F(FI_AND, ARG, LINE) \ - F(FI_OR, ARG, LINE) \ - F(FI_PAIR_CONSTRUCT, ARG, ARG) \ - F(FI_EC_CONSTRUCT, ARG, ARG, ECS) \ - F(FI_LC_CONSTRUCT, ARG, ARG, ARG) \ - F(FI_PATHMASK_CONSTRUCT, ARG, COUNT) \ - F(FI_NEQ, ARG, ARG) \ - F(FI_EQ, ARG, ARG) \ - F(FI_LT, ARG, ARG) \ - F(FI_LTE, ARG, ARG) \ - F(FI_NOT, ARG) \ - F(FI_MATCH, ARG, ARG) \ - F(FI_NOT_MATCH, ARG, ARG) \ - F(FI_DEFINED, ARG) \ - F(FI_TYPE, ARG) \ - F(FI_IS_V4, ARG) \ - F(FI_SET, ARG, SYMBOL) \ - F(FI_CONSTANT, VALI) \ - F(FI_VARIABLE, SYMBOL) \ - F(FI_CONSTANT_INDIRECT, VALP) \ - F(FI_PRINT, ARG) \ - F(FI_CONDITION, ARG, LINE, LINE) \ - F(FI_PRINT_AND_DIE, ARG, FRET) \ - F(FI_RTA_GET, SA) \ - F(FI_RTA_SET, ARG, SA) \ - F(FI_EA_GET, EA) \ - F(FI_EA_SET, ARG, EA) \ - F(FI_EA_UNSET, EA) \ - F(FI_PREF_GET) \ - F(FI_PREF_SET, ARG) \ - F(FI_LENGTH, ARG) \ - F(FI_ROA_MAXLEN, ARG) \ - F(FI_ROA_ASN, ARG) \ - F(FI_SADR_SRC, ARG) \ - F(FI_IP, ARG) \ - F(FI_ROUTE_DISTINGUISHER, ARG) \ - F(FI_AS_PATH_FIRST, ARG) \ - F(FI_AS_PATH_LAST, ARG) \ - F(FI_AS_PATH_LAST_NAG, ARG) \ - F(FI_RETURN, ARG) \ - F(FI_CALL, SYMBOL, LINE) \ - F(FI_DROP_RESULT, ARG) \ - F(FI_SWITCH, ARG, TREE) \ - F(FI_IP_MASK, ARG, ARG) \ - F(FI_PATH_PREPEND, ARG, ARG) \ - F(FI_CLIST_ADD, ARG, ARG) \ - F(FI_CLIST_DEL, ARG, ARG) \ - F(FI_CLIST_FILTER, ARG, ARG) \ - F(FI_ROA_CHECK_IMPLICIT, RTC) \ - F(FI_ROA_CHECK_EXPLICIT, ARG, ARG, RTC) \ - F(FI_FORMAT, ARG) \ - F(FI_ASSERT, ARG, STRING) - -/* The enum itself */ -enum f_instruction_code { -#define F(c, ...) c, -FI__LIST -#undef F - FI__MAX, -} PACKED; +#define f_new_inst(...) MACRO_CONCAT_AFTER(f_new_inst_, MACRO_FIRST(__VA_ARGS__))(__VA_ARGS__) /* Convert the instruction back to the enum name */ const char *f_instruction_name(enum f_instruction_code fi); -struct f_inst; -void f_inst_next(struct f_inst *first, const struct f_inst *append); struct f_inst *f_clear_local_vars(struct f_inst *decls); -#define FIA(x) , FIA_##x -#define FIA_ARG const struct f_inst * -#define FIA_LINE const struct f_inst * -#define FIA_COUNT uint -#define FIA_SYMBOL const struct symbol * -#define FIA_VALI struct f_val -#define FIA_VALP const struct f_val * -#define FIA_FRET enum filter_return -#define FIA_ECS enum ec_subtype -#define FIA_SA struct f_static_attr -#define FIA_EA struct f_dynamic_attr -#define FIA_RTC const struct rtable_config * -#define FIA_TREE const struct f_tree * -#define FIA_STRING const char * -#define F(c, ...) \ - struct f_inst *f_new_inst_##c(enum f_instruction_code MACRO_IFELSE(MACRO_ISLAST(__VA_ARGS__))()(MACRO_FOREACH(FIA, __VA_ARGS__))); -FI__LIST -#undef F -#undef FIA_ARG -#undef FIA_LINE -#undef FIA_LINEP -#undef FIA_COUNT -#undef FIA_SYMBOL -#undef FIA_VALI -#undef FIA_VALP -#undef FIA_FRET -#undef FIA_ECS -#undef FIA_SA -#undef FIA_EA -#undef FIA_RTC -#undef FIA_STRING -#undef FIA - -#define f_new_inst(...) MACRO_CONCAT_AFTER(f_new_inst_, MACRO_FIRST(__VA_ARGS__))(__VA_ARGS__) - /* Flags for instructions */ enum f_instruction_flags { FIF_PRINTED = 1, /* FI_PRINT_AND_DIE: message put in buffer */ @@ -202,7 +86,4 @@ struct f_bt_test_suite { const char *dsc; /* Description */ }; -/* Include the auto-generated structures */ -#include "filter/f-inst-struct.h" - #endif diff --git a/filter/f-util.c b/filter/f-util.c index eb948fa0..82aaa385 100644 --- a/filter/f-util.c +++ b/filter/f-util.c @@ -17,22 +17,6 @@ #define P(a,b) ((a<<8) | b) -static const char * const f_instruction_name_str[] = { -#define F(c,...) \ - [c] = #c, -FI__LIST -#undef F -}; - -const char * -f_instruction_name(enum f_instruction_code fi) -{ - if (fi < FI__MAX) - return f_instruction_name_str[fi]; - else - bug("Got unknown instruction code: %d", fi); -} - char * filter_name(struct filter *filter) { @@ -56,18 +40,21 @@ struct filter *f_new_where(const struct f_inst *where) struct f_inst acc = { .fi_code = FI_PRINT_AND_DIE, .lineno = ifs->lino, + .size = 1, .i_FI_PRINT_AND_DIE = { .fret = F_ACCEPT, }, }; struct f_inst rej = { .fi_code = FI_PRINT_AND_DIE, .lineno = ifs->lino, + .size = 1, .i_FI_PRINT_AND_DIE = { .fret = F_REJECT, }, }; struct f_inst i = { .fi_code = FI_CONDITION, .lineno = ifs->lino, + .size = 3, .i_FI_CONDITION = { .f1 = where, .f2 = &acc, diff --git a/filter/filter.c b/filter/filter.c index ff702f2b..0cb56fe4 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -48,7 +48,7 @@ #include "conf/conf.h" #include "filter/filter.h" #include "filter/f-inst.h" -#include "filter/f-util.h" +#include "filter/data.h" #define CMP_ERROR 999 @@ -64,6 +64,75 @@ struct filter_state { void (*bt_assert_hook)(int result, const struct f_line_item *assert); +static const char * const f_instruction_name_str[] = { + /* TODO: Make this better */ + [FI_ADD] = "FI_ADD", + [FI_SUBTRACT] = "FI_SUBTRACT", + [FI_MULTIPLY] = "FI_MULTIPLY", + [FI_DIVIDE] = "FI_DIVIDE", + [FI_AND] = "FI_AND", + [FI_OR] = "FI_OR", + [FI_PAIR_CONSTRUCT] = "FI_PAIR_CONSTRUCT", + [FI_EC_CONSTRUCT] = "FI_EC_CONSTRUCT", + [FI_LC_CONSTRUCT] = "FI_LC_CONSTRUCT", + [FI_PATHMASK_CONSTRUCT] = "FI_PATHMASK_CONSTRUCT", + [FI_NEQ] = "FI_NEQ", + [FI_EQ] = "FI_EQ", + [FI_LT] = "FI_LT", + [FI_LTE] = "FI_LTE", + [FI_NOT] = "FI_NOT", + [FI_MATCH] = "FI_MATCH", + [FI_NOT_MATCH] = "FI_NOT_MATCH", + [FI_DEFINED] = "FI_DEFINED", + [FI_TYPE] = "FI_TYPE", + [FI_IS_V4] = "FI_IS_V4", + [FI_SET] = "FI_SET", + [FI_CONSTANT] = "FI_CONSTANT", + [FI_VARIABLE] = "FI_VARIABLE", + [FI_CONSTANT_INDIRECT] = "FI_CONSTANT_INDIRECT", + [FI_PRINT] = "FI_PRINT", + [FI_CONDITION] = "FI_CONDITION", + [FI_PRINT_AND_DIE] = "FI_PRINT_AND_DIE", + [FI_RTA_GET] = "FI_RTA_GET", + [FI_RTA_SET] = "FI_RTA_SET", + [FI_EA_GET] = "FI_EA_GET", + [FI_EA_SET] = "FI_EA_SET", + [FI_EA_UNSET] = "FI_EA_UNSET", + [FI_PREF_GET] = "FI_PREF_GET", + [FI_PREF_SET] = "FI_PREF_SET", + [FI_LENGTH] = "FI_LENGTH", + [FI_SADR_SRC] = "FI_SADR_SRC", + [FI_ROA_MAXLEN] = "FI_ROA_MAXLEN", + [FI_ROA_ASN] = "FI_ROA_ASN", + [FI_IP] = "FI_IP", + [FI_ROUTE_DISTINGUISHER] = "FI_ROUTE_DISTINGUISHER", + [FI_AS_PATH_FIRST] = "FI_AS_PATH_FIRST", + [FI_AS_PATH_LAST] = "FI_AS_PATH_LAST", + [FI_AS_PATH_LAST_NAG] = "FI_AS_PATH_LAST_NAG", + [FI_RETURN] = "FI_RETURN", + [FI_CALL] = "FI_CALL", + [FI_DROP_RESULT] = "FI_DROP_RESULT", + [FI_SWITCH] = "FI_SWITCH", + [FI_IP_MASK] = "FI_IP_MASK", + [FI_PATH_PREPEND] = "FI_PATH_PREPEND", + [FI_CLIST_ADD] = "FI_CLIST_ADD", + [FI_CLIST_DEL] = "FI_CLIST_DEL", + [FI_CLIST_FILTER] = "FI_CLIST_FILTER", + [FI_ROA_CHECK_IMPLICIT] = "FI_ROA_CHECK_IMPLICIT", + [FI_ROA_CHECK_EXPLICIT] = "FI_ROA_CHECK_EXPLICIT", + [FI_FORMAT] = "FI_FORMAT", + [FI_ASSERT] = "FI_ASSERT", +}; + +const char * +f_instruction_name(enum f_instruction_code fi) +{ + if (fi < (sizeof(f_instruction_name_str) / sizeof(f_instruction_name_str[0]))) + return f_instruction_name_str[fi]; + else + bug("Got unknown instruction code: %d", fi); +} + /* Special undef value for paths and clists */ static inline int undef_value(struct f_val v) @@ -615,18 +684,6 @@ val_format_str(struct filter_state *fs, struct f_val *v) { static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS; -static uint -inst_line_size(const struct f_inst *what_) -{ - uint cnt = 0; - for ( ; what_; what_ = what_->next) { - switch (what_->fi_code) { -#include "filter/f-inst-line-size.c" - } - } - return cnt; -} - #define INDENT (((const char *) f_dump_line_indent_str) + sizeof(f_dump_line_indent_str) - (indent) - 1) static const char f_dump_line_indent_str[] = " "; @@ -685,7 +742,8 @@ f_postfixify_concat(const struct f_inst * const inst[], uint count) { uint len = 0; for (uint i=0; inext) + len += what->size; struct f_line *out = cfg_allocz(sizeof(struct f_line) + sizeof(struct f_line_item)*len); diff --git a/filter/filter_test.c b/filter/filter_test.c index a02f0832..edd73ac8 100644 --- a/filter/filter_test.c +++ b/filter/filter_test.c @@ -17,7 +17,7 @@ #include "test/bt-utils.h" #include "filter/filter.h" -#include "filter/f-util.h" +#include "filter/data.h" #include "filter/f-inst.h" #include "conf/conf.h" diff --git a/filter/interpret.m4 b/filter/interpret.m4 index dfd5c6a7..e32b3a76 100644 --- a/filter/interpret.m4 +++ b/filter/interpret.m4 @@ -63,10 +63,11 @@ m4_define(TREE, `') m4_define(STRING, `') m4_define(COUNT, `') m4_define(POSTFIXIFY, `') -m4_define(LINE_SIZE, `') m4_define(SAME, `') -m4_define(STRUCT, `') -m4_define(NEW, `') +m4_define(FID_STRUCT_IN, `m4_divert(-1)') +m4_define(FID_NEW_ARGS, `m4_divert(-1)') +m4_define(FID_NEW_BODY, `m4_divert(-1)') +m4_define(FID_END, `m4_divert(2)') m4_m4wrap(` INST_FLUSH() diff --git a/filter/line-size.m4 b/filter/line-size.m4 deleted file mode 100644 index 051d3b90..00000000 --- a/filter/line-size.m4 +++ /dev/null @@ -1,41 +0,0 @@ -m4_divert(-1)m4_dnl -# -# BIRD -- Line size counting -# -# (c) 2018 Maria Matejka -# -# Can be freely distributed and used under the terms of the GNU GPL. -# - -# Common aliases -m4_define(DNL, `m4_dnl') - -m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[ -m4_divert(1) -case INST_NAME(): -cnt += 1; -#define what ((const struct f_inst_]]INST_NAME()[[ *) &(what_->i_]]INST_NAME()[[)) -m4_undivert(2) -#undef what -break; -m4_divert(-1) -]])') -m4_define(INST, `INST_FLUSH()m4_define([[INST_NAME]], [[$1]])') - -m4_define(ARG, `m4_divert(2)cnt += inst_line_size(what->f$1); -m4_divert(-1)') -m4_define(ARG_T, `m4_divert(2)cnt += inst_line_size(what->f$1); -m4_divert(-1)') -m4_define(ARG_ANY, `m4_divert(2)cnt += inst_line_size(what->f$1); -m4_divert(-1)') -m4_define(LINE_SIZE, `m4_divert(2)$1m4_divert(-1)') - -m4_m4wrap(` -INST_FLUSH() -m4_divert(0)DNL -m4_undivert(1) - -default: bug( "Unknown instruction %d (%c)", what_->fi_code, what_->fi_code & 0xff); -') - -m4_changequote([[,]]) diff --git a/filter/new.m4 b/filter/new.m4 deleted file mode 100644 index 38295e5c..00000000 --- a/filter/new.m4 +++ /dev/null @@ -1,78 +0,0 @@ -m4_divert(-1)m4_dnl -# -# BIRD -- Construction of per-instruction structures -# -# (c) 2018 Maria Matejka -# -# Can be freely distributed and used under the terms of the GNU GPL. -# -# -# Diversions: -# 1 for prepared output -# 2 for function arguments -# 3 for function body - -# Common aliases -m4_define(DNL, `m4_dnl') - -m4_define(FNSTOP, `m4_divert(-1)') -m4_define(FNOUT, `m4_divert(1)') -m4_define(FNARG, `m4_divert(2)') -m4_define(FNBODY, `m4_divert(3)') - -m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[ -FNOUT()DNL -struct f_inst *f_new_inst_]]INST_NAME()[[(enum f_instruction_code fi_code -m4_undivert(2) -) { - struct f_inst *what = cfg_allocz(sizeof(struct f_inst)); - what->fi_code = fi_code; - what->lineno = ifs->lino; -m4_undivert(3) - return what; -} -FNSTOP() -]]DNL -)') - -m4_define(INST, `INST_FLUSH()m4_define([[INST_NAME]], [[$1]])') - -m4_define(WHAT, `what->i_[[]]INST_NAME()') - -m4_define(FNMETAARG, `FNARG(), $1 $2 -FNBODY() WHAT().$2 = $2; -FNSTOP()') -m4_define(ARG, `FNMETAARG(const struct f_inst *, f$1)') -m4_define(ARG_ANY, `FNMETAARG(const struct f_inst *, f$1)') -m4_define(LINE, `FNMETAARG(const struct f_inst *, f$1)') -m4_define(SYMBOL, `FNMETAARG(const struct symbol *, sym)') -m4_define(VALI, `FNMETAARG(struct f_val, vali)') -m4_define(VALP, `FNMETAARG(const struct f_val *, valp)') -m4_define(VAR, `FNARG(), const struct symbol * sym -FNBODY() WHAT().valp = (WHAT().sym = sym)->def; -FNSTOP()') -m4_define(FRET, `FNMETAARG(enum filter_return, fret)') -m4_define(ECS, `FNMETAARG(enum ec_subtype, ecs)') -m4_define(RTC, `FNMETAARG(const struct rtable_config *, rtc)') -m4_define(STATIC_ATTR, `FNMETAARG(struct f_static_attr, sa)') -m4_define(DYNAMIC_ATTR, `FNMETAARG(struct f_dynamic_attr, da)') -m4_define(COUNT, `FNMETAARG(uint, count)') -m4_define(TREE, `FNMETAARG(const struct f_tree *, tree)') -m4_define(STRING, `FNMETAARG(const char *, s)') -m4_define(NEW, `FNARG()$1 -FNBODY()$2 -FNSTOP()') - -m4_m4wrap(` -INST_FLUSH() -m4_divert(0) -#include "nest/bird.h" -#include "conf/conf.h" -#include "filter/filter.h" -#include "filter/f-inst.h" - -m4_undivert(1) - -') - -m4_changequote([[,]]) diff --git a/filter/struct.m4 b/filter/struct.m4 deleted file mode 100644 index 7af28cfd..00000000 --- a/filter/struct.m4 +++ /dev/null @@ -1,73 +0,0 @@ -m4_divert(-1)m4_dnl -# -# BIRD -- Definition of per-instruction structures -# -# (c) 2018 Maria Matejka -# -# Can be freely distributed and used under the terms of the GNU GPL. -# - -# Common aliases -m4_define(DNL, `m4_dnl') - -m4_define(INST_FLUSH, `m4_ifdef([[INST_NAME]], [[ -m4_divert(1) -struct f_inst_[[]]INST_NAME() { -m4_undivert(2) -}; -m4_divert(3) -struct f_inst_[[]]INST_NAME() i_[[]]INST_NAME(); -m4_divert(-1) -]])') -m4_define(INST, `INST_FLUSH()m4_define([[INST_NAME]], [[$1]])') - -m4_define(ARG, `m4_divert(2)const struct f_inst *f$1; -m4_divert(-1)') -m4_define(ARG_ANY, `m4_divert(2)const struct f_inst *f$1; -m4_divert(-1)') -m4_define(LINE, `m4_divert(2)const struct f_inst *f$1; -m4_divert(-1)') -m4_define(LINEP, `m4_divert(2)const struct f_line *fl$1; -m4_divert(-1)') -m4_define(SYMBOL, `m4_divert(2)const struct symbol *sym; -m4_divert(-1)') -m4_define(VALI, `m4_divert(2)struct f_val vali; -m4_divert(-1)') -m4_define(VALP, `m4_divert(2)const struct f_val *valp; -m4_divert(-1)') -m4_define(VAR, `VALP()SYMBOL()') -m4_define(FRET, `m4_divert(2)enum filter_return fret; -m4_divert(-1)') -m4_define(ECS, `m4_divert(2)enum ec_subtype ecs; -m4_divert(-1)') -m4_define(RTC, `m4_divert(2)const struct rtable_config *rtc; -m4_divert(-1)') -m4_define(STATIC_ATTR, `m4_divert(2)struct f_static_attr sa; -m4_divert(-1)') -m4_define(DYNAMIC_ATTR, `m4_divert(2)struct f_dynamic_attr da; -m4_divert(-1)') -m4_define(COUNT, `m4_divert(2)uint count; -m4_divert(-1)') -m4_define(TREE, `m4_divert(2)const struct f_tree *tree; -m4_divert(-1)') -m4_define(STRING, `m4_divert(2)const char *s; -m4_divert(-1)') -m4_define(STRUCT, `m4_divert(2)$1 -m4_divert(-1)') - -m4_m4wrap(` -INST_FLUSH() -m4_divert(0)DNL -m4_undivert(1) - -struct f_inst { - const struct f_inst *next; /* Next instruction */ - enum f_instruction_code fi_code; /* Instruction code */ - int lineno; /* Line number */ - union { - m4_undivert(3) - }; -}; -') - -m4_changequote([[,]]) diff --git a/filter/tree.c b/filter/tree.c index 879b0859..46d6e529 100644 --- a/filter/tree.c +++ b/filter/tree.c @@ -10,7 +10,7 @@ #include "nest/bird.h" #include "conf/conf.h" #include "filter/filter.h" -#include "filter/f-util.h" +#include "filter/data.h" /** * find_tree diff --git a/filter/tree_test.c b/filter/tree_test.c index 9e0de50f..6472d17e 100644 --- a/filter/tree_test.c +++ b/filter/tree_test.c @@ -10,7 +10,7 @@ #include "test/bt-utils.h" #include "filter/filter.h" -#include "filter/f-util.h" +#include "filter/data.h" #include "conf/conf.h" #define MAX_TREE_HEIGHT 13 diff --git a/filter/trie.c b/filter/trie.c index dccf9130..3038f5ec 100644 --- a/filter/trie.c +++ b/filter/trie.c @@ -73,7 +73,7 @@ #include "lib/string.h" #include "conf/conf.h" #include "filter/filter.h" -#include "filter/f-util.h" +#include "filter/data.h" /* diff --git a/filter/trie_test.c b/filter/trie_test.c index b6959c4a..38c387b0 100644 --- a/filter/trie_test.c +++ b/filter/trie_test.c @@ -10,7 +10,7 @@ #include "test/bt-utils.h" #include "filter/filter.h" -#include "filter/f-util.h" +#include "filter/data.h" #include "conf/conf.h" #define TESTS_NUM 10 diff --git a/nest/a-path.c b/nest/a-path.c index ac13d0fa..62369af3 100644 --- a/nest/a-path.c +++ b/nest/a-path.c @@ -13,7 +13,7 @@ #include "lib/resource.h" #include "lib/unaligned.h" #include "lib/string.h" -#include "filter/f-util.h" +#include "filter/data.h" // static inline void put_as(byte *data, u32 as) { put_u32(data, as); } // static inline u32 get_as(byte *data) { return get_u32(data); } diff --git a/nest/cmds.c b/nest/cmds.c index 40d397cc..2b83033f 100644 --- a/nest/cmds.c +++ b/nest/cmds.c @@ -15,7 +15,7 @@ #include "lib/string.h" #include "lib/resource.h" #include "filter/filter.h" -#include "filter/f-util.h" +#include "filter/data.h" extern int shutting_down; extern int configuring; diff --git a/nest/rt-table.c b/nest/rt-table.c index d72a8695..6c8e662e 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -39,7 +39,7 @@ #include "lib/string.h" #include "conf/conf.h" #include "filter/filter.h" -#include "filter/f-util.h" +#include "filter/data.h" #include "lib/hash.h" #include "lib/string.h" #include "lib/alloca.h" diff --git a/proto/static/config.Y b/proto/static/config.Y index 0e53c978..3e9ac578 100644 --- a/proto/static/config.Y +++ b/proto/static/config.Y @@ -139,7 +139,7 @@ stat_route: stat_route_item: cmd { if (this_srt_last_cmd) - f_inst_next(this_srt_last_cmd, $1); + this_srt_last_cmd->next = $1; else this_srt_cmds = $1; this_srt_last_cmd = $1; diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index f9002d58..0fdd5b34 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -36,7 +36,7 @@ #include "nest/locks.h" #include "conf/conf.h" #include "filter/filter.h" -#include "filter/f-util.h" +#include "filter/data.h" #include "unix.h" #include "krt.h"