diff --git a/filter/config.Y b/filter/config.Y index 79e274ab..29e3a734 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -67,6 +67,14 @@ f_merge_items(struct f_tree *a, struct f_tree *b) static inline struct f_tree * 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(); t->right = t; 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 * f_new_pair_set(int fa, int ta, int fb, int tb) { - struct f_tree *lst = NULL; - int i; + check_u16(fa); + check_u16(ta); + check_u16(fb); + check_u16(tb); - if ((fa == ta) || ((fb == 0) && (tb == 0xFFFF))) - return f_new_pair_item(fa, ta, fb, tb); - if ((ta < fa) || (tb < fb)) 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++) lst = f_merge_items(lst, f_new_pair_item(i, i, fb, tb)); return lst; } +#define CC_ALL 0xFFFF #define EC_ALL 0xFFFFFFFF +#define LC_ALL 0xFFFFFFFF static struct f_tree * 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; } +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 * f_generate_empty(struct f_inst *dyn) { @@ -327,9 +350,9 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, %type 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 filter filter_body where_filter -%type type break_command pair_expr ec_kind -%type pair_atom ec_expr -%type pair_item ec_item set_item switch_item set_items switch_items switch_body +%type type break_command ec_kind +%type cnum +%type pair_item ec_item lc_item set_item switch_item set_items switch_items switch_body %type fprefix_set %type set_atom switch_atom fprefix fprefix_s fipa %type decls declsn one_decl function_params @@ -550,30 +573,23 @@ switch_atom: | ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); } ; -pair_expr: - term { $$ = f_eval_int($1); check_u16($$); } - -pair_atom: - pair_expr { $$ = pair($1, $1); } - | pair_expr DDOT pair_expr { $$ = pair($1, $3); } - | '*' { $$ = 0xFFFF; } - ; +cnum: + term { $$ = f_eval_int($1); } pair_item: - '(' pair_atom ',' pair_atom ')' { - $$ = f_new_pair_set(pair_a($2), pair_b($2), pair_a($4), pair_b($4)); - } - | '(' pair_atom ',' pair_atom ')' DDOT '(' pair_expr ',' pair_expr ')' { - /* Hack: $2 and $4 should be pair_expr, but that would cause shift/reduce conflict */ - if ((pair_a($2) != pair_b($2)) || (pair_a($4) != pair_b($4))) - cf_error("syntax error"); - $$ = f_new_pair_item(pair_b($2), $8, pair_b($4), $10); - } + '(' cnum ',' cnum ')' { $$ = f_new_pair_item($2, $2, $4, $4); } + | '(' cnum ',' cnum DDOT cnum ')' { $$ = f_new_pair_item($2, $2, $4, $6); } + | '(' cnum ',' '*' ')' { $$ = f_new_pair_item($2, $2, 0, CC_ALL); } + | '(' cnum DDOT cnum ',' cnum ')' { $$ = f_new_pair_set($2, $4, $6, $6); } + | '(' cnum DDOT cnum ',' cnum DDOT cnum ')' { $$ = f_new_pair_set($2, $4, $6, $8); } + | '(' cnum DDOT cnum ',' '*' ')' { $$ = f_new_pair_item($2, $4, 0, CC_ALL); } + | '(' '*' ',' cnum ')' { $$ = f_new_pair_set(0, CC_ALL, $4, $4); } + | '(' '*' ',' 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: RT { $$ = EC_RT; } | RO { $$ = EC_RO; } @@ -582,14 +598,27 @@ ec_kind: ; ec_item: - '(' ec_kind ',' ec_expr ',' ec_expr ')' { $$ = 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 ',' ec_expr ',' '*' ')' { $$ = f_new_ec_item($2, 0, $4, 0, EC_ALL); } + '(' ec_kind ',' cnum ',' cnum ')' { $$ = f_new_ec_item($2, 0, $4, $6, $6); } + | '(' ec_kind ',' cnum ',' cnum DDOT cnum ')' { $$ = f_new_ec_item($2, 0, $4, $6, $8); } + | '(' 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: pair_item | ec_item + | lc_item | set_atom { $$ = f_new_item($1, $1); } | set_atom DDOT set_atom { $$ = f_new_item($1, $3); } ; @@ -597,6 +626,7 @@ set_item: switch_item: pair_item | ec_item + | lc_item | switch_atom { $$ = f_new_item($1, $1); } | switch_atom DDOT switch_atom { $$ = f_new_item($1, $3); } ;