summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bird.conf8
-rw-r--r--conf/confbase.Y2
-rw-r--r--doc/bird.conf.example1
-rw-r--r--filter/config.Y10
-rw-r--r--filter/filter.c33
-rw-r--r--proto/rip/rip.c5
6 files changed, 50 insertions, 9 deletions
diff --git a/bird.conf b/bird.conf
index 2129bab..850b53e 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 f65a9f6..522a180 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -39,7 +39,7 @@ CF_DECLS
%type <i> 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 c1bce78..6580ee7 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 4f910c2..4fd1815 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 c6c5c5a..7afae43 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 cfaaa4c..24d2e82 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;