mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-17 08:38:42 +00:00
Filter: Split printing and dying
This commit is contained in:
parent
3265c9169d
commit
0206c070ac
@ -64,7 +64,9 @@ CF_DECLS
|
|||||||
struct rtable_config *r;
|
struct rtable_config *r;
|
||||||
struct channel_config *cc;
|
struct channel_config *cc;
|
||||||
struct f_inst *x;
|
struct f_inst *x;
|
||||||
struct f_inst *xp[2];
|
struct {
|
||||||
|
struct f_inst *begin, *end;
|
||||||
|
} xp;
|
||||||
enum filter_return fret;
|
enum filter_return fret;
|
||||||
enum ec_subtype ecs;
|
enum ec_subtype ecs;
|
||||||
struct f_dynamic_attr fda;
|
struct f_dynamic_attr fda;
|
||||||
|
@ -447,7 +447,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
|
|||||||
%nonassoc ELSE
|
%nonassoc ELSE
|
||||||
|
|
||||||
%type <xp> cmds_int
|
%type <xp> cmds_int
|
||||||
%type <x> term block cmd cmds constant constructor print_one print_list var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail
|
%type <x> term block cmd cmds constant constructor print_list var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail
|
||||||
%type <fda> dynamic_attr
|
%type <fda> dynamic_attr
|
||||||
%type <fsa> static_attr
|
%type <fsa> static_attr
|
||||||
%type <f> filter where_filter
|
%type <f> filter where_filter
|
||||||
@ -621,11 +621,21 @@ function_def:
|
|||||||
/* Programs */
|
/* Programs */
|
||||||
|
|
||||||
cmds: /* EMPTY */ { $$ = NULL; }
|
cmds: /* EMPTY */ { $$ = NULL; }
|
||||||
| cmds_int { $$ = $1[0]; }
|
| cmds_int { $$ = $1.begin; }
|
||||||
;
|
;
|
||||||
|
|
||||||
cmds_int: cmd { $$[0] = $$[1] = $1; }
|
cmds_int: cmd {
|
||||||
| cmds_int cmd { $$[1] = $2; $1[1]->next = $2; $$[0] = $1[0]; }
|
$$.begin = $$.end = $1;
|
||||||
|
while ($$.end->next)
|
||||||
|
$$.end = $$.end->next;
|
||||||
|
}
|
||||||
|
| cmds_int cmd {
|
||||||
|
$$.begin = $1.begin;
|
||||||
|
$1.end->next = $2;
|
||||||
|
$$.end = $2;
|
||||||
|
while ($$.end->next)
|
||||||
|
$$.end = $$.end->next;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
block:
|
block:
|
||||||
@ -960,17 +970,13 @@ break_command:
|
|||||||
| PRINTN { $$ = F_NONL; }
|
| PRINTN { $$ = F_NONL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
print_one:
|
|
||||||
term { $$ = f_new_inst(FI_PRINT, $1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
print_list: /* EMPTY */ { $$ = NULL; }
|
print_list: /* EMPTY */ { $$ = NULL; }
|
||||||
| print_one { $$ = $1; }
|
| term { $$ = $1; }
|
||||||
| print_one ',' print_list {
|
| term ',' print_list {
|
||||||
if ($1) {
|
ASSERT($1);
|
||||||
$1->next = $3;
|
ASSERT($1->next == NULL);
|
||||||
$$ = $1;
|
$1->next = $3;
|
||||||
} else $$ = $3;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -1011,7 +1017,22 @@ cmd:
|
|||||||
| UNSET '(' dynamic_attr ')' ';' {
|
| UNSET '(' dynamic_attr ')' ';' {
|
||||||
$$ = f_new_inst(FI_EA_UNSET, $3);
|
$$ = f_new_inst(FI_EA_UNSET, $3);
|
||||||
}
|
}
|
||||||
| break_command print_list ';' { $$ = f_new_inst(FI_PRINT_AND_DIE, $2, $1); }
|
| break_command print_list ';' {
|
||||||
|
struct f_inst *breaker = NULL;
|
||||||
|
struct f_inst *printer = NULL;
|
||||||
|
if ($2)
|
||||||
|
printer = f_new_inst(FI_PRINT, $2);
|
||||||
|
if ($1 != F_NONL)
|
||||||
|
breaker = f_new_inst(FI_DIE, $1);
|
||||||
|
|
||||||
|
if (printer && breaker)
|
||||||
|
printer->next = breaker;
|
||||||
|
|
||||||
|
if (printer)
|
||||||
|
$$ = printer;
|
||||||
|
else
|
||||||
|
$$ = breaker;
|
||||||
|
}
|
||||||
| function_call ';' { $$ = f_new_inst(FI_DROP_RESULT, $1); }
|
| function_call ';' { $$ = f_new_inst(FI_DROP_RESULT, $1); }
|
||||||
| CASE term '{' switch_body '}' {
|
| CASE term '{' switch_body '}' {
|
||||||
$$ = f_new_inst(FI_SWITCH, $2, build_tree($4));
|
$$ = f_new_inst(FI_SWITCH, $2, build_tree($4));
|
||||||
|
@ -93,6 +93,25 @@ FID_INTERPRET_EXEC()m4_dnl
|
|||||||
const $1 $2 = whati->$2
|
const $1 $2 = whati->$2
|
||||||
FID_INTERPRET_BODY')
|
FID_INTERPRET_BODY')
|
||||||
|
|
||||||
|
m4_define(FID_MEMBER_IN, `m4_dnl
|
||||||
|
FID_LINE_IN()m4_dnl
|
||||||
|
$1 $2;
|
||||||
|
FID_STRUCT_IN()m4_dnl
|
||||||
|
$1 $2;
|
||||||
|
FID_LINEARIZE_BODY()m4_dnl
|
||||||
|
item->$2 = whati->$2;
|
||||||
|
m4_ifelse($3,,,[[
|
||||||
|
FID_SAME_BODY()m4_dnl
|
||||||
|
if ($3) return 0;
|
||||||
|
]])
|
||||||
|
m4_ifelse($4,,,[[
|
||||||
|
FID_DUMP_BODY()m4_dnl
|
||||||
|
debug("%s$4\n", INDENT, $5);
|
||||||
|
]])
|
||||||
|
FID_INTERPRET_EXEC()m4_dnl
|
||||||
|
const $1 $2 = whati->$2
|
||||||
|
FID_INTERPRET_BODY')
|
||||||
|
|
||||||
# Instruction arguments are needed only until linearization is done.
|
# Instruction arguments are needed only until linearization is done.
|
||||||
# This puts the arguments into the filter line to be executed before
|
# This puts the arguments into the filter line to be executed before
|
||||||
# the instruction itself.
|
# the instruction itself.
|
||||||
|
@ -173,7 +173,7 @@
|
|||||||
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);
|
||||||
|
|
||||||
#define pv fstk->vstk[fstk->vcnt - count + i]
|
#define pv fstk->vstk[fstk->vcnt - whati->count + i]
|
||||||
|
|
||||||
FID_INTERPRET_NEW
|
FID_INTERPRET_NEW
|
||||||
#define pv items[i]->i_FI_CONSTANT.val
|
#define pv items[i]->i_FI_CONSTANT.val
|
||||||
@ -320,11 +320,6 @@
|
|||||||
|
|
||||||
RESULT_VAL(val);
|
RESULT_VAL(val);
|
||||||
}
|
}
|
||||||
INST(FI_PRINT, 1, 0) {
|
|
||||||
NEVER_CONSTANT;
|
|
||||||
ARG_ANY(1);
|
|
||||||
val_format(&(v1), &fs->buf);
|
|
||||||
}
|
|
||||||
INST(FI_CONDITION, 1, 0) {
|
INST(FI_CONDITION, 1, 0) {
|
||||||
ARG(1, T_BOOL);
|
ARG(1, T_BOOL);
|
||||||
if (v1.val.i)
|
if (v1.val.i)
|
||||||
@ -332,28 +327,37 @@
|
|||||||
else
|
else
|
||||||
LINE(3,1);
|
LINE(3,1);
|
||||||
}
|
}
|
||||||
INST(FI_PRINT_AND_DIE, 0, 0) {
|
|
||||||
|
INST(FI_PRINT, 0, 0) {
|
||||||
NEVER_CONSTANT;
|
NEVER_CONSTANT;
|
||||||
FID_LINEARIZE_BODY
|
|
||||||
{
|
|
||||||
uint opos = pos;
|
|
||||||
FID_INTERPRET_BODY
|
|
||||||
|
|
||||||
ARG_ANY(1);
|
ARG_ANY(1);
|
||||||
|
FID_MEMBER_IN(uint, count, f1->count != f2->count, number of items %u, item->count);
|
||||||
|
|
||||||
|
FID_NEW_BODY
|
||||||
|
uint len = 0;
|
||||||
|
for (const struct f_inst *tt = f1; tt; tt = tt->next, len++)
|
||||||
|
;
|
||||||
|
whati->count = len;
|
||||||
|
|
||||||
FID_LINEARIZE_BODY
|
|
||||||
if (opos < pos)
|
|
||||||
dest->items[pos].flags |= FIF_PRINTED;
|
|
||||||
}
|
|
||||||
FID_INTERPRET_BODY
|
FID_INTERPRET_BODY
|
||||||
|
|
||||||
|
#define pv fstk->vstk[fstk->vcnt - whati->count + i]
|
||||||
|
if (whati->count)
|
||||||
|
for (uint i=0; i<whati->count; i++)
|
||||||
|
val_format(&(pv), &fs->buf);
|
||||||
|
#undef pv
|
||||||
|
|
||||||
|
fstk->vcnt -= whati->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
INST(FI_DIE, 0, 0) {
|
||||||
|
NEVER_CONSTANT;
|
||||||
FID_MEMBER(enum filter_return, fret, f1->fret != f2->fret, %s, filter_return_str(item->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 (fs->buf.start < fs->buf.pos)
|
||||||
!(fs->flags & FF_SILENT))
|
|
||||||
log_commit(*L_INFO, &fs->buf);
|
log_commit(*L_INFO, &fs->buf);
|
||||||
|
|
||||||
switch (fret) {
|
switch (whati->fret) {
|
||||||
case F_QUITBIRD:
|
case F_QUITBIRD:
|
||||||
die( "Filter asked me to die" );
|
die( "Filter asked me to die" );
|
||||||
case F_ACCEPT:
|
case F_ACCEPT:
|
||||||
@ -361,7 +365,6 @@
|
|||||||
case F_ERROR:
|
case F_ERROR:
|
||||||
case F_REJECT: /* FIXME (noncritical) Should print complete route along with reason to reject route */
|
case F_REJECT: /* FIXME (noncritical) Should print complete route along with reason to reject route */
|
||||||
return fret; /* We have to return now, no more processing. */
|
return fret; /* We have to return now, no more processing. */
|
||||||
case F_NONL:
|
|
||||||
case F_NOP:
|
case F_NOP:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -33,17 +33,17 @@ filter_name(const struct filter *filter)
|
|||||||
struct filter *f_new_where(struct f_inst *where)
|
struct filter *f_new_where(struct f_inst *where)
|
||||||
{
|
{
|
||||||
struct f_inst acc = {
|
struct f_inst acc = {
|
||||||
.fi_code = FI_PRINT_AND_DIE,
|
.fi_code = FI_DIE,
|
||||||
.lineno = ifs->lino,
|
.lineno = ifs->lino,
|
||||||
.size = 1,
|
.size = 1,
|
||||||
.i_FI_PRINT_AND_DIE = { .fret = F_ACCEPT, },
|
.i_FI_DIE = { .fret = F_ACCEPT, },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct f_inst rej = {
|
struct f_inst rej = {
|
||||||
.fi_code = FI_PRINT_AND_DIE,
|
.fi_code = FI_DIE,
|
||||||
.lineno = ifs->lino,
|
.lineno = ifs->lino,
|
||||||
.size = 1,
|
.size = 1,
|
||||||
.i_FI_PRINT_AND_DIE = { .fret = F_REJECT, },
|
.i_FI_DIE = { .fret = F_REJECT, },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct f_inst i = {
|
struct f_inst i = {
|
||||||
|
Loading…
Reference in New Issue
Block a user