Unified parsing of prefixes.
Had to rename `prefix' in filters to `fprefix'.
This commit is contained in:
parent
02bd064ab7
commit
758458be05
7 changed files with 38 additions and 24 deletions
1
TODO
1
TODO
|
@ -1,6 +1,5 @@
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
%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:
|
||||||
|
|
||||||
/* 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,
|
||||||
%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:
|
||||||
/*
|
/*
|
||||||
* 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:
|
||||||
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:
|
||||||
| 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 */
|
||||||
#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 {
|
||||||
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;
|
||||||
|
|
7
lib/ip.h
7
lib/ip.h
|
@ -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:
|
||||||
|
|
||||||
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:
|
||||||
$$->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:
|
||||||
| 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;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue