Filter: merged filter instruction constructors, counting line size on instruction construct

This commit is contained in:
Maria Matejka 2019-02-08 13:38:12 +01:00
parent 0a793ebc60
commit 4f082dfa89
23 changed files with 291 additions and 410 deletions

View file

@ -18,6 +18,12 @@ AC_ARG_ENABLE([debug],
[enable_debug=no] [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], AC_ARG_ENABLE([memcheck],
[AS_HELP_STRING([--enable-memcheck], [check memory allocations when debugging @<:@yes@:>@])], [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]) AC_MSG_CHECKING([bison version])
BIRD_CHECK_BISON_VERSION(BISON_VERSION) BIRD_CHECK_BISON_VERSION(BISON_VERSION)
AC_MSG_RESULT([$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" M4FLAGS="$M4FLAGS -s"
fi fi

View file

@ -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) obj := $(src-o-files)
$(all-daemon) $(all-daemon)
$(cf-local) $(cf-local)
M4FLAGS_FILTERS=$(filter-out -s,$(M4FLAGS)) 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 $(o)f-inst-postfixify.c: $(s)postfixify.m4 $(s)f-inst.c $(objdir)/.dir-stamp
$(M4) $(M4FLAGS_FILTERS) -P $^ >$@ $(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 $(o)f-inst-same.c: $(s)same.m4 $(s)f-inst.c $(objdir)/.dir-stamp
$(M4) $(M4FLAGS_FILTERS) -P $^ >$@ $(M4) $(M4FLAGS_FILTERS) -P $^ >$@
$(o)f-inst-struct.h: $(s)struct.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-new.c: $(s)new.m4 $(s)f-inst.c $(objdir)/.dir-stamp
$(M4) $(M4FLAGS_FILTERS) -P $^ >$@ $(M4) $(M4FLAGS_FILTERS) -P $^ >$@
$(o)f-inst-dump.c: $(s)dump.m4 $(s)f-inst.c $(objdir)/.dir-stamp $(o)f-inst-dump.c: $(s)dump.m4 $(s)f-inst.c $(objdir)/.dir-stamp
$(M4) $(M4FLAGS_FILTERS) -P $^ >$@ $(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_src := tree_test.c filter_test.c trie_test.c
tests_targets := $(tests_targets) $(tests-target-files) tests_targets := $(tests_targets) $(tests-target-files)

View file

@ -11,7 +11,7 @@
CF_HDR CF_HDR
#include "filter/f-inst.h" #include "filter/f-inst.h"
#include "filter/f-util.h" #include "filter/data.h"
CF_DEFINES 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); checker = f_new_inst(FI_EQ, expr, getter);
f_inst_next(setter, checker); setter->next = checker;
return assert_done(setter, start, end); return assert_done(setter, start, end);
} }
@ -550,7 +550,7 @@ one_decl:
decls: /* EMPTY */ { $$ = NULL; } decls: /* EMPTY */ { $$ = NULL; }
| one_decl ';' decls { | one_decl ';' decls {
$$ = $1; $$ = $1;
f_inst_next($$, $3); $$->next = $3;
} }
; ;
@ -559,7 +559,7 @@ declsn: one_decl { $$.inst = $1; $$.count = 1; }
| one_decl ';' declsn { | one_decl ';' declsn {
$$ = $3; $$ = $3;
$$.count++; $$.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 { $$[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: block:
@ -803,11 +803,11 @@ bgp_path:
; ;
bgp_path_tail: 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 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 }, }); f_inst_next($$, $4); } | 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 }, }); f_inst_next($$, $2); } | '*' 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 }, }); 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 }, }); $$->next = $2; }
| bgp_path_expr bgp_path_tail { $$ = $1; f_inst_next($$, $2); } | bgp_path_expr bgp_path_tail { $$ = $1; $$->next = $2; }
| { $$ = NULL; } | { $$ = NULL; }
; ;
@ -946,7 +946,7 @@ print_list: /* EMPTY */ { $$ = NULL; }
| print_one { $$ = $1; } | print_one { $$ = $1; }
| print_one ',' print_list { | print_one ',' print_list {
if ($1) { if ($1) {
f_inst_next($1, $3); $1->next = $3;
$$ = $1; $$ = $1;
} else $$ = $3; } else $$ = $3;
} }
@ -957,7 +957,7 @@ var_listn: term {
} }
| term ',' var_listn { | term ',' var_listn {
$$ = $1; $$ = $1;
f_inst_next($$, $3); $$->next = $3;
} }
; ;

