Filter: large community sets

Add support for lc sets to filter code. Grammar of (small) community sets
has to be updated to avoid parser collisions.
This commit is contained in:
Ondrej Zajicek (work) 2016-10-01 22:31:01 +02:00
parent 66dbdbd993
commit 60566c5c80

View file

@ -67,6 +67,14 @@ f_merge_items(struct f_tree *a, struct f_tree *b)
static inline struct f_tree * static inline struct f_tree *
f_new_pair_item(int fa, int ta, int fb, int tb) f_new_pair_item(int fa, int ta, int fb, int tb)
{ {
check_u16(fa);
check_u16(ta);
check_u16(fb);
check_u16(tb);
if ((ta < fa) || (tb < fb))
cf_error( "From value cannot be higher that To value in pair sets");
struct f_tree *t = f_new_tree(); struct f_tree *t = f_new_tree();
t->right = t; t->right = t;
t->from.type = t->to.type = T_PAIR; t->from.type = t->to.type = T_PAIR;
@ -78,22 +86,26 @@ f_new_pair_item(int fa, int ta, int fb, int tb)
static inline struct f_tree * static inline struct f_tree *
f_new_pair_set(int fa, int ta, int fb, int tb) f_new_pair_set(int fa, int ta, int fb, int tb)
{ {
struct f_tree *lst = NULL; check_u16(fa);
int i; check_u16(ta);
check_u16(fb);
if ((fa == ta) || ((fb == 0) && (tb == 0xFFFF))) check_u16(tb);
return f_new_pair_item(fa, ta, fb, tb);
if ((ta < fa) || (tb < fb)) if ((ta < fa) || (tb < fb))
cf_error( "From value cannot be higher that To value in pair sets"); cf_error( "From value cannot be higher that To value in pair sets");
struct f_tree *lst = NULL;
int i;
for (i = fa; i <= ta; i++) for (i = fa; i <= ta; i++)
lst = f_merge_items(lst, f_new_pair_item(i, i, fb, tb)); lst = f_merge_items(lst, f_new_pair_item(i, i, fb, tb));
return lst; return lst;
} }
#define CC_ALL 0xFFFF
#define EC_ALL 0xFFFFFFFF #define EC_ALL 0xFFFFFFFF
#define LC_ALL 0xFFFFFFFF
static struct f_tree * static struct f_tree *
f_new_ec_item(u32 kind, u32 ipv4_used, u32 key, u32 vf, u32 vt) f_new_ec_item(u32 kind, u32 ipv4_used, u32 key, u32 vf, u32 vt)
@ -133,6 +145,17 @@ f_new_ec_item(u32 kind, u32 ipv4_used, u32 key, u32 vf, u32 vt)
return t; return t;
} }
static struct f_tree *
f_new_lc_item(u32 f1, u32 t1, u32 f2, u32 t2, u32 f3, u32 t3)
{
struct f_tree *t = f_new_tree();
t->right = t;
t->from.type = t->to.type = T_LC;
t->from.val.lc = (lcomm) {f1, f2, f3};
t->to.val.lc = (lcomm) {t1, t2, t3};
return t;
}
static inline struct f_inst * static inline struct f_inst *
f_generate_empty(struct f_inst *dyn) f_generate_empty(struct f_inst *dyn)
{ {
@ -327,9 +350,9 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
%type <x> term block cmds cmds_int cmd function_body constant constructor print_one print_list var_list var_listn dynamic_attr static_attr function_call symbol bgp_path_expr %type <x> term block cmds cmds_int cmd function_body constant constructor print_one print_list var_list var_listn dynamic_attr static_attr function_call symbol bgp_path_expr
%type <f> filter filter_body where_filter %type <f> filter filter_body where_filter
%type <i> type break_command pair_expr ec_kind %type <i> type break_command ec_kind
%type <i32> pair_atom ec_expr %type <i32> cnum
%type <e> pair_item ec_item set_item switch_item set_items switch_items switch_body %type <e> pair_item ec_item lc_item set_item switch_item set_items switch_items switch_body
%type <trie> fprefix_set %type <trie> fprefix_set
%type <v> set_atom switch_atom fprefix fprefix_s fipa %type <v> set_atom switch_atom fprefix fprefix_s fipa
%type <s> decls declsn one_decl function_params %type <s> decls declsn one_decl function_params
@ -550,30 +573,23 @@ switch_atom:
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); } | ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
; ;
pair_expr: cnum:
term { $$ = f_eval_int($1); check_u16($$); } term { $$ = f_eval_int($1); }
pair_atom:
pair_expr { $$ = pair($1, $1); }
| pair_expr DDOT pair_expr { $$ = pair($1, $3); }
| '*' { $$ = 0xFFFF; }
;
pair_item: pair_item:
'(' pair_atom ',' pair_atom ')' { '(' cnum ',' cnum ')' { $$ = f_new_pair_item($2, $2, $4, $4); }
$$ = f_new_pair_set(pair_a($2), pair_b($2), pair_a($4), pair_b($4)); | '(' cnum ',' cnum DDOT cnum ')' { $$ = f_new_pair_item($2, $2, $4, $6); }
} | '(' cnum ',' '*' ')' { $$ = f_new_pair_item($2, $2, 0, CC_ALL); }
| '(' pair_atom ',' pair_atom ')' DDOT '(' pair_expr ',' pair_expr ')' { | '(' cnum DDOT cnum ',' cnum ')' { $$ = f_new_pair_set($2, $4, $6, $6); }
/* Hack: $2 and $4 should be pair_expr, but that would cause shift/reduce conflict */ | '(' cnum DDOT cnum ',' cnum DDOT cnum ')' { $$ = f_new_pair_set($2, $4, $6, $8); }
if ((pair_a($2) != pair_b($2)) || (pair_a($4) != pair_b($4))) | '(' cnum DDOT cnum ',' '*' ')' { $$ = f_new_pair_item($2, $4, 0, CC_ALL); }
cf_error("syntax error"); | '(' '*' ',' cnum ')' { $$ = f_new_pair_set(0, CC_ALL, $4, $4); }
$$ = f_new_pair_item(pair_b($2), $8, pair_b($4), $10); | '(' '*' ',' cnum DDOT cnum ')' { $$ = f_new_pair_set(0, CC_ALL, $4, $6); }
} | '(' '*' ',' '*' ')' { $$ = f_new_pair_item(0, CC_ALL, 0, CC_ALL); }
| '(' cnum ',' cnum ')' DDOT '(' cnum ',' cnum ')'
{ $$ = f_new_pair_item($2, $8, $4, $10); }
; ;
ec_expr:
term { $$ = f_eval_int($1); }
ec_kind: ec_kind:
RT { $$ = EC_RT; } RT { $$ = EC_RT; }
| RO { $$ = EC_RO; } | RO { $$ = EC_RO; }
@ -582,14 +598,27 @@ ec_kind:
; ;
ec_item: ec_item:
'(' ec_kind ',' ec_expr ',' ec_expr ')' { $$ = f_new_ec_item($2, 0, $4, $6, $6); } '(' ec_kind ',' cnum ',' cnum ')' { $$ = f_new_ec_item($2, 0, $4, $6, $6); }
| '(' ec_kind ',' ec_expr ',' ec_expr DDOT ec_expr ')' { $$ = f_new_ec_item($2, 0, $4, $6, $8); } | '(' ec_kind ',' cnum ',' cnum DDOT cnum ')' { $$ = f_new_ec_item($2, 0, $4, $6, $8); }
| '(' ec_kind ',' ec_expr ',' '*' ')' { $$ = f_new_ec_item($2, 0, $4, 0, EC_ALL); } | '(' ec_kind ',' cnum ',' '*' ')' { $$ = f_new_ec_item($2, 0, $4, 0, EC_ALL); }
;
lc_item:
'(' cnum ',' cnum ',' cnum ')' { $$ = f_new_lc_item($2, $2, $4, $4, $6, $6); }
| '(' cnum ',' cnum ',' cnum DDOT cnum ')' { $$ = f_new_lc_item($2, $2, $4, $4, $6, $8); }
| '(' cnum ',' cnum ',' '*' ')' { $$ = f_new_lc_item($2, $2, $4, $4, 0, LC_ALL); }
| '(' cnum ',' cnum DDOT cnum ',' '*' ')' { $$ = f_new_lc_item($2, $2, $4, $6, 0, LC_ALL); }
| '(' cnum ',' '*' ',' '*' ')' { $$ = f_new_lc_item($2, $2, 0, LC_ALL, 0, LC_ALL); }
| '(' cnum DDOT cnum ',' '*' ',' '*' ')' { $$ = f_new_lc_item($2, $4, 0, LC_ALL, 0, LC_ALL); }
| '(' '*' ',' '*' ',' '*' ')' { $$ = f_new_lc_item(0, LC_ALL, 0, LC_ALL, 0, LC_ALL); }
| '(' cnum ',' cnum ',' cnum ')' DDOT '(' cnum ',' cnum ',' cnum ')'
{ $$ = f_new_lc_item($2, $10, $4, $12, $6, $14); }
; ;
set_item: set_item:
pair_item pair_item
| ec_item | ec_item
| lc_item
| set_atom { $$ = f_new_item($1, $1); } | set_atom { $$ = f_new_item($1, $1); }
| set_atom DDOT set_atom { $$ = f_new_item($1, $3); } | set_atom DDOT set_atom { $$ = f_new_item($1, $3); }
; ;
@ -597,6 +626,7 @@ set_item:
switch_item: switch_item:
pair_item pair_item
| ec_item | ec_item
| lc_item
| switch_atom { $$ = f_new_item($1, $1); } | switch_atom { $$ = f_new_item($1, $1); }
| switch_atom DDOT switch_atom { $$ = f_new_item($1, $3); } | switch_atom DDOT switch_atom { $$ = f_new_item($1, $3); }
; ;