summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filter/config.Y21
-rw-r--r--filter/f-util.c9
-rw-r--r--filter/filter.h3
-rw-r--r--proto/rip/config.Y6
4 files changed, 26 insertions, 13 deletions
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 <x> term block cmds cmd function_body constant print_one print_list var_list var_listn any_dynamic function_call
+%type <x> term block cmds cmd function_body constant print_one print_list var_list var_listn dynamic_attr function_call
%type <f> filter filter_body where_filter
%type <i> type break_command pair
%type <e> 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 <i> 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