From b1a597e0c3821c791a41278454e74261cf1b95fb Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Tue, 31 Mar 2009 12:55:57 +0200 Subject: 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. --- filter/config.Y | 69 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 27 deletions(-) (limited to 'filter/config.Y') 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 filter filter_body where_filter %type type break_command pair %type set_item set_items switch_body +%type fprefix_set %type set_atom fprefix fprefix_s fipa %type decls declsn one_decl function_params %type 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; -- cgit v1.2.3