iof-bird-daemon / conf / confbase.Y @ 62e64905
History | View | Annotate | Download (6.49 KB)
1 |
/* |
---|---|
2 |
* BIRD -- Configuration Parser Top |
3 |
* |
4 |
* (c) 1998--2000 Martin Mares <mj@ucw.cz> |
5 |
* |
6 |
* Can be freely distributed and used under the terms of the GNU GPL. |
7 |
*/ |
8 |
|
9 |
CF_HDR |
10 |
|
11 |
#define PARSER 1 |
12 |
|
13 |
#include "nest/bird.h" |
14 |
#include "conf/conf.h" |
15 |
#include "lib/resource.h" |
16 |
#include "lib/socket.h" |
17 |
#include "sysdep/unix/timer.h" |
18 |
#include "lib/string.h" |
19 |
#include "nest/protocol.h" |
20 |
#include "nest/iface.h" |
21 |
#include "nest/route.h" |
22 |
#include "nest/cli.h" |
23 |
#include "filter/filter.h" |
24 |
|
25 |
/* FIXME: Turn on YYERROR_VERBOSE and work around lots of bison bugs? */ |
26 |
|
27 |
CF_DEFINES |
28 |
|
29 |
static void |
30 |
check_u16(unsigned val) |
31 |
{ |
32 |
if (val > 0xFFFF) |
33 |
cf_error("Value %d out of range (0-65535)", val); |
34 |
} |
35 |
|
36 |
CF_DECLS |
37 |
|
38 |
%union { |
39 |
int i; |
40 |
u32 i32; |
41 |
u64 i64; |
42 |
ip_addr a; |
43 |
ip4_addr ip4; |
44 |
ip6_addr ip6; |
45 |
net_addr net; |
46 |
net_addr *net_ptr; |
47 |
struct symbol *s; |
48 |
char *t; |
49 |
struct rtable_config *r; |
50 |
struct channel_config *cc; |
51 |
struct f_inst *x; |
52 |
struct filter *f; |
53 |
struct f_tree *e; |
54 |
struct f_trie *trie; |
55 |
struct f_val v; |
56 |
struct f_path_mask *h; |
57 |
struct password_item *p; |
58 |
struct rt_show_data *ra; |
59 |
struct sym_show_data *sd; |
60 |
struct lsadb_show_data *ld; |
61 |
struct iface *iface; |
62 |
void *g; |
63 |
bird_clock_t time; |
64 |
struct f_prefix px; |
65 |
struct proto_spec ps; |
66 |
struct channel_limit cl; |
67 |
struct timeformat *tf; |
68 |
u32 *lbl; |
69 |
} |
70 |
|
71 |
%token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT |
72 |
%token GEQ LEQ NEQ AND OR |
73 |
%token PO PC |
74 |
%token <i> NUM ENUM |
75 |
%token <ip4> IP4 |
76 |
%token <ip6> IP6 |
77 |
%token <i64> VPN_RD |
78 |
%token <s> SYM |
79 |
%token <t> TEXT |
80 |
%type <iface> ipa_scope |
81 |
|
82 |
%type <i> expr bool pxlen4 |
83 |
%type <i32> expr_us |
84 |
%type <time> datetime |
85 |
%type <a> ipa |
86 |
%type <net> net_ip4_ net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa |
87 |
%type <net_ptr> net_ net_any net_vpn4_ net_vpn6_ net_vpn_ net_roa4_ net_roa6_ net_roa_ |
88 |
%type <lbl> label_stack_start label_stack |
89 |
|
90 |
%type <t> text opttext |
91 |
|
92 |
%nonassoc PREFIX_DUMMY |
93 |
%left AND OR |
94 |
%nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA PO PC |
95 |
%left '+' '-' |
96 |
%left '*' '/' '%' |
97 |
%left '!' |
98 |
%nonassoc '.' |
99 |
|
100 |
CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, VPN) |
101 |
|
102 |
CF_GRAMMAR |
103 |
|
104 |
/* Basic config file structure */ |
105 |
|
106 |
config: conf_entries END { return 0; } |
107 |
| CLI_MARKER cli_cmd { return 0; } |
108 |
; |
109 |
|
110 |
conf_entries: |
111 |
/* EMPTY */ |
112 |
| conf_entries conf |
113 |
; |
114 |
|
115 |
CF_ADDTO(conf, ';') |
116 |
|
117 |
|
118 |
/* Constant expressions */ |
119 |
|
120 |
CF_ADDTO(conf, definition) |
121 |
definition: |
122 |
DEFINE SYM '=' term ';' { |
123 |
struct f_val *val = cfg_alloc(sizeof(struct f_val)); |
124 |
*val = f_eval($4, cfg_mem); |
125 |
if (val->type == T_RETURN) cf_error("Runtime error"); |
126 |
cf_define_symbol($2, SYM_CONSTANT | val->type, val); |
127 |
} |
128 |
; |
129 |
|
130 |
expr: |
131 |
NUM |
132 |
| '(' term ')' { $$ = f_eval_int($2); } |
133 |
| SYM { |
134 |
if ($1->class != (SYM_CONSTANT | T_INT)) cf_error("Number expected"); |
135 |
$$ = SYM_VAL($1).i; } |
136 |
; |
137 |
|
138 |
|
139 |
expr_us: |
140 |
expr S { $$ = (u32) $1 * 1000000; } |
141 |
| expr MS { $$ = (u32) $1 * 1000; } |
142 |
| expr US { $$ = (u32) $1 * 1; } |
143 |
; |
144 |
|
145 |
/* Switches */ |
146 |
|
147 |
bool: |
148 |
expr { $$ = !!$1; } |
149 |
| ON { $$ = 1; } |
150 |
| YES { $$ = 1; } |
151 |
| OFF { $$ = 0; } |
152 |
| NO { $$ = 0; } |
153 |
| /* Silence means agreement */ { $$ = 1; } |
154 |
; |
155 |
|
156 |
|
157 |
/* Addresses */ |
158 |
|
159 |
ipa: |
160 |
IP4 { $$ = ipa_from_ip4($1); } |
161 |
| IP6 { $$ = ipa_from_ip6($1); } |
162 |
| SYM { |
163 |
if ($1->class != (SYM_CONSTANT | T_IP)) cf_error("IP address expected"); |
164 |
$$ = SYM_VAL($1).ip; |
165 |
} |
166 |
; |
167 |
|
168 |
ipa_scope: |
169 |
/* empty */ { $$ = NULL; } |
170 |
| '%' SYM { $$ = if_get_by_name($2->name); } |
171 |
; |
172 |
|
173 |
|
174 |
/* Networks - internal */ |
175 |
|
176 |
pxlen4: |
177 |
'/' NUM { |
178 |
if ($2 < 0 || $2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2); |
179 |
$$ = $2; |
180 |
} |
181 |
| ':' IP4 { |
182 |
$$ = ip4_masklen($2); |
183 |
if ($$ == 255) cf_error("Invalid netmask %I4", $2); |
184 |
} |
185 |
; |
186 |
|
187 |
net_ip4_: IP4 pxlen4 |
188 |
{ |
189 |
net_fill_ip4(&($$), $1, $2); |
190 |
if (!net_validate_ip4((net_addr_ip4 *) &($$))) |
191 |
cf_error("Invalid IPv4 prefix"); |
192 |
}; |
193 |
|
194 |
net_ip6_: IP6 '/' NUM |
195 |
{ |
196 |
net_fill_ip6(&($$), $1, $3); |
197 |
if ($3 < 0 || $3 > IP6_MAX_PREFIX_LENGTH) |
198 |
cf_error("Invalid prefix length %d", $3); |
199 |
if (!net_validate_ip6((net_addr_ip6 *) &($$))) |
200 |
cf_error("Invalid IPv6 prefix"); |
201 |
}; |
202 |
|
203 |
net_vpn4_: VPN_RD net_ip4_ |
204 |
{ |
205 |
$$ = cfg_alloc(sizeof(net_addr_vpn4)); |
206 |
net_fill_vpn4($$, net4_prefix(&$2), net4_pxlen(&$2), $1); |
207 |
} |
208 |
|
209 |
net_vpn6_: VPN_RD net_ip6_ |
210 |
{ |
211 |
$$ = cfg_alloc(sizeof(net_addr_vpn6)); |
212 |
net_fill_vpn6($$, net6_prefix(&$2), net6_pxlen(&$2), $1); |
213 |
} |
214 |
|
215 |
net_roa4_: net_ip4_ MAX NUM AS NUM |
216 |
{ |
217 |
$$ = cfg_alloc(sizeof(net_addr_roa4)); |
218 |
net_fill_roa4($$, net4_prefix(&$1), net4_pxlen(&$1), $3, $5); |
219 |
if ($3 < (int) net4_pxlen(&$1) || $3 > IP4_MAX_PREFIX_LENGTH) |
220 |
cf_error("Invalid max prefix length %d", $3); |
221 |
}; |
222 |
|
223 |
net_roa6_: net_ip6_ MAX NUM AS NUM |
224 |
{ |
225 |
$$ = cfg_alloc(sizeof(net_addr_roa6)); |
226 |
net_fill_roa6($$, net6_prefix(&$1), net6_pxlen(&$1), $3, $5); |
227 |
if ($3 < (int) net6_pxlen(&$1) || $3 > IP6_MAX_PREFIX_LENGTH) |
228 |
cf_error("Invalid max prefix length %d", $3); |
229 |
}; |
230 |
|
231 |
net_ip_: net_ip4_ | net_ip6_ ; |
232 |
net_vpn_: net_vpn4_ | net_vpn6_ ; |
233 |
net_roa_: net_roa4_ | net_roa6_ ; |
234 |
|
235 |
net_: |
236 |
net_ip_ { $$ = cfg_alloc($1.length); net_copy($$, &($1)); } |
237 |
| net_vpn_ |
238 |
| net_roa_ |
239 |
| net_flow_ |
240 |
; |
241 |
|
242 |
|
243 |
/* Networks - regular */ |
244 |
|
245 |
net_ip6: |
246 |
net_ip6_ |
247 |
| SYM { |
248 |
if (($1->class != (SYM_CONSTANT | T_NET)) || (SYM_VAL($1).net->type != NET_IP6)) |
249 |
cf_error("IPv6 network expected"); |
250 |
$$ = * SYM_VAL($1).net; |
251 |
} |
252 |
; |
253 |
|
254 |
net_ip: |
255 |
net_ip_ |
256 |
| SYM { |
257 |
if (($1->class != (SYM_CONSTANT | T_NET)) || !net_is_ip(SYM_VAL($1).net)) |
258 |
cf_error("IP network expected"); |
259 |
$$ = * SYM_VAL($1).net; |
260 |
} |
261 |
; |
262 |
|
263 |
net_any: |
264 |
net_ |
265 |
| SYM { |
266 |
if ($1->class != (SYM_CONSTANT | T_NET)) |
267 |
cf_error("Network expected"); |
268 |
$$ = (net_addr *) SYM_VAL($1).net; /* Avoid const warning */ |
269 |
} |
270 |
; |
271 |
|
272 |
net_or_ipa: |
273 |
net_ip4_ |
274 |
| net_ip6_ |
275 |
| net_vpn4_ { $$ = *$1; } |
276 |
| net_vpn6_ { $$ = *$1; } |
277 |
| IP4 { net_fill_ip4(&($$), $1, IP4_MAX_PREFIX_LENGTH); } |
278 |
| IP6 { net_fill_ip6(&($$), $1, IP6_MAX_PREFIX_LENGTH); } |
279 |
| SYM { |
280 |
if ($1->class == (SYM_CONSTANT | T_IP)) |
281 |
net_fill_ip_host(&($$), SYM_VAL($1).ip); |
282 |
else if (($1->class == (SYM_CONSTANT | T_NET)) && net_is_ip(SYM_VAL($1).net)) |
283 |
$$ = * SYM_VAL($1).net; |
284 |
else |
285 |
cf_error("IP address or network expected"); |
286 |
} |
287 |
; |
288 |
|
289 |
label_stack_start: NUM |
290 |
{ |
291 |
$$ = cfg_allocz(sizeof(u32) * (MPLS_MAX_LABEL_STACK+1)); |
292 |
$$[0] = 1; |
293 |
$$[1] = $1; |
294 |
}; |
295 |
|
296 |
label_stack: |
297 |
label_stack_start |
298 |
| label_stack '/' NUM { |
299 |
if ($1[0] >= MPLS_MAX_LABEL_STACK) |
300 |
cf_error("Too many labels in stack"); |
301 |
$1[0]++; |
302 |
$1[*$1] = $3; |
303 |
$$ = $1; |
304 |
} |
305 |
; |
306 |
|
307 |
datetime: |
308 |
TEXT { |
309 |
$$ = tm_parse_datetime($1); |
310 |
if (!$$) |
311 |
cf_error("Invalid date and time"); |
312 |
} |
313 |
; |
314 |
|
315 |
text: |
316 |
TEXT |
317 |
| SYM { |
318 |
if ($1->class != (SYM_CONSTANT | T_STRING)) cf_error("String expected"); |
319 |
$$ = SYM_VAL($1).s; |
320 |
} |
321 |
; |
322 |
|
323 |
opttext: |
324 |
TEXT |
325 |
| /* empty */ { $$ = NULL; } |
326 |
; |
327 |
|
328 |
|
329 |
CF_CODE |
330 |
|
331 |
CF_END |