]> git.ipfire.org Git - thirdparty/bird.git/blob - conf/confbase.Y
Merge branch 'int-new' into int-new-merged
[thirdparty/bird.git] / conf / confbase.Y
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 ip_addr a;
42 ip4_addr ip4;
43 ip6_addr ip6;
44 net_addr net;
45 net_addr *net_ptr;
46 struct symbol *s;
47 char *t;
48 struct rtable_config *r;
49 struct channel_config *cc;
50 struct f_inst *x;
51 struct filter *f;
52 struct f_tree *e;
53 struct f_trie *trie;
54 struct f_val v;
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;
60 struct iface *iface;
61 void *g;
62 bird_clock_t time;
63 struct f_prefix px;
64 struct proto_spec ps;
65 struct channel_limit cl;
66 struct timeformat *tf;
67 }
68
69 %token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT
70 %token GEQ LEQ NEQ AND OR
71 %token PO PC
72 %token <i> NUM ENUM
73 %token <ip4> IP4
74 %token <ip6> IP6
75 %token <s> SYM
76 %token <t> TEXT
77 %type <iface> ipa_scope
78
79 %type <i> expr bool pxlen4
80 %type <i32> expr_us
81 %type <time> datetime
82 %type <a> ipa
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_
85
86 %type <t> text opttext
87
88 %nonassoc PREFIX_DUMMY
89 %left AND OR
90 %nonassoc '=' '<' '>' '~' GEQ LEQ NEQ PO PC
91 %left '+' '-'
92 %left '*' '/' '%'
93 %left '!'
94 %nonassoc '.'
95
96 CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT)
97
98 CF_GRAMMAR
99
100 /* Basic config file structure */
101
102 config: conf_entries END { return 0; }
103 | CLI_MARKER cli_cmd { return 0; }
104 ;
105
106 conf_entries:
107 /* EMPTY */
108 | conf_entries conf
109 ;
110
111 CF_ADDTO(conf, ';')
112
113
114 /* Constant expressions */
115
116 CF_ADDTO(conf, definition)
117 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);
123 }
124 ;
125
126 expr:
127 NUM
128 | '(' term ')' { $$ = f_eval_int($2); }
129 | SYM {
130 if ($1->class != (SYM_CONSTANT | T_INT)) cf_error("Number expected");
131 $$ = SYM_VAL($1).i; }
132 ;
133
134
135 expr_us:
136 expr S { $$ = (u32) $1 * 1000000; }
137 | expr MS { $$ = (u32) $1 * 1000; }
138 | expr US { $$ = (u32) $1 * 1; }
139 ;
140
141 /* expr_u16: expr { check_u16($1); $$ = $1; }; */
142
143 /* Switches */
144
145 bool:
146 expr {$$ = !!$1; }
147 | ON { $$ = 1; }
148 | YES { $$ = 1; }
149 | OFF { $$ = 0; }
150 | NO { $$ = 0; }
151 | /* Silence means agreement */ { $$ = 1; }
152 ;
153
154
155 /* Addresses */
156
157 ipa:
158 IP4 { $$ = ipa_from_ip4($1); }
159 | IP6 { $$ = ipa_from_ip6($1); }
160 | SYM {
161 if ($1->class != (SYM_CONSTANT | T_IP)) cf_error("IP address expected");
162 $$ = SYM_VAL($1).ip;
163 }
164 ;
165
166 ipa_scope:
167 /* empty */ { $$ = NULL; }
168 | '%' SYM { $$ = if_get_by_name($2->name); }
169 ;
170
171
172 /* Networks - internal */
173
174 pxlen4:
175 '/' NUM {
176 if ($2 < 0 || $2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2);
177 $$ = $2;
178 }
179 | ':' IP4 {
180 $$ = ip4_masklen($2);
181 if ($$ == 255) cf_error("Invalid netmask %I4", $2);
182 }
183 ;
184
185 net_ip4_: IP4 pxlen4
186 {
187 net_fill_ip4(&($$), $1, $2);
188 if (!net_validate_ip4((net_addr_ip4 *) &($$)))
189 cf_error("Invalid IPv4 prefix");
190 };
191
192 net_ip6_: IP6 '/' NUM
193 {
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");
199 };
200
201 net_roa4_: net_ip4_ MAX NUM AS NUM
202 {
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);
209 };
210
211 net_roa6_: net_ip6_ MAX NUM AS NUM
212 {
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);
219 };
220
221 net_ip_: net_ip4_ | net_ip6_ ;
222 net_roa_: net_roa4_ | net_roa6_ ;
223
224 net_:
225 net_ip_ { $$ = cfg_alloc($1.length); net_copy($$, &($1)); }
226 | net_roa_
227 ;
228
229
230 /* Networks - regular */
231
232 net_ip6:
233 net_ip6_
234 | SYM {
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;
238 }
239 ;
240
241 net_ip:
242 net_ip_
243 | SYM {
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;
247 }
248 ;
249
250 net_any:
251 net_
252 | SYM {
253 if ($1->class != (SYM_CONSTANT | T_NET))
254 cf_error("Network expected");
255 $$ = (net_addr *) SYM_VAL($1).net; /* Avoid const warning */
256 }
257 ;
258
259 net_or_ipa:
260 net_ip4_
261 | net_ip6_
262 | IP4 { net_fill_ip4(&($$), $1, IP4_MAX_PREFIX_LENGTH); }
263 | IP6 { net_fill_ip6(&($$), $1, IP6_MAX_PREFIX_LENGTH); }
264 | SYM {
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;
269 else
270 cf_error("IP address or network expected");
271 }
272 ;
273
274
275 datetime:
276 TEXT {
277 $$ = tm_parse_datetime($1);
278 if (!$$)
279 cf_error("Invalid date and time");
280 }
281 ;
282
283 text:
284 TEXT
285 | SYM {
286 if ($1->class != (SYM_CONSTANT | T_STRING)) cf_error("String expected");
287 $$ = SYM_VAL($1).s;
288 }
289 ;
290
291 opttext:
292 TEXT
293 | /* empty */ { $$ = NULL; }
294 ;
295
296
297 CF_CODE
298
299 CF_END