Commit 758458be authored by Martin Mareš's avatar Martin Mareš

Unified parsing of prefixes.

Had to rename `prefix' in filters to `fprefix'.
parent 02bd064a
Core Core
~~~~ ~~~~
- config: when parsing prefix, check zero bits
- config: try to unify expressions - config: try to unify expressions
- static: check validity of route destination? - static: check validity of route destination?
......
...@@ -40,6 +40,7 @@ CF_DECLS ...@@ -40,6 +40,7 @@ CF_DECLS
struct rt_show_data *ra; struct rt_show_data *ra;
void *g; void *g;
bird_clock_t time; bird_clock_t time;
struct prefix px;
} }
%token END CLI_MARKER INVALID_TOKEN %token END CLI_MARKER INVALID_TOKEN
...@@ -52,6 +53,7 @@ CF_DECLS ...@@ -52,6 +53,7 @@ CF_DECLS
%type <i> expr bool pxlen %type <i> expr bool pxlen
%type <time> datetime %type <time> datetime
%type <px> prefix
%nonassoc '=' '<' '>' '~' '.' GEQ LEQ NEQ %nonassoc '=' '<' '>' '~' '.' GEQ LEQ NEQ
%left '+' '-' %left '+' '-'
...@@ -109,6 +111,13 @@ bool: ...@@ -109,6 +111,13 @@ bool:
/* Prefixes and netmasks */ /* Prefixes and netmasks */
prefix:
IPA pxlen {
if (!ip_is_prefix($1, $2)) cf_error("Invalid prefix");
$$.addr = $1; $$.len = $2;
}
;
pxlen: pxlen:
'/' NUM { '/' NUM {
if ($2 < 0 || $2 > BITS_PER_IP_ADDRESS) cf_error("Invalid prefix length %d", $2); if ($2 < 0 || $2 > BITS_PER_IP_ADDRESS) cf_error("Invalid prefix length %d", $2);
......
...@@ -42,7 +42,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, ...@@ -42,7 +42,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
%type <f> filter filter_body where_filter %type <f> filter filter_body where_filter
%type <i> type break_command pair %type <i> type break_command pair
%type <e> set_item set_items switch_body %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 <s> decls declsn one_decl function_params
%type <h> bgp_path %type <h> bgp_path
%type <i> bgp_one %type <i> bgp_one
...@@ -212,15 +212,18 @@ pair: ...@@ -212,15 +212,18 @@ pair:
/* /*
* Complex types, their bison value is struct f_val * Complex types, their bison value is struct f_val
*/ */
prefix_s: fprefix_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 ); } 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: fprefix:
prefix_s { $$ = $1; } fprefix_s { $$ = $1; }
| prefix_s '+' { $$ = $1; $$.val.px.len |= LEN_PLUS; } | fprefix_s '+' { $$ = $1; $$.val.px.len |= LEN_PLUS; }
| prefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; } | fprefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; }
| prefix_s '{' NUM ',' NUM '}' { $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8); } | fprefix_s '{' NUM ',' NUM '}' { $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8); }
; ;
ipa: ipa:
...@@ -231,7 +234,7 @@ set_atom: ...@@ -231,7 +234,7 @@ set_atom:
NUM { $$.type = T_INT; $$.val.i = $1; } NUM { $$.type = T_INT; $$.val.i = $1; }
| pair { $$.type = T_PAIR; $$.val.i = $1; } | pair { $$.type = T_PAIR; $$.val.i = $1; }
| ipa { $$ = $1; } | ipa { $$ = $1; }
| prefix { $$ = $1; } | fprefix { $$ = $1; }
; ;
set_item: set_item:
...@@ -291,7 +294,7 @@ constant: ...@@ -291,7 +294,7 @@ constant:
| TEXT { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_STRING; $$->a2.p = $1; } | TEXT { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_STRING; $$->a2.p = $1; }
| pair { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_PAIR; $$->a2.i = $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; } | 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" ); } | '[' 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; } | 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; } | '/' bgp_path '/' { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; val->type = T_PATH_MASK; val->val.path_mask = $2; $$->a1.p = val; }
......
...@@ -30,7 +30,7 @@ struct f_inst { /* Instruction */ ...@@ -30,7 +30,7 @@ struct f_inst { /* Instruction */
#define arg1 a1.p #define arg1 a1.p
#define arg2 a2.p #define arg2 a2.p
struct prefix { struct f_prefix {
ip_addr ip; ip_addr ip;
int len; int len;
#define LEN_MASK 0xff #define LEN_MASK 0xff
...@@ -45,7 +45,7 @@ struct f_val { ...@@ -45,7 +45,7 @@ struct f_val {
union { union {
int i; int i;
/* ip_addr ip; Folded into prefix */ /* ip_addr ip; Folded into prefix */
struct prefix px; struct f_prefix px;
char *s; char *s;
struct f_tree *t; struct f_tree *t;
struct adata *ad; struct adata *ad;
......
...@@ -41,9 +41,14 @@ ...@@ -41,9 +41,14 @@
char *ip_scope_text(unsigned); 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))))) #define ip_is_prefix(a,l) (!ipa_nonzero(ipa_and(a, ipa_not(ipa_mkmask(l)))))
/* /*
......
...@@ -124,8 +124,8 @@ debug_default: ...@@ -124,8 +124,8 @@ debug_default:
iface_patt: iface_patt:
TEXT { this_ipatt->pattern = $1; this_ipatt->prefix = IPA_NONE; this_ipatt->pxlen = 0; } 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; } | prefix { this_ipatt->pattern = NULL; this_ipatt->prefix = $1.addr; this_ipatt->pxlen = $1.len; }
| TEXT IPA pxlen { this_ipatt->pattern = $1; this_ipatt->prefix = $2; this_ipatt->pxlen = $3; } | TEXT prefix { this_ipatt->pattern = $1; this_ipatt->prefix = $2.addr; this_ipatt->pxlen = $2.len; }
; ;
/* Direct device route protocol */ /* Direct device route protocol */
...@@ -250,12 +250,11 @@ r_args: ...@@ -250,12 +250,11 @@ r_args:
$$->filter = FILTER_ACCEPT; $$->filter = FILTER_ACCEPT;
$$->table = config->master_rtc->table; $$->table = config->master_rtc->table;
} }
| r_args IPA pxlen { | r_args prefix {
$$ = $1; $$ = $1;
if ($$->pxlen != 256) cf_error("Only one prefix expected"); if ($$->pxlen != 256) cf_error("Only one prefix expected");
if (!ip_is_prefix($2, $3)) cf_error("Invalid prefix"); $$->prefix = $2.addr;
$$->prefix = $2; $$->pxlen = $2.len;
$$->pxlen = $3;
} }
| r_args TABLE SYM { | r_args TABLE SYM {
$$ = $1; $$ = $1;
......
...@@ -34,12 +34,11 @@ static_proto: ...@@ -34,12 +34,11 @@ static_proto:
| static_proto stat_route ';' | static_proto stat_route ';'
; ;
stat_route0: ROUTE IPA pxlen { stat_route0: ROUTE prefix {
this_srt = cfg_allocz(sizeof(struct static_route)); this_srt = cfg_allocz(sizeof(struct static_route));
add_tail(&((struct static_config *) this_proto)->other_routes, &this_srt->n); 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.addr;
this_srt->net = $2; this_srt->masklen = $2.len;
this_srt->masklen = $3;
} }
; ;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment