diff --git a/conf/cf-lex.l b/conf/cf-lex.l index e0430485..50f390e0 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -15,10 +15,10 @@ * symbols and keywords. * * Each symbol is represented by a &symbol structure containing name - * of the symbol, its lexical scope, symbol class (%SYM_PROTO for a name of a protocol, - * %SYM_NUMBER for a numeric constant etc.) and class dependent data. - * When an unknown symbol is encountered, it's automatically added to the - * symbol table with class %SYM_VOID. + * of the symbol, its lexical scope, symbol class (%SYM_PROTO for a + * name of a protocol, %SYM_CONSTANT for a constant etc.) and class + * dependent data. When an unknown symbol is encountered, it's + * automatically added to the symbol table with class %SYM_VOID. * * The keyword tables are generated from the grammar templates * using the |gen_keywords.m4| script. @@ -623,24 +623,23 @@ cf_walk_symbols(struct config *cf, struct symbol *sym, int *pos) char * cf_symbol_class_name(struct symbol *sym) { + if ((sym->class & 0xff00) == SYM_CONSTANT) + return "constant"; + switch (sym->class) { case SYM_VOID: return "undefined"; case SYM_PROTO: return "protocol"; - case SYM_NUMBER: - return "numeric constant"; + case SYM_TEMPLATE: + return "protocol template"; case SYM_FUNCTION: return "function"; case SYM_FILTER: return "filter"; case SYM_TABLE: return "routing table"; - case SYM_IPA: - return "network address"; - case SYM_TEMPLATE: - return "protocol template"; case SYM_ROA: return "ROA table"; default: diff --git a/conf/conf.h b/conf/conf.h index 683374e0..28624294 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -110,15 +110,17 @@ struct symbol { /* Remember to update cf_symbol_class_name() */ #define SYM_VOID 0 #define SYM_PROTO 1 -#define SYM_NUMBER 2 +#define SYM_TEMPLATE 2 #define SYM_FUNCTION 3 #define SYM_FILTER 4 #define SYM_TABLE 5 -#define SYM_IPA 6 -#define SYM_TEMPLATE 7 -#define SYM_ROA 8 +#define SYM_ROA 6 #define SYM_VARIABLE 0x100 /* 0x100-0x1ff are variable types */ +#define SYM_CONSTANT 0x200 /* 0x200-0x2ff are variable types */ + +#define SYM_TYPE(s) (((struct f_val *) (s)->def)->type) +#define SYM_VAL(s) (((struct f_val *) (s)->def)->val) struct include_file_stack { void *buffer; /* Internal lexer state */ diff --git a/conf/confbase.Y b/conf/confbase.Y index dcb0719f..c6678e77 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -103,28 +103,29 @@ conf_entries: CF_ADDTO(conf, ';') + /* Constant expressions */ +CF_ADDTO(conf, definition) +definition: + DEFINE SYM '=' term ';' { + struct f_val *val = cfg_alloc(sizeof(struct f_val)); + *val = f_eval($4, cfg_mem); + if (val->type == T_RETURN) cf_error("Runtime error"); + cf_define_symbol($2, SYM_CONSTANT | val->type, val); + } + ; + expr: NUM | '(' term ')' { $$ = f_eval_int($2); } - | SYM { if ($1->class != SYM_NUMBER) cf_error("Number expected"); else $$ = $1->aux; } + | SYM { + if ($1->class != (SYM_CONSTANT | T_INT)) cf_error("Number expected"); + $$ = SYM_VAL($1).i; } ; /* expr_u16: expr { check_u16($1); $$ = $1; }; */ -CF_ADDTO(conf, definition) -definition: - DEFINE SYM '=' expr ';' { - cf_define_symbol($2, SYM_NUMBER, NULL); - $2->aux = $4; - } - | DEFINE SYM '=' IPA ';' { - cf_define_symbol($2, SYM_IPA, cfg_alloc(sizeof(ip_addr))); - *(ip_addr *)$2->def = $4; - } - ; - /* Switches */ bool: @@ -141,8 +142,8 @@ bool: ipa: IPA | SYM { - if ($1->class != SYM_IPA) cf_error("IP address expected"); - $$ = *(ip_addr *)$1->def; + if ($1->class != (SYM_CONSTANT | T_IP)) cf_error("IP address expected"); + $$ = SYM_VAL($1).px.ip; } ; diff --git a/filter/config.Y b/filter/config.Y index 0eeb2ce1..2ca03463 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -193,7 +193,14 @@ f_generate_ec(u16 kind, struct f_inst *tk, struct f_inst *tv) else if (tk->code == 'C') { c1 = 1; struct f_val *val = tk->a1.p; - if (val->type == T_IP) { + + if (val->type == T_INT) { + ipv4_used = 0; key = val->val.i; + } + else if (val->type == T_QUAD) { + ipv4_used = 1; key = val->val.i; + } + else if (val->type == T_IP) { ipv4_used = 1; key = ipa_to_u32(val->val.px.ip); } else @@ -661,37 +668,15 @@ function_call: symbol: SYM { $$ = f_new_inst(); - switch ($1->class) { - case SYM_NUMBER: - $$ = f_new_inst(); - $$->code = 'c'; - $$->aux = T_INT; - $$->a2.i = $1->aux; - break; - case SYM_IPA: - { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; val->type = T_IP; val->val.px.ip = * (ip_addr *) ($1->def); } - break; - case SYM_VARIABLE | T_BOOL: - case SYM_VARIABLE | T_INT: - case SYM_VARIABLE | T_PAIR: - case SYM_VARIABLE | T_QUAD: - case SYM_VARIABLE | T_EC: - case SYM_VARIABLE | T_STRING: - case SYM_VARIABLE | T_IP: - case SYM_VARIABLE | T_PREFIX: - case SYM_VARIABLE | T_PREFIX_SET: - case SYM_VARIABLE | T_SET: - case SYM_VARIABLE | T_PATH: - case SYM_VARIABLE | T_PATH_MASK: - case SYM_VARIABLE | T_CLIST: - case SYM_VARIABLE | T_ECLIST: - $$->code = 'V'; - $$->a1.p = $1->def; - $$->a2.p = $1->name; - break; - default: - cf_error("%s: variable expected.", $1->name ); + + switch ($1->class & 0xff00) { + case SYM_CONSTANT: $$->code = 'C'; break; + case SYM_VARIABLE: $$->code = 'V'; break; + default: cf_error("%s: variable expected.", $1->name); } + + $$->a1.p = $1->def; + $$->a2.p = $1->name; } static_attr: diff --git a/filter/test.conf b/filter/test.conf index 3b29232a..4f40abff 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -240,6 +240,15 @@ int b; print "Defined: ", a, " ", b, " ", defined(b); } +define is1 = [ one, (2+1), (6-one), 8, 11, 15, 17, 19]; +define is2 = [(17+2), 17, 15, 11, 8, 5, 3, 2]; +define is3 = [5, 17, 2, 11, 8, 15, 3, 19]; + +define pxs2 = [ 10.0.0.0/16{8,12}, 20.0.0.0/16{24,28} ]; + +define ecs2 = [(rt, ten, (one+onef(0))*10), (ro, 100000, 100..200), (rt, 12345, *)]; + + function __startup() int i; bool b; @@ -249,9 +258,6 @@ pair pp; quad qq; ec cc; int set is; -int set is1; -int set is2; -int set is3; pair set ps; ec set ecs; prefix set pxs; @@ -279,11 +285,6 @@ string s; print " must be true: ", defined(1), ",", defined(1.2.3.4), ",", 1 != 2, ",", 1 <= 2; print " data types: must be false: ", 1 ~ [ 2, 3, 4 ], ",", 5 ~ is, ",", 1.2.3.4 ~ [ 1.2.3.3, 1.2.3.5 ], ",", (1,2) > (2,2), ",", (1,1) > (1,1), ",", 1.0.0.0/9 ~ [ 1.0.0.0/8- ], ",", 1.2.0.0/17 ~ [ 1.0.0.0/8{ 15 , 16 } ], ",", true && false; - is1 = [ 1, 5, 8, 11, 15, 17, 19]; - - is1 = [ one, (2+1), (6-one), 8, 11, 15, 17, 19]; - is2 = [(17+2), 17, 15, 11, 8, 5, 3, 2]; - is3 = [5, 17, 2, 11, 8, 15, 3, 19]; print " must be true: ", 1 ~ is1, " ", 3 ~ is1, " ", 5 ~ is1; print " must be true: ", (one+2) ~ is1, " ", 2 ~ is2, " ", 2 ~ is3; @@ -333,6 +334,7 @@ string s; ecs = [(rt, ten, (one+onef(0))*10), (ro, 100000, 100..200), (rt, 12345, *)]; print "EC set: ", ecs; + print "EC set: ", ecs2; print "Testing EC set, true: ", (rt, 10, 20) ~ ecs, " ", (ro, 100000, 100) ~ ecs, " ", (ro, 100000, 200) ~ ecs, " ", (rt, 12345, 0) ~ ecs, " ", cc ~ ecs, " ", (rt, 12345, 4000000) ~ ecs; print "Testing EC set, false: ", (ro, 10, 20) ~ ecs, " ", (rt, 10, 21) ~ ecs, " ", (ro, 100000, 99) ~ ecs, @@ -354,6 +356,7 @@ string s; print " must be false: ", 1.1.0.0/16 ~ pxs, ",", 1.3.0.0/16 ~ pxs, ",", 1.2.0.0/15 ~ pxs, ",", 1.2.0.0/17 ~ pxs, ",", 1.2.0.0/32 ~ pxs, ",", 1.4.0.0/15 ~ pxs; + test_pxset(pxs2); test_pxset([ 10.0.0.0/16{8,12}, 20.0.0.0/16{24,28} ]); print "What will this do? ", [ 1, 2, 1, 1, 1, 3, 4, 1, 1, 1, 5 ]; diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index 23040e54..bd80ba2c 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -97,9 +97,10 @@ static inline void add_num_const(char *name, int val) { struct symbol *s = cf_find_symbol(name); - s->class = SYM_NUMBER; - s->def = NULL; - s->aux = val; + s->class = SYM_CONSTANT | T_INT; + s->def = cfg_allocz(sizeof(struct f_val)); + SYM_TYPE(s) = T_INT; + SYM_VAL(s).i = val; } /* the code of read_iproute_table() is based on