Allows to define constants of all filter types.
This commit is contained in:
parent
ac57451348
commit
1103b32e83
6 changed files with 62 additions and 71 deletions
|
@ -15,10 +15,10 @@
|
||||||
* symbols and keywords.
|
* symbols and keywords.
|
||||||
*
|
*
|
||||||
* Each symbol is represented by a &symbol structure containing name
|
* 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,
|
* of the symbol, its lexical scope, symbol class (%SYM_PROTO for a
|
||||||
* %SYM_NUMBER for a numeric constant etc.) and class dependent data.
|
* name of a protocol, %SYM_CONSTANT for a constant etc.) and class
|
||||||
* When an unknown symbol is encountered, it's automatically added to the
|
* dependent data. When an unknown symbol is encountered, it's
|
||||||
* symbol table with class %SYM_VOID.
|
* automatically added to the symbol table with class %SYM_VOID.
|
||||||
*
|
*
|
||||||
* The keyword tables are generated from the grammar templates
|
* The keyword tables are generated from the grammar templates
|
||||||
* using the |gen_keywords.m4| script.
|
* using the |gen_keywords.m4| script.
|
||||||
|
@ -623,24 +623,23 @@ cf_walk_symbols(struct config *cf, struct symbol *sym, int *pos)
|
||||||
char *
|
char *
|
||||||
cf_symbol_class_name(struct symbol *sym)
|
cf_symbol_class_name(struct symbol *sym)
|
||||||
{
|
{
|
||||||
|
if ((sym->class & 0xff00) == SYM_CONSTANT)
|
||||||
|
return "constant";
|
||||||
|
|
||||||
switch (sym->class)
|
switch (sym->class)
|
||||||
{
|
{
|
||||||
case SYM_VOID:
|
case SYM_VOID:
|
||||||
return "undefined";
|
return "undefined";
|
||||||
case SYM_PROTO:
|
case SYM_PROTO:
|
||||||
return "protocol";
|
return "protocol";
|
||||||
case SYM_NUMBER:
|
case SYM_TEMPLATE:
|
||||||
return "numeric constant";
|
return "protocol template";
|
||||||
case SYM_FUNCTION:
|
case SYM_FUNCTION:
|
||||||
return "function";
|
return "function";
|
||||||
case SYM_FILTER:
|
case SYM_FILTER:
|
||||||
return "filter";
|
return "filter";
|
||||||
case SYM_TABLE:
|
case SYM_TABLE:
|
||||||
return "routing table";
|
return "routing table";
|
||||||
case SYM_IPA:
|
|
||||||
return "network address";
|
|
||||||
case SYM_TEMPLATE:
|
|
||||||
return "protocol template";
|
|
||||||
case SYM_ROA:
|
case SYM_ROA:
|
||||||
return "ROA table";
|
return "ROA table";
|
||||||
default:
|
default:
|
||||||
|
|
10
conf/conf.h
10
conf/conf.h
|
@ -110,15 +110,17 @@ struct symbol {
|
||||||
/* Remember to update cf_symbol_class_name() */
|
/* Remember to update cf_symbol_class_name() */
|
||||||
#define SYM_VOID 0
|
#define SYM_VOID 0
|
||||||
#define SYM_PROTO 1
|
#define SYM_PROTO 1
|
||||||
#define SYM_NUMBER 2
|
#define SYM_TEMPLATE 2
|
||||||
#define SYM_FUNCTION 3
|
#define SYM_FUNCTION 3
|
||||||
#define SYM_FILTER 4
|
#define SYM_FILTER 4
|
||||||
#define SYM_TABLE 5
|
#define SYM_TABLE 5
|
||||||
#define SYM_IPA 6
|
#define SYM_ROA 6
|
||||||
#define SYM_TEMPLATE 7
|
|
||||||
#define SYM_ROA 8
|
|
||||||
|
|
||||||
#define SYM_VARIABLE 0x100 /* 0x100-0x1ff are variable types */
|
#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 {
|
struct include_file_stack {
|
||||||
void *buffer; /* Internal lexer state */
|
void *buffer; /* Internal lexer state */
|
||||||
|
|
|
@ -103,28 +103,29 @@ conf_entries:
|
||||||
|
|
||||||
CF_ADDTO(conf, ';')
|
CF_ADDTO(conf, ';')
|
||||||
|
|
||||||
|
|
||||||
/* Constant expressions */
|
/* 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:
|
expr:
|
||||||
NUM
|
NUM
|
||||||
| '(' term ')' { $$ = f_eval_int($2); }
|
| '(' 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; }; */
|
/* 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 */
|
/* Switches */
|
||||||
|
|
||||||
bool:
|
bool:
|
||||||
|
@ -141,8 +142,8 @@ bool:
|
||||||
ipa:
|
ipa:
|
||||||
IPA
|
IPA
|
||||||
| SYM {
|
| SYM {
|
||||||
if ($1->class != SYM_IPA) cf_error("IP address expected");
|
if ($1->class != (SYM_CONSTANT | T_IP)) cf_error("IP address expected");
|
||||||
$$ = *(ip_addr *)$1->def;
|
$$ = SYM_VAL($1).px.ip;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,14 @@ f_generate_ec(u16 kind, struct f_inst *tk, struct f_inst *tv)
|
||||||
else if (tk->code == 'C') {
|
else if (tk->code == 'C') {
|
||||||
c1 = 1;
|
c1 = 1;
|
||||||
struct f_val *val = tk->a1.p;
|
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);
|
ipv4_used = 1; key = ipa_to_u32(val->val.px.ip);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -661,37 +668,15 @@ function_call:
|
||||||
symbol:
|
symbol:
|
||||||
SYM {
|
SYM {
|
||||||
$$ = f_new_inst();
|
$$ = f_new_inst();
|
||||||
switch ($1->class) {
|
|
||||||
case SYM_NUMBER:
|
switch ($1->class & 0xff00) {
|
||||||
$$ = f_new_inst();
|
case SYM_CONSTANT: $$->code = 'C'; break;
|
||||||
$$->code = 'c';
|
case SYM_VARIABLE: $$->code = 'V'; break;
|
||||||
$$->aux = T_INT;
|
default: cf_error("%s: variable expected.", $1->name);
|
||||||
$$->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;
|
$$->a1.p = $1->def;
|
||||||
$$->a2.p = $1->name;
|
$$->a2.p = $1->name;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cf_error("%s: variable expected.", $1->name );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static_attr:
|
static_attr:
|
||||||
|
|
|
@ -240,6 +240,15 @@ int b;
|
||||||
print "Defined: ", a, " ", b, " ", defined(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()
|
function __startup()
|
||||||
int i;
|
int i;
|
||||||
bool b;
|
bool b;
|
||||||
|
@ -249,9 +258,6 @@ pair pp;
|
||||||
quad qq;
|
quad qq;
|
||||||
ec cc;
|
ec cc;
|
||||||
int set is;
|
int set is;
|
||||||
int set is1;
|
|
||||||
int set is2;
|
|
||||||
int set is3;
|
|
||||||
pair set ps;
|
pair set ps;
|
||||||
ec set ecs;
|
ec set ecs;
|
||||||
prefix set pxs;
|
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 " 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;
|
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: ", 1 ~ is1, " ", 3 ~ is1, " ", 5 ~ is1;
|
||||||
print " must be true: ", (one+2) ~ is1, " ", 2 ~ is2, " ", 2 ~ is3;
|
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, *)];
|
ecs = [(rt, ten, (one+onef(0))*10), (ro, 100000, 100..200), (rt, 12345, *)];
|
||||||
print "EC set: ", ecs;
|
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,
|
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;
|
" ", (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,
|
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, ",",
|
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;
|
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} ]);
|
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 ];
|
print "What will this do? ", [ 1, 2, 1, 1, 1, 3, 4, 1, 1, 1, 5 ];
|
||||||
|
|
||||||
|
|
|
@ -97,9 +97,10 @@ static inline void
|
||||||
add_num_const(char *name, int val)
|
add_num_const(char *name, int val)
|
||||||
{
|
{
|
||||||
struct symbol *s = cf_find_symbol(name);
|
struct symbol *s = cf_find_symbol(name);
|
||||||
s->class = SYM_NUMBER;
|
s->class = SYM_CONSTANT | T_INT;
|
||||||
s->def = NULL;
|
s->def = cfg_allocz(sizeof(struct f_val));
|
||||||
s->aux = val;
|
SYM_TYPE(s) = T_INT;
|
||||||
|
SYM_VAL(s).i = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the code of read_iproute_table() is based on
|
/* the code of read_iproute_table() is based on
|
||||||
|
|
Loading…
Reference in a new issue