summaryrefslogtreecommitdiff
path: root/filter/config.Y
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2016-11-08 19:27:58 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2016-11-08 19:27:58 +0100
commit8860e991f6650e47cfe6c1af595fe4fe92a4edfd (patch)
tree18f49bb3a21739a1a596b54d9f65e82cff4fc09f /filter/config.Y
parentcc5b93f72db80abd1262a0a5e1d8400ceef54385 (diff)
parentc8cafc8ebb5320ac7c6117c17e6460036f0fdf62 (diff)
Merge branch 'master' into int-new
Diffstat (limited to 'filter/config.Y')
-rw-r--r--filter/config.Y151
1 files changed, 110 insertions, 41 deletions
diff --git a/filter/config.Y b/filter/config.Y
index 3eb5b08f..8af444a3 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -36,6 +36,7 @@ f_valid_set_type(int type)
case T_ENUM:
case T_IP:
case T_EC:
+ case T_LC:
return 1;
default:
@@ -66,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;
@@ -77,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)
@@ -132,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)
{
@@ -148,6 +172,9 @@ f_generate_empty(struct f_inst *dyn)
case EAF_TYPE_EC_SET:
e->aux = T_ECLIST;
break;
+ case EAF_TYPE_LC_SET:
+ e->aux = T_LCLIST;
+ break;
default:
cf_error("Can't empty that attribute");
}
@@ -266,14 +293,44 @@ f_generate_ec(u16 kind, struct f_inst *tk, struct f_inst *tv)
return rv;
}
+static inline struct f_inst *
+f_generate_lc(struct f_inst *t1, struct f_inst *t2, struct f_inst *t3)
+{
+ struct f_inst *rv;
+
+ if ((t1->code == 'c') && (t2->code == 'c') && (t3->code == 'c')) {
+ if ((t1->aux != T_INT) || (t2->aux != T_INT) || (t3->aux != T_INT))
+ cf_error( "LC - Can't operate with value of non-integer type in tuple constructor");
+
+ rv = f_new_inst();
+ rv->code = 'C';
+
+ NEW_F_VAL;
+ rv->a1.p = val;
+ val->type = T_LC;
+ val->val.lc = (lcomm) { t1->a2.i, t2->a2.i, t3->a2.i };
+ }
+ else
+ {
+ rv = cfg_allocz(sizeof(struct f_inst3));
+ rv->lineno = ifs->lino;
+ rv->code = P('m','l');
+ rv->a1.p = t1;
+ rv->a2.p = t2;
+ INST3(rv).p = t3;
+ }
+
+ return rv;
+}
+
CF_DECLS
CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
ACCEPT, REJECT, ERROR, QUITBIRD,
- INT, BOOL, IP, PREFIX, PAIR, QUAD, EC,
- SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST,
+ INT, BOOL, IP, PREFIX, PAIR, QUAD, EC, LC,
+ SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
IF, THEN, ELSE, CASE,
TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, CAST, DEST, IFNAME, IFINDEX,
@@ -291,9 +348,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 <f> filter filter_body where_filter
-%type <i> type break_command pair_expr ec_kind
-%type <i32> pair_atom ec_expr
-%type <e> pair_item ec_item set_item switch_item set_items switch_items switch_body
+%type <i> type break_command ec_kind
+%type <i32> cnum
+%type <e> pair_item ec_item lc_item set_item switch_item set_items switch_items switch_body
%type <trie> fprefix_set
%type <v> set_atom switch_atom fipa
%type <px> fprefix
@@ -326,17 +383,20 @@ type:
| PAIR { $$ = T_PAIR; }
| QUAD { $$ = T_QUAD; }
| EC { $$ = T_EC; }
+ | LC { $$ = T_LC; }
| STRING { $$ = T_STRING; }
| BGPMASK { $$ = T_PATH_MASK; }
| BGPPATH { $$ = T_PATH; }
| CLIST { $$ = T_CLIST; }
| ECLIST { $$ = T_ECLIST; }
- | type SET {
+ | LCLIST { $$ = T_LCLIST; }
+ | type SET {
switch ($1) {
case T_INT:
case T_PAIR:
case T_QUAD:
case T_EC:
+ case T_LC:
case T_IP:
$$ = T_SET;
break;
@@ -445,7 +505,7 @@ function_def:
} function_params function_body {
$2->def = $5;
$2->aux2 = $4;
- DBG("Hmm, we've got one function here - %s\n", $2->name);
+ DBG("Hmm, we've got one function here - %s\n", $2->name);
cf_pop_scope();
}
;
@@ -511,30 +571,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; }
@@ -543,14 +596,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); }
;
@@ -558,6 +624,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); }
;
@@ -608,7 +675,7 @@ switch_body: /* EMPTY */ { $$ = NULL; }
/* CONST '(' expr ')' { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_INT; $$->a2.i = $3; } */
bgp_path_expr:
- symbol { $$ = $1; }
+ symbol { $$ = $1; }
| '(' term ')' { $$ = $2; }
;
@@ -648,6 +715,7 @@ constant:
constructor:
'(' term ',' term ')' { $$ = f_generate_dpair($2, $4); }
| '(' ec_kind ',' term ',' term ')' { $$ = f_generate_ec($2, $4, $6); }
+ | '(' term ',' term ',' term ')' { $$ = f_generate_lc($2, $4, $6); }
;
@@ -758,8 +826,9 @@ term:
| '+' EMPTY '+' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_PATH; }
| '-' EMPTY '-' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_CLIST; }
| '-' '-' EMPTY '-' '-' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_ECLIST; }
- | PREPEND '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('A','p'); $$->a1.p = $3; $$->a2.p = $5; }
- | ADD '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'a'; }
+ | '-' '-' '-' EMPTY '-' '-' '-' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_LCLIST; }
+ | PREPEND '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('A','p'); $$->a1.p = $3; $$->a2.p = $5; }
+ | ADD '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'a'; }
| DELETE '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'd'; }
| FILTER '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'f'; }
@@ -814,7 +883,7 @@ print_list: /* EMPTY */ { $$ = NULL; }
}
;
-var_listn: term {
+var_listn: term {
$$ = f_new_inst();
$$->code = 's';
$$->a1.p = NULL;
@@ -882,7 +951,7 @@ cmd:
$$ = f_new_inst();
$$->code = P('P','S');
$$->a1.p = $3;
- }
+ }
| UNSET '(' rtadot dynamic_attr ')' ';' {
$$ = $4;
$$->aux = EAF_TYPE_UNDEF | EAF_TEMP;