diff --git a/bird.conf b/bird.conf index 2129bab1..850b53e3 100644 --- a/bird.conf +++ b/bird.conf @@ -32,15 +32,16 @@ int i; print " false = " 1.2.3.4 ~ [ 1.2.3.3, 1.2.3.5 ]; print "done"; - quitbird; +# quitbird; print "*** FAIL: this is unreachable"; } filter testf int j; { - j = const(4321); - print j; + print "Heya, filtering route to " rta.net.ip " prefixlen " rta.net.len; + print "This route was from " rta.from; + accept; } protocol rip MyRIP_test { @@ -50,6 +51,7 @@ protocol rip MyRIP_test { period 5; garbagetime 30; interface "*"; + export filter testf; } protocol device { diff --git a/conf/confbase.Y b/conf/confbase.Y index f65a9f6b..522a1803 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -39,7 +39,7 @@ CF_DECLS %type expr bool pxlen -%nonassoc '=' '<' '>' '~' ELSE IF +%nonassoc '=' '<' '>' '~' ELSE IF '.' %left '+' '-' %left '*' '/' '%' %left '!' diff --git a/doc/bird.conf.example b/doc/bird.conf.example index c1bce781..6580ee7a 100644 --- a/doc/bird.conf.example +++ b/doc/bird.conf.example @@ -14,6 +14,7 @@ #protocol rip MyRIP_test { # preference xyzzy; # debug all; +# import filter okay; #} protocol direct { diff --git a/filter/config.Y b/filter/config.Y index 4f910c26..4fd18157 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -23,6 +23,9 @@ CF_KEYWORDS(FUNCTION, PRINT, CONST, INT, BOOL, IP, PREFIX, PAIR, SET, STRING, IF, THEN, ELSE, TRUE, FALSE, + RTA, FROM, GW, NET, + LEN, + IMPOSSIBLE, FILTER ) @@ -179,6 +182,13 @@ term: } } | constant { $$ = $1; } + | RTA '.' FROM { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_IP; $$->a2.i = OFFSETOF(struct rta, from); } + + | RTA '.' GW { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_IP; $$->a2.i = OFFSETOF(struct rta, gw); } + | RTA '.' NET { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_PREFIX; $$->a2.i = 0x12345678; } + + | term '.' IP { $$ = f_new_inst(); $$->code = 'cp'; $$->a1.p = $1; $$->a2.i = T_IP; } + | term '.' LEN { $$ = f_new_inst(); $$->code = 'cp'; $$->a1.p = $1; $$->a2.i = T_INT; } ; break_command: diff --git a/filter/filter.c b/filter/filter.c index c6c5c5af..7afae437 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -93,6 +93,8 @@ val_print(struct f_val v) printf( buf ); } +static struct rte **f_rte; + static struct f_val interpret(struct f_inst *what) { @@ -218,6 +220,36 @@ interpret(struct f_inst *what) bug( "unknown return type: can not happen"); } break; + case 'a': /* rta access */ + { + struct rta *rta = (*f_rte)->attrs; + res.type = what->a1.i; + switch(res.type) { + case T_IP: + res.val.ip = * (ip_addr *) ((char *) rta + what->a2.i); + break; + case T_PREFIX: /* Warning: this works only for prefix of network */ + { + res.val.px.ip = (*f_rte)->net->n.prefix; + res.val.px.len = (*f_rte)->net->n.pxlen; + break; + } + default: + bug( "Invalid type for rta access" ); + } + } + break; + case 'cp': /* Convert prefix to ... */ + ONEARG; + if (v1.type != T_PREFIX) + runtime( "Can not convert non-prefix this way" ); + res.type = what->a2.i; + switch(res.type) { + case T_INT: res.val.i = v1.val.px.len; break; + case T_IP: res.val.ip = v1.val.px.ip; break; + default: bug( "Unknown prefix to conversion\n" ); + } + break; default: bug( "Unknown instruction %d (%c)", what->code, what->code & 0xff); } @@ -233,6 +265,7 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc struct f_val res; debug( "Running filter `%s'...", filter->name ); + f_rte = rte; inst = filter->root; res = interpret(inst); if (res.type != T_RETURN) diff --git a/proto/rip/rip.c b/proto/rip/rip.c index cfaaa4c3..24d2e82b 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -69,11 +69,6 @@ rip_tx( sock *s ) return; } - if (c->done) { - DBG( "looks like I'm done!\n" ); - return; - } - DBG( "Preparing packet to send: " ); packet->heading.command = RIPCMD_RESPONSE;