summaryrefslogtreecommitdiffstats
path: root/filter/config.Y
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2009-03-31 12:55:57 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2009-03-31 12:55:57 +0200
commitb1a597e0c3821c791a41278454e74261cf1b95fb (patch)
treefec1fdf523429e3afdcdaec6b0a96ef297723729 /filter/config.Y
parent1733d080c9f60de69e843f22e138f27240a8176c (diff)
downloadbird-b1a597e0c3821c791a41278454e74261cf1b95fb.tar
bird-b1a597e0c3821c791a41278454e74261cf1b95fb.zip
Reimplementation of prefix sets.
Prefix sets were broken beyond any repair and have to be reimplemented. They are reimplemented using a trie with bitmasks in nodes. There is also change in the interpretation of minus prefix pattern, but the old interpretation was already inconsistent with the documentation and broken. There is also some bugfixes in filter code related to set variables.
Diffstat (limited to 'filter/config.Y')
-rw-r--r--filter/config.Y69
1 files changed, 42 insertions, 27 deletions
diff --git a/filter/config.Y b/filter/config.Y
index 688464d..b6a0f47 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -36,6 +36,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
%type <f> filter filter_body where_filter
%type <i> type break_command pair
%type <e> set_item set_items switch_body
+%type <trie> fprefix_set
%type <v> set_atom fprefix fprefix_s fipa
%type <s> decls declsn one_decl function_params
%type <h> bgp_path bgp_path_tail1 bgp_path_tail2
@@ -69,12 +70,20 @@ type:
| CLIST { $$ = T_CLIST; }
| type SET {
switch ($1) {
+ case T_INT:
+ case T_IP:
+ case T_PAIR:
+ $$ = T_SET;
+ break;
+
+ case T_PREFIX:
+ $$ = T_PREFIX_SET;
+ break;
+
default:
cf_error( "You can't create sets of this type." );
- case T_INT: case T_IP: case T_PREFIX: case T_PAIR: ;
- }
- $$ = $1 | T_SET;
}
+ }
;
one_decl:
@@ -201,20 +210,6 @@ pair:
/*
* Complex types, their bison value is struct f_val
*/
-fprefix_s:
- IPA '/' NUM %prec '/' {
- if (!ip_is_prefix($1, $3)) cf_error("Invalid network prefix: %I/%d.", $1, $3);
- $$.type = T_PREFIX; $$.val.px.ip = $1; $$.val.px.len = $3;
- }
- ;
-
-fprefix:
- fprefix_s { $$ = $1; }
- | fprefix_s '+' { $$ = $1; $$.val.px.len |= LEN_PLUS; }
- | fprefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; }
- | fprefix_s '{' NUM ',' NUM '}' { $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8); }
- ;
-
fipa:
IPA %prec PREFIX_DUMMY { $$.type = T_IP; $$.val.px.ip = $1; }
;
@@ -223,7 +218,6 @@ set_atom:
NUM { $$.type = T_INT; $$.val.i = $1; }
| pair { $$.type = T_PAIR; $$.val.i = $1; }
| fipa { $$ = $1; }
- | fprefix { $$ = $1; }
| ENUM { $$.type = $1 >> 16; $$.val.i = $1 & 0xffff; }
;
@@ -231,18 +225,12 @@ set_item:
set_atom {
$$ = f_new_tree();
$$->from = $1;
- if ($1.type != T_PREFIX)
- $$->to = $1;
- else {
- $$->to = $1;
- $$->to.val.px.ip = ipa_or( $$->to.val.px.ip, ipa_not( ipa_mkmask( $$->to.val.px.len ) ));
- }
+ $$->to = $1;
}
| set_atom '.' '.' set_atom {
$$ = f_new_tree();
$$->from = $1;
$$->to = $4;
- if (($1.type == T_PREFIX) || ($4.type == T_PREFIX)) cf_error( "You can't use prefixes for range." );
}
;
@@ -251,6 +239,28 @@ set_items:
| set_items ',' set_item { $$ = $3; $$->left = $1; }
;
+fprefix_s:
+ IPA '/' NUM %prec '/' {
+ if (($3 < 0) || ($3 > MAX_PREFIX_LENGTH) || !ip_is_prefix($1, $3)) cf_error("Invalid network prefix: %I/%d.", $1, $3);
+ $$.type = T_PREFIX; $$.val.px.ip = $1; $$.val.px.len = $3;
+ }
+ ;
+
+fprefix:
+ fprefix_s { $$ = $1; }
+ | fprefix_s '+' { $$ = $1; $$.val.px.len |= LEN_PLUS; }
+ | fprefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; }
+ | fprefix_s '{' NUM ',' NUM '}' {
+ if (! ((0 <= $3) && ($3 <= $5) && ($5 <= MAX_PREFIX_LENGTH))) cf_error("Invalid prefix pattern range: {%d, %d}.", $3, $5);
+ $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8);
+ }
+ ;
+
+fprefix_set:
+ fprefix { $$ = f_new_trie(); trie_add_prefix($$, &($1.val.px)); }
+ | fprefix_set ',' fprefix { $$ = $1; trie_add_prefix($$, &($3.val.px)); }
+ ;
+
switch_body: /* EMPTY */ { $$ = NULL; }
| set_item ':' cmds switch_body {
$$ = $1;
@@ -294,6 +304,7 @@ constant:
| fipa { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
| fprefix_s {NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
| '[' set_items ']' { DBG( "We've got a set here..." ); $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_SET; $$->a2.p = build_tree($2); DBG( "ook\n" ); }
+ | '[' fprefix_set ']' { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_PREFIX_SET; $$->a2.p = $2; }
| ENUM { $$ = f_new_inst(); $$->code = 'c'; $$->aux = $1 >> 16; $$->a2.i = $1 & 0xffff; }
| bgp_path { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; val->type = T_PATH_MASK; val->val.path_mask = $1; $$->a1.p = val; }
;
@@ -374,12 +385,16 @@ term:
case SYM_IPA:
{ NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; val->type = T_IP; val->val.px.ip = * (ip_addr *) ($1->def); }
break;
+ case SYM_VARIABLE | T_BOOL:
case SYM_VARIABLE | T_INT:
case SYM_VARIABLE | T_PAIR:
- case SYM_VARIABLE | T_PREFIX:
+ case SYM_VARIABLE | T_STRING:
case SYM_VARIABLE | T_IP:
- case SYM_VARIABLE | T_PATH_MASK:
+ case SYM_VARIABLE | T_PREFIX:
+ case SYM_VARIABLE | T_PREFIX_SET:
+ case SYM_VARIABLE | T_SET:
case SYM_VARIABLE | T_PATH:
+ case SYM_VARIABLE | T_PATH_MASK:
case SYM_VARIABLE | T_CLIST:
$$->code = 'C';
$$->a1.p = $1->def;