2 * BIRD -- Configuration Parser Top
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
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"
23 #include "filter/filter.h"
25 /* FIXME: Turn on YYERROR_VERBOSE and work around lots of bison bugs? */
30 check_u16(unsigned val)
33 cf_error("Value %d out of range (0-65535)", val);
48 struct rtable_config *r;
49 struct channel_config *cc;
55 struct f_path_mask *h;
56 struct password_item *p;
57 struct rt_show_data *ra;
58 struct sym_show_data *sd;
59 struct lsadb_show_data *ld;
65 struct channel_limit cl;
66 struct timeformat *tf;
69 %token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT
70 %token GEQ LEQ NEQ AND OR
77 %type <iface> ipa_scope
79 %type <i> expr bool pxlen4
83 %type <net> net_ip4_ net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa
84 %type <net_ptr> net_ net_any net_roa4_ net_roa6_ net_roa_
86 %type <t> text opttext
88 %nonassoc PREFIX_DUMMY
90 %nonassoc '=' '<' '>' '~' GEQ LEQ NEQ PO PC
96 CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT)
100 /* Basic config file structure */
102 config: conf_entries END { return 0; }
103 | CLI_MARKER cli_cmd { return 0; }
114 /* Constant expressions */
116 CF_ADDTO(conf, definition)
118 DEFINE SYM '=' term ';' {
119 struct f_val *val = cfg_alloc(sizeof(struct f_val));
120 *val = f_eval($4, cfg_mem);
121 if (val->type == T_RETURN) cf_error("Runtime error");
122 cf_define_symbol($2, SYM_CONSTANT | val->type, val);
128 | '(' term ')' { $$ = f_eval_int($2); }
130 if ($1->class != (SYM_CONSTANT | T_INT)) cf_error("Number expected");
131 $$ = SYM_VAL($1).i; }
136 expr S { $$ = (u32) $1 * 1000000; }
137 | expr MS { $$ = (u32) $1 * 1000; }
138 | expr US { $$ = (u32) $1 * 1; }
141 /* expr_u16: expr { check_u16($1); $$ = $1; }; */
151 | /* Silence means agreement */ { $$ = 1; }
158 IP4 { $$ = ipa_from_ip4($1); }
159 | IP6 { $$ = ipa_from_ip6($1); }
161 if ($1->class != (SYM_CONSTANT | T_IP)) cf_error("IP address expected");
167 /* empty */ { $$ = NULL; }
168 | '%' SYM { $$ = if_get_by_name($2->name); }
172 /* Networks - internal */
176 if ($2 < 0 || $2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2);
180 $$ = ip4_masklen($2);
181 if ($$ == 255) cf_error("Invalid netmask %I4", $2);
187 net_fill_ip4(&($$), $1, $2);
188 if (!net_validate_ip4((net_addr_ip4 *) &($$)))
189 cf_error("Invalid IPv4 prefix");
192 net_ip6_: IP6 '/' NUM
194 net_fill_ip6(&($$), $1, $3);
195 if ($3 < 0 || $3 > IP6_MAX_PREFIX_LENGTH)
196 cf_error("Invalid prefix length %d", $3);
197 if (!net_validate_ip6((net_addr_ip6 *) &($$)))
198 cf_error("Invalid IPv6 prefix");
201 net_roa4_: net_ip4_ MAX NUM AS NUM
203 $$ = cfg_alloc(sizeof(net_addr_roa4));
204 net_fill_roa4($$, ((net_addr_ip4 *)&$1)->prefix, $1.pxlen, $3, $5);
205 if ($3 < 0 || $3 > IP4_MAX_PREFIX_LENGTH)
206 cf_error("Invalid max prefix length %d", $3);
207 if (((net_addr_roa4 *) $$)->max_pxlen < ($$)->pxlen)
208 cf_error("Maximum prefix length %d must be >= prefix length %d", ((net_addr_roa4 *) $$)->max_pxlen, ($$)->pxlen);
211 net_roa6_: net_ip6_ MAX NUM AS NUM
213 $$ = cfg_alloc(sizeof(net_addr_roa6));
214 net_fill_roa6($$, ((net_addr_ip6 *)&$1)->prefix, $1.pxlen, $3, $5);
215 if ($3 < 0 || $3 > IP6_MAX_PREFIX_LENGTH)
216 cf_error("Invalid max prefix length %d", $3);
217 if (((net_addr_roa6 *) $$)->max_pxlen < ($$)->pxlen)
218 cf_error("Maximum prefix length %d must be >= prefix length %d", ((net_addr_roa6 *) $$)->max_pxlen, ($$)->pxlen);
221 net_ip_: net_ip4_ | net_ip6_ ;
222 net_roa_: net_roa4_ | net_roa6_ ;
225 net_ip_ { $$ = cfg_alloc($1.length); net_copy($$, &($1)); }
230 /* Networks - regular */
235 if (($1->class != (SYM_CONSTANT | T_NET)) || (SYM_VAL($1).net->type != NET_IP6))
236 cf_error("IPv6 network expected");
237 $$ = * SYM_VAL($1).net;
244 if (($1->class != (SYM_CONSTANT | T_NET)) || !net_is_ip(SYM_VAL($1).net))
245 cf_error("IP network expected");
246 $$ = * SYM_VAL($1).net;
253 if ($1->class != (SYM_CONSTANT | T_NET))
254 cf_error("Network expected");
255 $$ = (net_addr *) SYM_VAL($1).net; /* Avoid const warning */
262 | IP4 { net_fill_ip4(&($$), $1, IP4_MAX_PREFIX_LENGTH); }
263 | IP6 { net_fill_ip6(&($$), $1, IP6_MAX_PREFIX_LENGTH); }
265 if ($1->class == (SYM_CONSTANT | T_IP))
266 net_fill_ip_host(&($$), SYM_VAL($1).ip);
267 else if (($1->class == (SYM_CONSTANT | T_NET)) && net_is_ip(SYM_VAL($1).net))
268 $$ = * SYM_VAL($1).net;
270 cf_error("IP address or network expected");
277 $$ = tm_parse_datetime($1);
279 cf_error("Invalid date and time");
286 if ($1->class != (SYM_CONSTANT | T_STRING)) cf_error("String expected");
293 | /* empty */ { $$ = NULL; }