diff options
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | conf/confbase.Y | 9 | ||||
-rw-r--r-- | filter/config.Y | 23 | ||||
-rw-r--r-- | filter/filter.h | 4 | ||||
-rw-r--r-- | lib/ip.h | 7 | ||||
-rw-r--r-- | nest/config.Y | 11 | ||||
-rw-r--r-- | proto/static/config.Y | 7 |
7 files changed, 38 insertions, 24 deletions
@@ -1,6 +1,5 @@ Core ~~~~ -- config: when parsing prefix, check zero bits - config: try to unify expressions - static: check validity of route destination? diff --git a/conf/confbase.Y b/conf/confbase.Y index 7ac07fe..c614301 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -40,6 +40,7 @@ CF_DECLS struct rt_show_data *ra; void *g; bird_clock_t time; + struct prefix px; } %token END CLI_MARKER INVALID_TOKEN @@ -52,6 +53,7 @@ CF_DECLS %type <i> expr bool pxlen %type <time> datetime +%type <px> prefix %nonassoc '=' '<' '>' '~' '.' GEQ LEQ NEQ %left '+' '-' @@ -109,6 +111,13 @@ bool: /* Prefixes and netmasks */ +prefix: + IPA pxlen { + if (!ip_is_prefix($1, $2)) cf_error("Invalid prefix"); + $$.addr = $1; $$.len = $2; + } + ; + pxlen: '/' NUM { if ($2 < 0 || $2 > BITS_PER_IP_ADDRESS) cf_error("Invalid prefix length %d", $2); diff --git a/filter/config.Y b/filter/config.Y index 38ee16a..343c1e0 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -42,7 +42,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 <v> set_atom prefix prefix_s ipa +%type <v> set_atom fprefix fprefix_s ipa %type <s> decls declsn one_decl function_params %type <h> bgp_path %type <i> bgp_one @@ -212,15 +212,18 @@ pair: /* * Complex types, their bison value is struct f_val */ -prefix_s: - IPA '/' NUM { $$.type = T_PREFIX; $$.val.px.ip = $1; $$.val.px.len = $3; if (ipa_nonzero(ipa_and($$.val.px.ip, ipa_not(ipa_mkmask($$.val.px.len))))) cf_error( "%I/%d is not really prefix\n", $$.val.px.ip, $$.val.px.len ); } +fprefix_s: + IPA '/' NUM { + 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; + } ; -prefix: - prefix_s { $$ = $1; } - | prefix_s '+' { $$ = $1; $$.val.px.len |= LEN_PLUS; } - | prefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; } - | prefix_s '{' NUM ',' NUM '}' { $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8); } +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); } ; ipa: @@ -231,7 +234,7 @@ set_atom: NUM { $$.type = T_INT; $$.val.i = $1; } | pair { $$.type = T_PAIR; $$.val.i = $1; } | ipa { $$ = $1; } - | prefix { $$ = $1; } + | fprefix { $$ = $1; } ; set_item: @@ -291,7 +294,7 @@ constant: | TEXT { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_STRING; $$->a2.p = $1; } | pair { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_PAIR; $$->a2.i = $1; } | ipa { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; } - | prefix_s {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" ); } | 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 = $2; $$->a1.p = val; } diff --git a/filter/filter.h b/filter/filter.h index e86aa02..a1bf548 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -30,7 +30,7 @@ struct f_inst { /* Instruction */ #define arg1 a1.p #define arg2 a2.p -struct prefix { +struct f_prefix { ip_addr ip; int len; #define LEN_MASK 0xff @@ -45,7 +45,7 @@ struct f_val { union { int i; /* ip_addr ip; Folded into prefix */ - struct prefix px; + struct f_prefix px; char *s; struct f_tree *t; struct adata *ad; @@ -41,9 +41,14 @@ char *ip_scope_text(unsigned); /* - * Is it a valid network prefix? + * Network prefixes */ +struct prefix { + ip_addr addr; + int len; +}; + #define ip_is_prefix(a,l) (!ipa_nonzero(ipa_and(a, ipa_not(ipa_mkmask(l))))) /* diff --git a/nest/config.Y b/nest/config.Y index e5249ea..f92c054 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -124,8 +124,8 @@ debug_default: iface_patt: TEXT { this_ipatt->pattern = $1; this_ipatt->prefix = IPA_NONE; this_ipatt->pxlen = 0; } - | IPA pxlen { this_ipatt->pattern = NULL; this_ipatt->prefix = $1; this_ipatt->pxlen = $2; } - | TEXT IPA pxlen { this_ipatt->pattern = $1; this_ipatt->prefix = $2; this_ipatt->pxlen = $3; } + | prefix { this_ipatt->pattern = NULL; this_ipatt->prefix = $1.addr; this_ipatt->pxlen = $1.len; } + | TEXT prefix { this_ipatt->pattern = $1; this_ipatt->prefix = $2.addr; this_ipatt->pxlen = $2.len; } ; /* Direct device route protocol */ @@ -250,12 +250,11 @@ r_args: $$->filter = FILTER_ACCEPT; $$->table = config->master_rtc->table; } - | r_args IPA pxlen { + | r_args prefix { $$ = $1; if ($$->pxlen != 256) cf_error("Only one prefix expected"); - if (!ip_is_prefix($2, $3)) cf_error("Invalid prefix"); - $$->prefix = $2; - $$->pxlen = $3; + $$->prefix = $2.addr; + $$->pxlen = $2.len; } | r_args TABLE SYM { $$ = $1; diff --git a/proto/static/config.Y b/proto/static/config.Y index 12d7934..0197da3 100644 --- a/proto/static/config.Y +++ b/proto/static/config.Y @@ -34,12 +34,11 @@ static_proto: | static_proto stat_route ';' ; -stat_route0: ROUTE IPA pxlen { +stat_route0: ROUTE prefix { this_srt = cfg_allocz(sizeof(struct static_route)); add_tail(&((struct static_config *) this_proto)->other_routes, &this_srt->n); - if (!ip_is_prefix($2, $3)) cf_error("Invalid network prefix: %I/%d", $2, $3); - this_srt->net = $2; - this_srt->masklen = $3; + this_srt->net = $2.addr; + this_srt->masklen = $2.len; } ; |