]> git.ipfire.org Git - thirdparty/bird.git/blame - filter/config.Y
Failure to set socket TOS is not a fatal error.
[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.
7 */
8
9CF_HDR
10
11#include "nest/bird.h"
b9d70dc8
PM
12#include "lib/resource.h"
13#include "lib/socket.h"
14#include "lib/timer.h"
15#include "nest/protocol.h"
16#include "nest/iface.h"
17#include "nest/route.h"
18
19CF_DECLS
20
38506f71 21CF_KEYWORDS(FUNCTION, PRINT, CONST,
ba921648
PM
22 ACCEPT, REJECT, ERROR, QUITBIRD,
23 INT, BOOL, IP, PREFIX, PAIR, SET, STRING,
7db7b7db 24 IF, THEN, ELSE, CASE,
23b1539b 25 TRUE, FALSE,
36bbfc70
PM
26 RTA, FROM, GW, NET,
27 LEN,
28 IMPOSSIBLE,
ba921648
PM
29 FILTER
30 )
b9d70dc8 31
7db7b7db 32%type <x> term block cmds cmd function_body ifthen constant print_one print_list var_list switch_body
e0f2e42f 33%type <f> filter filter_body
ba921648 34%type <i> type break_command
38506f71
PM
35%type <e> set_item set_items
36%type <v> set_atom
6542ece9 37%type <s> decls function_params
b9d70dc8
PM
38
39CF_GRAMMAR
40
e0f2e42f
MM
41CF_ADDTO(conf, filter_def)
42filter_def:
43 FILTER SYM filter_body {
4107df1d 44 cf_define_symbol($2, SYM_FILTER, $3);
e0f2e42f 45 $3->name = $2->name;
b9d70dc8
PM
46 printf( "We have new filter defined (%s)\n", $2->name )
47 }
48 ;
49
ba921648
PM
50type:
51 INT { $$ = T_INT; }
52 | BOOL { $$ = T_BOOL; }
53 | IP { $$ = T_IP; }
54 | PREFIX { $$ = T_PREFIX; }
55 | PAIR { $$ = T_PAIR; }
56 | STRING { $$ = T_STRING; }
57 | type SET {
58 switch ($1) {
59 default:
60 cf_error( "You can not create sets of this type\n" );
61 case T_INT: case T_IP: case T_PREFIX: case T_PAIR:
62 }
63 $$ = $1 | T_SET;
64 }
65 ;
66
6542ece9 67decls: /* EMPTY */ { $$ = NULL; }
ba921648 68 | type SYM ';' decls {
4107df1d 69 cf_define_symbol($2, SYM_VARIABLE | $1, NULL);
ba921648 70 printf( "New variable %s type %x\n", $2->name, $1 );
6542ece9
PM
71 $2->aux = $4;
72 $$=$2;
ba921648
PM
73 }
74 ;
75
e0f2e42f 76filter_body:
ba921648 77 function_body {
e0f2e42f
MM
78 struct filter *f = cfg_alloc(sizeof(struct filter));
79 f->name = NULL;
ba921648 80 f->root = $1;
e0f2e42f
MM
81 $$ = f;
82 }
83 ;
84
85filter:
86 SYM {
87 if ($1->class != SYM_FILTER) cf_error("No such filter");
88 $$ = $1->def;
89 }
90 | filter_body
91 ;
92
ba921648 93function_params:
6542ece9 94 '(' decls ')' { printf( "Have function parameters\n" ); $$=$2; }
ba921648 95 ;
b9d70dc8 96
ba921648
PM
97function_body:
98 decls '{' cmds '}' {
99 $$ = $3;
84c7e194 100 }
ba921648
PM
101 ;
102
103CF_ADDTO(conf, function_def)
104function_def:
105 FUNCTION SYM function_params function_body {
106 extern struct f_inst *startup_func;
4107df1d 107 cf_define_symbol($2, SYM_FUNCTION, $4);
ba921648
PM
108 if (!strcasecmp($2->name, "startup"))
109 startup_func = $4;
6542ece9
PM
110 $2->aux = $3;
111 $2->aux2 = $4;
ba921648
PM
112 printf("Hmm, we've got one function here - %s\n", $2->name);
113 }
114 ;
115
116/* Programs */
117
118cmds: /* EMPTY */ { $$ = NULL; }
119 | cmd cmds {
84c7e194 120 if ($1) {
7db7b7db
PM
121 if ($1->next)
122 bug("Command has next already set\n");
ba921648 123 $1->next = $2;
84c7e194 124 $$ = $1;
ba921648 125 } else $$ = $2;
84c7e194
PM
126 }
127 ;
128
2575593e 129block:
ba921648 130 cmd {
2575593e
PM
131 $$=$1;
132 }
133 | '{' cmds '}' {
134 $$=$2;
135 }
136 ;
137
38506f71
PM
138set_atom:
139 NUM { $$.type = T_INT; $$.val.i = $1; }
140 | IPA { $$.type = T_IP; $$.val.ip = $1; }
141 ;
142
143set_item:
144 set_atom { $$ = f_new_tree(); $$->from = $$->to = $1 }
145 | set_atom '.' '.' set_atom { $$ = f_new_tree(); $$->from = $1; $$->to = $4; }
146 ;
147
148set_items:
149 set_item { $$ = $1; }
150 | set_items ',' set_item { $$ = $3; $$->left = $1; }
151 ;
152
23b1539b 153constant:
2db3b288
PM
154 CONST '(' expr ')' { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_INT; $$->a2.i = $3; }
155 | NUM { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_INT; $$->a2.i = $1; }
156 | TRUE { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_BOOL; $$->a2.i = 1; }
157 | FALSE { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_BOOL; $$->a2.i = 0; }
38506f71
PM
158 | TEXT { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_STRING; $$->a2.p = $1; }
159 | IPA { struct f_val * val; val = cfg_alloc(sizeof(struct f_val)); $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; val->type = T_IP; val->val.ip = $1; }
160 | '[' 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" ); }
23b1539b
PM
161 ;
162
84c7e194 163term:
2db3b288 164 term '+' term { $$ = f_new_inst(); $$->code = '+'; $$->a1.p = $1; $$->a2.p = $3; }
2db3b288
PM
165 | term '=' term { $$ = f_new_inst(); $$->code = '=='; $$->a1.p = $1; $$->a2.p = $3; }
166 | term '!' '=' term { $$ = f_new_inst(); $$->code = '!='; $$->a1.p = $1; $$->a2.p = $4; }
167 | term '<' term { $$ = f_new_inst(); $$->code = '<'; $$->a1.p = $1; $$->a2.p = $3; }
168 | term '<' '=' term { $$ = f_new_inst(); $$->code = '<='; $$->a1.p = $1; $$->a2.p = $4; }
169 | term '>' term { $$ = f_new_inst(); $$->code = '<'; $$->a1.p = $3; $$->a2.p = $1; }
170 | term '>' '=' term { $$ = f_new_inst(); $$->code = '<='; $$->a1.p = $4; $$->a2.p = $1; }
38506f71 171 | term '~' term { $$ = f_new_inst(); $$->code = '~'; $$->a1.p = $1; $$->a2.p = $3; }
23b1539b 172
2575593e
PM
173 | SYM {
174 $$ = f_new_inst();
175 switch ($1->class) {
ba921648 176 case SYM_VARIABLE | T_INT:
2575593e 177 $$->code = 'i';
2db3b288
PM
178 $$->a1.i = T_INT;
179 $$->a2.p = &($1->aux);
2575593e
PM
180 break;
181 default:
6542ece9 182 cf_error("Can not use this class of symbol as variable." );
2575593e
PM
183 }
184 }
23b1539b 185 | constant { $$ = $1; }
36bbfc70
PM
186 | RTA '.' FROM { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_IP; $$->a2.i = OFFSETOF(struct rta, from); }
187
188 | RTA '.' GW { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_IP; $$->a2.i = OFFSETOF(struct rta, gw); }
189 | RTA '.' NET { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_PREFIX; $$->a2.i = 0x12345678; }
190
191 | term '.' IP { $$ = f_new_inst(); $$->code = 'cp'; $$->a1.p = $1; $$->a2.i = T_IP; }
192 | term '.' LEN { $$ = f_new_inst(); $$->code = 'cp'; $$->a1.p = $1; $$->a2.i = T_INT; }
ba921648
PM
193 ;
194
195break_command:
196 QUITBIRD { $$ = F_QUITBIRD }
197 | ACCEPT { $$ = F_ACCEPT }
198 | REJECT { $$ = F_REJECT }
199 | ERROR { $$ = F_ERROR }
23b1539b 200 | PRINT { $$ = F_NOP }
ba921648
PM
201 ;
202
23b1539b 203ifthen:
ba921648 204 IF term THEN block {
b7005824 205 $$ = f_new_inst();
ba921648 206 $$->code = '?';
2db3b288
PM
207 $$->a1.p = $2;
208 $$->a2.p = $4;
b7005824 209 }
23b1539b
PM
210 ;
211
212print_one:
2db3b288 213 term { $$ = f_new_inst(); $$->code = 'p'; $$->a1.p = $1; $$->a2.p = NULL; }
23b1539b
PM
214 ;
215
216print_list: /* EMPTY */ { $$ = NULL; }
217 | print_one print_list {
218 if ($1) {
219 $1->next = $2;
220 $$ = $1;
221 } else $$ = $2;
222 }
223 ;
224
6542ece9
PM
225var_list: /* EMPTY */ { $$ = NULL; }
226 | term ',' var_list {
227 $$ = f_new_inst();
228 $$->code = 's';
229 $$->a1.p = NULL;
230 $$->a2.p = $1;
231 $$->next = $3;
232 }
233 ;
234
7db7b7db
PM
235switch_body: /* EMPTY */ { $$ = NULL; }
236 | term ':' block switch_body {
237 $$ = f_new_inst();
238 $$->code = 'of';
239 $$->a1.p = $1;
240 $$->a2.p = $3;
241 $$->next = $4;
242 }
243 | ELSE ':' block {
244 $$ = f_new_inst();
245 $$->code = 'el';
246 $$->a1.p = NULL;
247 $$->a2.p = $3;
248 }
249 ;
250
23b1539b
PM
251cmd:
252 ifthen {
253 $$ = $1;
254 }
255 /* FIXME: this leads to shift/reduce conflict. */
256 | ifthen ELSE block {
257 $$ = f_new_inst();
258 $$->code = '?';
2db3b288
PM
259 $$->a1.p = $1;
260 $$->a2.p = $3;
23b1539b 261 }
ba921648 262 | SYM '=' term ';' {
84c7e194 263 $$ = f_new_inst();
b9d70dc8 264 printf( "Ook, we'll set value\n" );
ba921648
PM
265 if (($1->class & ~T_MASK) != SYM_VARIABLE)
266 cf_error( "You may only set variables, and this is %x.\n", $1->class );
23b1539b 267 $$->code = 's';
2db3b288
PM
268 $$->a1.p = $1;
269 $$->a2.p = $3;
b9d70dc8 270 }
2db3b288 271 | break_command print_list ';' { $$ = f_new_inst(); $$->code = 'p,'; $$->a1.p = $2; $$->a2.i = $1; }
6542ece9
PM
272 | SYM '(' var_list ')' ';' {
273 struct symbol *sym;
274 struct f_inst *inst = $3;
275 if ($1->class != SYM_FUNCTION)
276 cf_error("You can not call something which is not function. Really.");
277 printf("You are calling function %s\n", $1->name);
278 $$ = f_new_inst();
279 $$->code = 'ca';
280 $$->a1.p = inst;
281 $$->a2.p = $1->aux2;
282 sym = $1->aux;
283 while (sym || inst) {
284 if (!sym || !inst)
285 cf_error("wrong number of arguments for function %s.", $1->name);
286 printf( "You should pass parameter called %s\n", sym->name);
287 inst->a1.p = sym;
288 sym = sym->aux;
289 inst = inst->next;
290 }
291 }
7db7b7db
PM
292 | CASE term '{' switch_body '}' {
293 $$ = f_new_inst();
294 $$->code = 'sw';
295 $$->a1.p = $2;
296 $$->a2.p = $4;
297 }
b9d70dc8
PM
298 ;
299
300CF_END