View file

@ -1,5 +1,5 @@
/* /*
* BIRD Internet Routing Daemon -- Filter utils * BIRD Internet Routing Daemon -- Dynamic data structures
* *
* (c) 1999 Pavel Machek <pavel@ucw.cz> * (c) 1999 Pavel Machek <pavel@ucw.cz>
* (c) 2018--2019 Maria Matejka <mq@jmq.cz> * (c) 2018--2019 Maria Matejka <mq@jmq.cz>
@ -7,14 +7,10 @@
* Can be freely distributed and used under the terms of the GNU GPL. * Can be freely distributed and used under the terms of the GNU GPL.
*/ */
#ifndef _BIRD_F_UTIL_H_ #ifndef _BIRD_FILTER_DATA_H_
#define _BIRD_F_UTIL_H_ #define _BIRD_FILTER_DATA_H_
/* IP prefix range structure */ #include "nest/bird.h"
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 */
};
/* Type numbers must be in 0..0xff range */ /* Type numbers must be in 0..0xff range */
#define T_MASK 0xff #define T_MASK 0xff
@ -84,8 +80,6 @@ struct f_val {
} val; } val;
}; };
#define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val));
/* Dynamic attribute definition (eattrs) */ /* Dynamic attribute definition (eattrs) */
struct f_dynamic_attr { struct f_dynamic_attr {
u8 type; /* EA type (EAF_*) */ u8 type; /* EA type (EAF_*) */
@ -113,6 +107,30 @@ struct f_static_attr {
int readonly:1; /* Don't allow writing */ 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 {
struct f_tree *left, *right; struct f_tree *left, *right;
struct f_val from, to; struct f_val from, to;

128
filter/decl.m4 Normal file
View file

@ -0,0 +1,128 @@
m4_divert(-1)m4_dnl
#
# BIRD -- Construction of per-instruction structures
#
# (c) 2018 Maria Matejka <mq@jmq.cz>
#
# 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([[,]])

View file

@ -109,15 +109,15 @@
ARG_ANY(1); ARG_ANY(1);
COUNT(2); COUNT(2);
NEW(, [[ FID_NEW_BODY
uint len = 0; uint len = 0;
uint dyn = 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) if (tt->fi_code != FI_CONSTANT)
dyn++; dyn++;
WHAT().count = len; what->count = len;
]]); FID_END
if (vstk.cnt < what->count) /* TODO: make this check systematic */ 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); runtime("Construction of BGP path mask from %u elements must have at least that number of elements", what->count);
@ -719,7 +719,7 @@
/* Then push the arguments */ /* Then push the arguments */
LINE(1,1); LINE(1,1);
NEW(, [[ FID_NEW_BODY
if (sym->class != SYM_FUNCTION) if (sym->class != SYM_FUNCTION)
cf_error("You can't call something which is not a function. Really."); cf_error("You can't call something which is not a function. Really.");
@ -729,7 +729,7 @@
if (count != sym->aux2) if (count != sym->aux2)
cf_error("Function %s takes %u arguments, got %u.", sym->name, sym->aux2, count); cf_error("Function %s takes %u arguments, got %u.", sym->name, sym->aux2, count);
]]); FID_END
} }
INST(FI_DROP_RESULT, 1, 0) { INST(FI_DROP_RESULT, 1, 0) {

View file

@ -10,137 +10,21 @@
#ifndef _BIRD_F_INST_H_ #ifndef _BIRD_F_INST_H_
#define _BIRD_F_INST_H_ #define _BIRD_F_INST_H_
#include "nest/bird.h"
#include "conf/conf.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "filter/f-util.h" #include "filter/data.h"
/* Filter l-value type */ /* Include generated filter instruction declarations */
enum f_lval_type { #include "filter/f-inst-decl.h"
F_LVAL_VARIABLE,
F_LVAL_PREFERENCE,
F_LVAL_SA,
F_LVAL_EA,
};
/* Filter l-value */ #define f_new_inst(...) MACRO_CONCAT_AFTER(f_new_inst_, MACRO_FIRST(__VA_ARGS__))(__VA_ARGS__)
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;
/* Convert the instruction back to the enum name */ /* Convert the instruction back to the enum name */
const char *f_instruction_name(enum f_instruction_code fi); 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); 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 */ /* Flags for instructions */
enum f_instruction_flags { enum f_instruction_flags {
FIF_PRINTED = 1, /* FI_PRINT_AND_DIE: message put in buffer */ FIF_PRINTED = 1, /* FI_PRINT_AND_DIE: message put in buffer */
@ -202,7 +86,4 @@ struct f_bt_test_suite {
const char *dsc; /* Description */ const char *dsc; /* Description */
}; };
/* Include the auto-generated structures */
#include "filter/f-inst-struct.h"
#endif #endif

View file

@ -17,22 +17,6 @@
#define P(a,b) ((a<<8) | b) #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 * char *
filter_name(struct filter *filter) filter_name(struct filter *filter)
{ {
@ -56,18 +40,21 @@ struct filter *f_new_where(const struct f_inst *where)
struct f_inst acc = { struct f_inst acc = {
.fi_code = FI_PRINT_AND_DIE, .fi_code = FI_PRINT_AND_DIE,
.lineno = ifs->lino, .lineno = ifs->lino,
.size = 1,
.i_FI_PRINT_AND_DIE = { .fret = F_ACCEPT, }, .i_FI_PRINT_AND_DIE = { .fret = F_ACCEPT, },
}; };
struct f_inst rej = { struct f_inst rej = {
.fi_code = FI_PRINT_AND_DIE, .fi_code = FI_PRINT_AND_DIE,
.lineno = ifs->lino, .lineno = ifs->lino,
.size = 1,
.i_FI_PRINT_AND_DIE = { .fret = F_REJECT, }, .i_FI_PRINT_AND_DIE = { .fret = F_REJECT, },
}; };
struct f_inst i = { struct f_inst i = {
.fi_code = FI_CONDITION, .fi_code = FI_CONDITION,
.lineno = ifs->lino, .lineno = ifs->lino,
.size = 3,
.i_FI_CONDITION = { .i_FI_CONDITION = {
.f1 = where, .f1 = where,
.f2 = &acc, .f2 = &acc,

View file

@ -48,7 +48,7 @@
#include "conf/conf.h" #include "conf/conf.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "filter/f-inst.h" #include "filter/f-inst.h"
#include "filter/f-util.h" #include "filter/data.h"
#define CMP_ERROR 999 #define CMP_ERROR 999
@ -64,6 +64,75 @@ struct filter_state {
void (*bt_assert_hook)(int result, const struct f_line_item *assert); 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 */ /* Special undef value for paths and clists */
static inline int static inline int
undef_value(struct f_val v) 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 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) #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[] = " "; 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; uint len = 0;
for (uint i=0; i<count; i++) for (uint i=0; i<count; i++)
len += inst_line_size(inst[i]); for (const struct f_inst *what = inst[i]; what; what = what->next)
len += what->size;
struct f_line *out = cfg_allocz(sizeof(struct f_line) + sizeof(struct f_line_item)*len); struct f_line *out = cfg_allocz(sizeof(struct f_line) + sizeof(struct f_line_item)*len);

View file

@ -17,7 +17,7 @@
#include "test/bt-utils.h" #include "test/bt-utils.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "filter/f-util.h" #include "filter/data.h"
#include "filter/f-inst.h" #include "filter/f-inst.h"
#include "conf/conf.h" #include "conf/conf.h"

View file

@ -63,10 +63,11 @@ m4_define(TREE, `')
m4_define(STRING, `') m4_define(STRING, `')
m4_define(COUNT, `') m4_define(COUNT, `')
m4_define(POSTFIXIFY, `') m4_define(POSTFIXIFY, `')
m4_define(LINE_SIZE, `')
m4_define(SAME, `') m4_define(SAME, `')
m4_define(STRUCT, `') m4_define(FID_STRUCT_IN, `m4_divert(-1)')
m4_define(NEW, `') 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(` m4_m4wrap(`
INST_FLUSH() INST_FLUSH()

View file

@ -1,41 +0,0 @@
m4_divert(-1)m4_dnl
#
# BIRD -- Line size counting
#
# (c) 2018 Maria Matejka <mq@jmq.cz>
#
# 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([[,]])

View file

@ -1,78 +0,0 @@
m4_divert(-1)m4_dnl
#
# BIRD -- Construction of per-instruction structures
#
# (c) 2018 Maria Matejka <mq@jmq.cz>
#
# 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([[,]])

View file

@ -1,73 +0,0 @@
m4_divert(-1)m4_dnl
#
# BIRD -- Definition of per-instruction structures
#
# (c) 2018 Maria Matejka <mq@jmq.cz>
#
# 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([[,]])

View file

@ -10,7 +10,7 @@
#include "nest/bird.h" #include "nest/bird.h"
#include "conf/conf.h" #include "conf/conf.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "filter/f-util.h" #include "filter/data.h"
/** /**
* find_tree * find_tree

View file

@ -10,7 +10,7 @@
#include "test/bt-utils.h" #include "test/bt-utils.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "filter/f-util.h" #include "filter/data.h"
#include "conf/conf.h" #include "conf/conf.h"
#define MAX_TREE_HEIGHT 13 #define MAX_TREE_HEIGHT 13

View file

@ -73,7 +73,7 @@
#include "lib/string.h" #include "lib/string.h"
#include "conf/conf.h" #include "conf/conf.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "filter/f-util.h" #include "filter/data.h"
/* /*

View file

@ -10,7 +10,7 @@
#include "test/bt-utils.h" #include "test/bt-utils.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "filter/f-util.h" #include "filter/data.h"
#include "conf/conf.h" #include "conf/conf.h"
#define TESTS_NUM 10 #define TESTS_NUM 10

View file

@ -13,7 +13,7 @@
#include "lib/resource.h" #include "lib/resource.h"
#include "lib/unaligned.h" #include "lib/unaligned.h"
#include "lib/string.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 void put_as(byte *data, u32 as) { put_u32(data, as); }
// static inline u32 get_as(byte *data) { return get_u32(data); } // static inline u32 get_as(byte *data) { return get_u32(data); }

View file

@ -15,7 +15,7 @@
#include "lib/string.h" #include "lib/string.h"
#include "lib/resource.h" #include "lib/resource.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "filter/f-util.h" #include "filter/data.h"
extern int shutting_down; extern int shutting_down;
extern int configuring; extern int configuring;

View file

@ -39,7 +39,7 @@
#include "lib/string.h" #include "lib/string.h"
#include "conf/conf.h" #include "conf/conf.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "filter/f-util.h" #include "filter/data.h"
#include "lib/hash.h" #include "lib/hash.h"
#include "lib/string.h" #include "lib/string.h"
#include "lib/alloca.h" #include "lib/alloca.h"

View file

@ -139,7 +139,7 @@ stat_route:
stat_route_item: stat_route_item:
cmd { cmd {
if (this_srt_last_cmd) if (this_srt_last_cmd)
f_inst_next(this_srt_last_cmd, $1); this_srt_last_cmd->next = $1;
else else
this_srt_cmds = $1; this_srt_cmds = $1;
this_srt_last_cmd = $1; this_srt_last_cmd = $1;

View file

@ -36,7 +36,7 @@
#include "nest/locks.h" #include "nest/locks.h"
#include "conf/conf.h" #include "conf/conf.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "filter/f-util.h" #include "filter/data.h"
#include "unix.h" #include "unix.h"
#include "krt.h" #include "krt.h"