iof-bird-daemon / conf / confbase.Y @ 04632fd7
History | View | Annotate | Download (5.16 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 "lib/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 f_inst *x; |
50 |
struct filter *f; |
51 |
struct f_tree *e; |
52 |
struct f_trie *trie; |
53 |
struct f_val v; |
54 |
struct f_path_mask *h; |
55 |
struct password_item *p; |
56 |
struct rt_show_data *ra; |
57 |
struct roa_show_data *ro; |
58 |
struct sym_show_data *sd; |
59 |
struct lsadb_show_data *ld; |
60 |
struct iface *iface; |
61 |
struct roa_table *rot; |
62 |
void *g; |
63 |
bird_clock_t time; |
64 |
struct f_prefix px; |
65 |
struct proto_spec ps; |
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 |
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 %I", $2); /* XXXX */ |
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_ip_: net_ip4_ | net_ip6_ ; |
202 |
|
203 |
net_: net_ip_ { $$ = cfg_alloc($1.length); net_copy($$, &($1)); } ; |
204 |
|
205 |
|
206 |
/* Networks - regular */ |
207 |
|
208 |
net_ip6: |
209 |
net_ip6_ |
210 |
| SYM { |
211 |
if (($1->class != (SYM_CONSTANT | T_NET)) || (SYM_VAL($1).net->type != NET_IP6)) |
212 |
cf_error("IPv6 network expected"); |
213 |
$$ = * SYM_VAL($1).net; |
214 |
} |
215 |
; |
216 |
|
217 |
net_ip: |
218 |
net_ip_ |
219 |
| SYM { |
220 |
if (($1->class != (SYM_CONSTANT | T_NET)) || !net_is_ip(SYM_VAL($1).net)) |
221 |
cf_error("IP network expected"); |
222 |
$$ = * SYM_VAL($1).net; |
223 |
} |
224 |
; |
225 |
|
226 |
net_any: |
227 |
net_ |
228 |
| SYM { |
229 |
if ($1->class != (SYM_CONSTANT | T_NET)) |
230 |
cf_error("Network expected"); |
231 |
$$ = (net_addr *) SYM_VAL($1).net; /* Avoid const warning */ |
232 |
} |
233 |
; |
234 |
|
235 |
net_or_ipa: |
236 |
net_ip4_ |
237 |
| net_ip6_ |
238 |
| IP4 { net_fill_ip4(&($$), $1, IP4_MAX_PREFIX_LENGTH); } |
239 |
| IP6 { net_fill_ip6(&($$), $1, IP6_MAX_PREFIX_LENGTH); } |
240 |
| SYM { |
241 |
if ($1->class == (SYM_CONSTANT | T_IP)) |
242 |
net_fill_ip_host(&($$), SYM_VAL($1).ip); |
243 |
else if (($1->class == (SYM_CONSTANT | T_NET)) && net_is_ip(SYM_VAL($1).net)) |
244 |
$$ = * SYM_VAL($1).net; |
245 |
else |
246 |
cf_error("IP address or network expected"); |
247 |
} |
248 |
; |
249 |
|
250 |
|
251 |
datetime: |
252 |
TEXT { |
253 |
$$ = tm_parse_datetime($1); |
254 |
if (!$$) |
255 |
cf_error("Invalid date and time"); |
256 |
} |
257 |
; |
258 |
|
259 |
text: |
260 |
TEXT |
261 |
| SYM { |
262 |
if ($1->class != (SYM_CONSTANT | T_STRING)) cf_error("String expected"); |
263 |
$$ = SYM_VAL($1).s; |
264 |
} |
265 |
; |
266 |
|
267 |
opttext: |
268 |
TEXT |
269 |
| /* empty */ { $$ = NULL; } |
270 |
; |
271 |
|
272 |
|
273 |
CF_CODE |
274 |
|
275 |
CF_END |