diff --git a/filter/config.Y b/filter/config.Y index 856189ec..ed94b9bf 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -34,16 +34,15 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, CONST, UNSET, RETURN, INT, BOOL, IP, PREFIX, PAIR, SET, STRING, IF, THEN, ELSE, CASE, TRUE, FALSE, - RTA, FROM, GW, NET, MASK, RIP_METRIC, RIP_TAG, SOURCE, + FROM, GW, NET, MASK, SOURCE, LEN, DEFINED, - IMPOSSIBLE, FILTER, WHERE) %nonassoc THEN %nonassoc ELSE -%type term block cmds cmd function_body constant print_one print_list var_list var_listn any_dynamic function_call +%type term block cmds cmd function_body constant print_one print_list var_list var_listn dynamic_attr function_call %type filter filter_body where_filter %type type break_command pair %type set_item set_items switch_body @@ -268,10 +267,12 @@ constant: | ENUM { $$ = f_new_inst(); $$->code = 'c'; $$->aux = $1 >> 16; $$->a2.i = $1 & 0xffff; } ; -any_dynamic: - RIP_METRIC { $$ = f_new_inst(); $$->aux = T_INT; $$->a2.i = EA_RIP_METRIC;} - | RIP_TAG { $$ = f_new_inst(); $$->aux = T_INT; $$->a2.i = EA_RIP_TAG; } - ; +/* + * Maybe there are no dynamic attributes defined by protocols. + * For such cases, we force the dynamic_attr list to contain + * at least an invalid token, so it's syntantically correct. + */ +CF_ADDTO(dynamic_attr, INVALID_TOKEN { $$ = NULL; }) rtadot: /* EMPTY, we are not permitted RTA. prefix */ ; @@ -334,7 +335,7 @@ term: | rtadot NET { $$ = f_new_inst(); $$->code = 'a'; $$->aux = T_PREFIX; $$->a2.i = 0x12345678; } | rtadot SOURCE { $$ = f_new_inst(); $$->code = 'a'; $$->aux = T_ENUM_RTS; $$->a2.i = OFFSETOF(struct rta, gw); } - | rtadot any_dynamic { $$ = $2; $$->code = P('e','a'); } + | rtadot dynamic_attr { $$ = $2; $$->code = P('e','a'); } | term '.' IP { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_IP; } | term '.' LEN { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_INT; } @@ -416,12 +417,12 @@ cmd: $$->code = 'r'; $$->a1.p = $2; } - | rtadot any_dynamic '=' term ';' { + | rtadot dynamic_attr '=' term ';' { $$ = $2; $$->code = P('e','S'); $$->a1.p = $4; } - | UNSET '(' rtadot any_dynamic ')' ';' { + | UNSET '(' rtadot dynamic_attr ')' ';' { $$ = $4; $$->aux = T_VOID; $$->code = P('e','S'); diff --git a/filter/f-util.c b/filter/f-util.c index b070d951..2bc78737 100644 --- a/filter/f-util.c +++ b/filter/f-util.c @@ -32,6 +32,15 @@ f_new_inst(void) return ret; } +struct f_inst * +f_new_dynamic_attr(int code) +{ + struct f_inst *f = f_new_inst(); + f->aux = T_INT; + f->a2.i = code; + return f; +} + char * filter_name(struct filter *filter) { diff --git a/filter/filter.h b/filter/filter.h index a08f1267..bbf30408 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -57,6 +57,7 @@ struct filter { void filters_postconfig(void); struct f_inst *f_new_inst(void); +struct f_inst *f_new_dynamic_attr(int code); struct f_tree *f_new_tree(void); struct f_tree *build_tree(struct f_tree *); @@ -121,6 +122,4 @@ struct f_tree { #define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val)); -/* Create pair from two letters */ - #endif diff --git a/proto/rip/config.Y b/proto/rip/config.Y index 1bc67207..e1094a50 100644 --- a/proto/rip/config.Y +++ b/proto/rip/config.Y @@ -25,7 +25,8 @@ CF_DECLS CF_KEYWORDS(RIP, INFINITY, METRIC, PORT, PERIOD, GARBAGETIME, PASSWORDS, MODE, BROADCAST, QUIET, NOLISTEN, VERSION1, AUTHENTICATION, NONE, PLAINTEXT, MD5, - HONOUR, NEVER, NEIGHBOUR, ALWAYS) + HONOUR, NEVER, NEIGHBOUR, ALWAYS, + RIP_METRIC, RIP_TAG) %type rip_mode rip_auth @@ -97,6 +98,9 @@ rip_iface_list: | rip_iface_list ',' rip_iface ; +CF_ADDTO(dynamic_attr, RIP_METRIC { $$ = f_new_dynamic_attr(EA_RIP_METRIC); }) +CF_ADDTO(dynamic_attr, RIP_TAG { $$ = f_new_dynamic_attr(EA_RIP_TAG); }) + CF_CODE CF_END