]> git.ipfire.org Git - thirdparty/bird.git/blame - filter/config.Y
DEF_PREF_UKR and DEF_PREF_SINK removed.
[thirdparty/bird.git] / filter / config.Y
CommitLineData
b9d70dc8
PM
1/*
2 * BIRD - filters
3 *
6542ece9 4 * Copyright 1998,1999 Pavel Machek
b9d70dc8
PM
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
c9f8c1a8 7 *
f4536657 8 FIXME (nonurgent): define keyword
c9f8c1a8
PM
9 FIXME: whole system of paths, path ~ string, path.prepend(), path.originate
10 FIXME: create community lists
f4536657 11 FIXME: write access to dynamic attributes.
346a12c2
PM
12 FIXME: '! =' should not be permitted. Ze `!=' by nemelo byt totez jako `! =' Nadefinujes si pres %token novy token a do cf-lex.l pridas nove pravidlo, ktere jej rozpoznava. Napriklad != return NEQ;
13
b9d70dc8
PM
14 */
15
16CF_HDR
17
18#include "nest/bird.h"
b9d70dc8
PM
19#include "lib/resource.h"
20#include "lib/socket.h"
21#include "lib/timer.h"
22#include "nest/protocol.h"
23#include "nest/iface.h"
24#include "nest/route.h"
cb8034f4 25#include <string.h>
b9d70dc8
PM
26
27CF_DECLS
28
d3dd620b 29CF_KEYWORDS(FUNCTION, PRINT, PRINTN, CONST,
ba921648
PM
30 ACCEPT, REJECT, ERROR, QUITBIRD,
31 INT, BOOL, IP, PREFIX, PAIR, SET, STRING,
7db7b7db 32 IF, THEN, ELSE, CASE,
23b1539b 33 TRUE, FALSE,
346a12c2 34 RTA, FROM, GW, NET, MASK, RIP_METRIC, RIP_TAG, SOURCE,
36bbfc70 35 LEN,
f4536657 36 DEFINED,
36bbfc70 37 IMPOSSIBLE,
fd54b602 38 FILTER)
b9d70dc8 39
f4536657 40%nonassoc THEN
4ed8718a 41%nonassoc ELSE
f4536657 42
4515bdba 43%type <x> term block cmds cmd function_body constant print_one print_list var_list var_listn any_dynamic
e0f2e42f 44%type <f> filter filter_body
4515bdba 45%type <i> type break_command pair
41be4444 46%type <e> set_item set_items switch_body
d3dd620b 47%type <v> set_atom prefix prefix_s ipa
6dc7a0cb 48%type <s> decls declsn one_decl function_params
b9d70dc8
PM
49
50CF_GRAMMAR
51
e0f2e42f
MM
52CF_ADDTO(conf, filter_def)
53filter_def:
cb8034f4 54 FILTER SYM { cf_push_scope( $2 ); } filter_body {
ae3e1af2
PM
55 cf_define_symbol($2, SYM_FILTER, $4);
56 $4->name = $2->name;
57 printf( "We have new filter defined (%s)\n", $2->name );
58 cf_pop_scope();
b9d70dc8
PM
59 }
60 ;
61
ba921648
PM
62type:
63 INT { $$ = T_INT; }
64 | BOOL { $$ = T_BOOL; }
65 | IP { $$ = T_IP; }
66 | PREFIX { $$ = T_PREFIX; }
67 | PAIR { $$ = T_PAIR; }
68 | STRING { $$ = T_STRING; }
69 | type SET {
70 switch ($1) {
71 default:
72 cf_error( "You can not create sets of this type\n" );
73 case T_INT: case T_IP: case T_PREFIX: case T_PAIR:
74 }
75 $$ = $1 | T_SET;
76 }
77 ;
78
6dc7a0cb
PM
79one_decl:
80 type SYM {
4107df1d 81 cf_define_symbol($2, SYM_VARIABLE | $1, NULL);
ba921648 82 printf( "New variable %s type %x\n", $2->name, $1 );
cb8034f4 83 $2->aux = 0;
d3dd620b
PM
84 {
85 struct f_val * val;
86 val = cfg_alloc(sizeof(struct f_val));
87 val->type = $1;
88 $2->aux2 = val;
89 }
6542ece9 90 $$=$2;
ba921648
PM
91 }
92 ;
93
6dc7a0cb
PM
94/* Decls with ';' at the end */
95decls: /* EMPTY */ { $$ = NULL; }
96 | one_decl ';' decls {
97 $$ = $1;
cb8034f4 98 $$->aux = (int) $3;
6dc7a0cb
PM
99 }
100 ;
101
3c989eb4 102/* Declarations that have no ';' at the end. */
6dc7a0cb
PM
103declsn: one_decl { $$ = $1; }
104 | declsn ';' one_decl {
4515bdba
PM
105 $$ = $1;
106 $$->aux = (int) $3;
6dc7a0cb
PM
107 }
108 ;
109
110
e0f2e42f 111filter_body:
ba921648 112 function_body {
e0f2e42f
MM
113 struct filter *f = cfg_alloc(sizeof(struct filter));
114 f->name = NULL;
ba921648 115 f->root = $1;
e0f2e42f
MM
116 $$ = f;
117 }
118 ;
119
120filter:
121 SYM {
122 if ($1->class != SYM_FILTER) cf_error("No such filter");
123 $$ = $1->def;
124 }
125 | filter_body
126 ;
127
ba921648 128function_params:
6dc7a0cb
PM
129 '(' declsn ')' { printf( "Have function parameters\n" ); $$=$2; }
130 | '(' ')' { $$=NULL; }
ba921648 131 ;
b9d70dc8 132
ba921648
PM
133function_body:
134 decls '{' cmds '}' {
135 $$ = $3;
84c7e194 136 }
ba921648
PM
137 ;
138
139CF_ADDTO(conf, function_def)
140function_def:
cb8034f4 141 FUNCTION SYM { printf( "Begining of function %s\n", $2->name ); cf_push_scope($2); } function_params function_body {
ba921648 142 extern struct f_inst *startup_func;
ae3e1af2 143 cf_define_symbol($2, SYM_FUNCTION, $5);
ba921648 144 if (!strcasecmp($2->name, "startup"))
ae3e1af2 145 startup_func = $5;
cb8034f4 146 $2->aux = (int) $4;
ae3e1af2 147 $2->aux2 = $5;
ba921648 148 printf("Hmm, we've got one function here - %s\n", $2->name);
ae3e1af2 149 cf_pop_scope();
ba921648
PM
150 }
151 ;
152
153/* Programs */
154
155cmds: /* EMPTY */ { $$ = NULL; }
156 | cmd cmds {
84c7e194 157 if ($1) {
7db7b7db
PM
158 if ($1->next)
159 bug("Command has next already set\n");
ba921648 160 $1->next = $2;
84c7e194 161 $$ = $1;
ba921648 162 } else $$ = $2;
84c7e194
PM
163 }
164 ;
165
2575593e 166block:
ba921648 167 cmd {
2575593e
PM
168 $$=$1;
169 }
170 | '{' cmds '}' {
171 $$=$2;
172 }
173 ;
174
d3dd620b
PM
175/*
176 * Simple types, their bison value is int
177 */
178pair:
179 '(' NUM ',' NUM ')' { $$ = $2 << 16 | $4; }
180 ;
181
182/*
183 * Complex types, their bison value is struct f_val
184 */
185prefix_s:
186 IPA '/' NUM { $$.type = T_PREFIX; $$.val.px.ip = $1; $$.val.px.len = $3; printf( "ook, we have prefix here\n" ); }
187 ;
188
189prefix:
190 prefix_s { $$ = $1; }
191 | prefix_s '+' { $$ = $1; $$.val.px.len |= LEN_PLUS; }
192 | prefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; }
6dc7a0cb 193 | prefix_s '{' NUM ',' NUM '}' { $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8); }
d3dd620b
PM
194 ;
195
196ipa:
6dc7a0cb 197 IPA { $$.type = T_IP; $$.val.px.ip = $1; }
d3dd620b
PM
198 ;
199
38506f71 200set_atom:
d3dd620b
PM
201 NUM { $$.type = T_INT; $$.val.i = $1; }
202 | pair { $$.type = T_PAIR; $$.val.i = $1; }
203 | ipa { $$ = $1; }
204 | prefix { $$ = $1; }
38506f71
PM
205 ;
206
207set_item:
208 set_atom { $$ = f_new_tree(); $$->from = $$->to = $1 }
209 | set_atom '.' '.' set_atom { $$ = f_new_tree(); $$->from = $1; $$->to = $4; }
210 ;
211
212set_items:
213 set_item { $$ = $1; }
214 | set_items ',' set_item { $$ = $3; $$->left = $1; }
215 ;
216
41be4444
PM
217switch_body: /* EMPTY */ { $$ = NULL; }
218 | set_item ':' cmds switch_body {
219 $$ = $1;
220 $$->data = $3;
221 $$->left = $4;
222 }
223 | ELSE ':' cmds {
224 $$ = f_new_tree();
225 $$->from.type = T_VOID;
226 $$->to.type = T_VOID;
227 $$->data = $3;
228 }
229 ;
d3dd620b 230
23b1539b 231constant:
2db3b288
PM
232 CONST '(' expr ')' { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_INT; $$->a2.i = $3; }
233 | NUM { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_INT; $$->a2.i = $1; }
234 | TRUE { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_BOOL; $$->a2.i = 1; }
235 | FALSE { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_BOOL; $$->a2.i = 0; }
38506f71 236 | TEXT { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_STRING; $$->a2.p = $1; }
d3dd620b
PM
237 | pair { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_PAIR; $$->a2.i = $1; }
238 | ipa { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
2f702671 239 | prefix_s {NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
38506f71 240 | '[' set_items ']' { printf( "We've got a set here..." ); $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_SET; $$->a2.p = build_tree($2); printf( "ook\n" ); }
fd54b602 241 | ENUM { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = $1 >> 16; $$->a2.i = $1 & 0xffff; }
23b1539b
PM
242 ;
243
f4536657
PM
244any_dynamic:
245 RIP_METRIC { $$ = f_new_inst(); $$->a1.i = T_INT; $$->a2.i = EA_RIP_METRIC;}
246 | RIP_TAG { $$ = f_new_inst(); $$->a1.i = T_INT; $$->a2.i = EA_RIP_TAG; }
247 ;
248
249
84c7e194 250term:
f4536657
PM
251 '(' term ')' { $$ = $2; }
252 | term '+' term { $$ = f_new_inst(); $$->code = '+'; $$->a1.p = $1; $$->a2.p = $3; }
2db3b288
PM
253 | term '=' term { $$ = f_new_inst(); $$->code = '=='; $$->a1.p = $1; $$->a2.p = $3; }
254 | term '!' '=' term { $$ = f_new_inst(); $$->code = '!='; $$->a1.p = $1; $$->a2.p = $4; }
255 | term '<' term { $$ = f_new_inst(); $$->code = '<'; $$->a1.p = $1; $$->a2.p = $3; }
256 | term '<' '=' term { $$ = f_new_inst(); $$->code = '<='; $$->a1.p = $1; $$->a2.p = $4; }
257 | term '>' term { $$ = f_new_inst(); $$->code = '<'; $$->a1.p = $3; $$->a2.p = $1; }
258 | term '>' '=' term { $$ = f_new_inst(); $$->code = '<='; $$->a1.p = $4; $$->a2.p = $1; }
38506f71 259 | term '~' term { $$ = f_new_inst(); $$->code = '~'; $$->a1.p = $1; $$->a2.p = $3; }
f4536657 260 | DEFINED '(' term ')' { $$ = f_new_inst(); $$->code = 'de'; $$->a1.p = $3; }
23b1539b 261
1183b6b2 262 | constant { $$ = $1; }
2575593e
PM
263 | SYM {
264 $$ = f_new_inst();
265 switch ($1->class) {
ba921648 266 case SYM_VARIABLE | T_INT:
d3dd620b
PM
267 case SYM_VARIABLE | T_PAIR:
268 case SYM_VARIABLE | T_PREFIX:
269 case SYM_VARIABLE | T_IP:
270 $$->code = 'C';
271 $$->a1.p = $1->aux2;
2575593e
PM
272 break;
273 default:
1183b6b2 274 cf_error("Can not use this class of symbol (%s,%x) as variable.", $1->name, $1->class );
2575593e
PM
275 }
276 }
4515bdba 277
346a12c2 278 | RTA '.' FROM { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_IP; $$->a2.i = OFFSETOF(struct rta, from); }
36bbfc70 279
346a12c2
PM
280 | RTA '.' GW { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_IP; $$->a2.i = OFFSETOF(struct rta, gw); }
281 | RTA '.' NET { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_PREFIX; $$->a2.i = 0x12345678; }
282 | RTA '.' SOURCE { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_ENUM_RTS; $$->a2.i = OFFSETOF(struct rta, gw); }
6dc7a0cb 283
f4536657 284 | RTA '.' any_dynamic { $$ = $3; $$->code = 'ea'; }
36bbfc70
PM
285
286 | term '.' IP { $$ = f_new_inst(); $$->code = 'cp'; $$->a1.p = $1; $$->a2.i = T_IP; }
287 | term '.' LEN { $$ = f_new_inst(); $$->code = 'cp'; $$->a1.p = $1; $$->a2.i = T_INT; }
d3dd620b 288 | term '.' MASK '(' term ')' { $$ = f_new_inst(); $$->code = 'iM'; $$->a1.p = $1; $$->a2.p = $5; }
ba921648
PM
289 ;
290
291break_command:
292 QUITBIRD { $$ = F_QUITBIRD }
293 | ACCEPT { $$ = F_ACCEPT }
294 | REJECT { $$ = F_REJECT }
295 | ERROR { $$ = F_ERROR }
23b1539b 296 | PRINT { $$ = F_NOP }
d3dd620b 297 | PRINTN { $$ = F_NONL }
ba921648
PM
298 ;
299
23b1539b 300print_one:
2db3b288 301 term { $$ = f_new_inst(); $$->code = 'p'; $$->a1.p = $1; $$->a2.p = NULL; }
23b1539b
PM
302 ;
303
304print_list: /* EMPTY */ { $$ = NULL; }
305 | print_one print_list {
306 if ($1) {
307 $1->next = $2;
308 $$ = $1;
309 } else $$ = $2;
310 }
311 ;
312
6dc7a0cb 313var_listn: term {
d3dd620b
PM
314 $$ = f_new_inst();
315 $$->code = 's';
316 $$->a1.p = NULL;
317 $$->a2.p = $1;
318 $$->next = NULL;
319 }
6dc7a0cb 320 | term ',' var_listn {
6542ece9
PM
321 $$ = f_new_inst();
322 $$->code = 's';
323 $$->a1.p = NULL;
324 $$->a2.p = $1;
325 $$->next = $3;
326 }
327 ;
328
6dc7a0cb
PM
329var_list: /* EMPTY */ { $$ = NULL; }
330 | var_listn { $$ = $1; }
331 ;
332
23b1539b 333cmd:
49955645
MM
334 IF term THEN block {
335 $$ = f_new_inst();
336 $$->code = '?';
337 $$->a1.p = $2;
338 $$->a2.p = $4;
23b1539b 339 }
49955645
MM
340 | IF term THEN block ELSE block {
341 struct f_inst *i = f_new_inst();
342 i->code = '?';
343 i->a1.p = $2;
344 i->a2.p = $4;
23b1539b
PM
345 $$ = f_new_inst();
346 $$->code = '?';
49955645
MM
347 $$->a1.p = i;
348 $$->a2.p = $6;
23b1539b 349 }
ba921648 350 | SYM '=' term ';' {
84c7e194 351 $$ = f_new_inst();
b9d70dc8 352 printf( "Ook, we'll set value\n" );
ba921648
PM
353 if (($1->class & ~T_MASK) != SYM_VARIABLE)
354 cf_error( "You may only set variables, and this is %x.\n", $1->class );
23b1539b 355 $$->code = 's';
2db3b288
PM
356 $$->a1.p = $1;
357 $$->a2.p = $3;
b9d70dc8 358 }
2db3b288 359 | break_command print_list ';' { $$ = f_new_inst(); $$->code = 'p,'; $$->a1.p = $2; $$->a2.i = $1; }
6542ece9
PM
360 | SYM '(' var_list ')' ';' {
361 struct symbol *sym;
362 struct f_inst *inst = $3;
363 if ($1->class != SYM_FUNCTION)
364 cf_error("You can not call something which is not function. Really.");
365 printf("You are calling function %s\n", $1->name);
366 $$ = f_new_inst();
367 $$->code = 'ca';
368 $$->a1.p = inst;
369 $$->a2.p = $1->aux2;
cb8034f4 370 sym = (void *) $1->aux;
6542ece9
PM
371 while (sym || inst) {
372 if (!sym || !inst)
373 cf_error("wrong number of arguments for function %s.", $1->name);
374 printf( "You should pass parameter called %s\n", sym->name);
375 inst->a1.p = sym;
cb8034f4 376 sym = (void *) sym->aux;
6542ece9
PM
377 inst = inst->next;
378 }
379 }
7db7b7db
PM
380 | CASE term '{' switch_body '}' {
381 $$ = f_new_inst();
41be4444 382 $$->code = 'SW';
7db7b7db 383 $$->a1.p = $2;
41be4444 384 $$->a2.p = build_tree( $4 );
7db7b7db 385 }
b9d70dc8
PM
386 ;
387
388CF_END