]>
Commit | Line | Data |
---|---|---|
f142750d MM |
1 | /* |
2 | * BIRD -- Configuration Parser Top | |
3 | * | |
aee539f2 | 4 | * (c) 1998--2000 Martin Mares <mj@ucw.cz> |
f142750d MM |
5 | * |
6 | * Can be freely distributed and used under the terms of the GNU GPL. | |
7 | */ | |
8 | ||
9 | CF_HDR | |
10 | ||
93e868c7 OZ |
11 | #define PARSER 1 |
12 | ||
f142750d MM |
13 | #include "nest/bird.h" |
14 | #include "conf/conf.h" | |
c74c0e3c MM |
15 | #include "lib/resource.h" |
16 | #include "lib/socket.h" | |
17 | #include "lib/timer.h" | |
221135d6 | 18 | #include "lib/string.h" |
c74c0e3c | 19 | #include "nest/protocol.h" |
50d8424a | 20 | #include "nest/iface.h" |
166b9c49 | 21 | #include "nest/route.h" |
bc2fb680 | 22 | #include "nest/cli.h" |
b9d70dc8 | 23 | #include "filter/filter.h" |
f142750d | 24 | |
f2c6c80a MM |
25 | /* FIXME: Turn on YYERROR_VERBOSE and work around lots of bison bugs? */ |
26 | ||
b8cc390e OZ |
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 | ||
f142750d MM |
36 | CF_DECLS |
37 | ||
38 | %union { | |
39 | int i; | |
dce26783 | 40 | u32 i32; |
f142750d MM |
41 | ip_addr a; |
42 | struct symbol *s; | |
43 | char *t; | |
0e02abfd | 44 | struct rtable_config *r; |
e0f2e42f | 45 | struct f_inst *x; |
5a14df39 MJM |
46 | struct f_dynamic_attr fda; |
47 | struct f_static_attr fsa; | |
e0f2e42f | 48 | struct filter *f; |
38506f71 | 49 | struct f_tree *e; |
b1a597e0 | 50 | struct f_trie *trie; |
38506f71 | 51 | struct f_val v; |
dcab7890 | 52 | struct f_path_mask *h; |
9d79fec8 | 53 | struct password_item *p; |
730f2e2c | 54 | struct rt_show_data *ra; |
af582c48 | 55 | struct roa_show_data *ro; |
0f808c06 | 56 | struct sym_show_data *sd; |
20ab192b | 57 | struct lsadb_show_data *ld; |
c0fc3e67 | 58 | struct mrt_dump_data *md; |
69a8259c | 59 | struct iface *iface; |
af582c48 | 60 | struct roa_table *rot; |
4ab5331c | 61 | void *g; |
aee539f2 | 62 | bird_clock_t time; |
758458be | 63 | struct prefix px; |
e304fd4b | 64 | struct proto_spec ps; |
c37e7851 | 65 | struct timeformat *tf; |
f142750d MM |
66 | } |
67 | ||
b8cc390e | 68 | %token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT |
5f4aee76 | 69 | %token GEQ LEQ NEQ AND OR |
cf186034 | 70 | %token PO PC |
944f008a | 71 | %token <i> NUM ENUM |
dce26783 | 72 | %token <i32> RTRID |
f142750d MM |
73 | %token <a> IPA |
74 | %token <s> SYM | |
75 | %token <t> TEXT | |
69a8259c | 76 | %type <iface> ipa_scope |
f142750d | 77 | |
a1beb8f3 | 78 | %type <i> expr bool pxlen |
6a8d3f1c | 79 | %type <i32> expr_us |
aee539f2 | 80 | %type <time> datetime |
e3f2d5fc | 81 | %type <a> ipa |
d3abfbc6 | 82 | %type <px> prefix prefix_or_ipa |
2d6d4b80 | 83 | %type <t> text opttext |
874b8685 | 84 | %type <t> text_or_none |
0b62c3a7 | 85 | |
60de3356 | 86 | %nonassoc PREFIX_DUMMY |
1960d203 | 87 | %left AND OR |
768d5e10 | 88 | %nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA PO PC |
1960d203 | 89 | %left '+' '-' |
0b62c3a7 | 90 | %left '*' '/' '%' |
23b1539b | 91 | %left '!' |
112d71a7 | 92 | %nonassoc '.' |
0b62c3a7 | 93 | |
dcde7ae5 | 94 | CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT) |
0b62c3a7 | 95 | |
f142750d MM |
96 | CF_GRAMMAR |
97 | ||
0b62c3a7 MM |
98 | /* Basic config file structure */ |
99 | ||
bc2fb680 | 100 | config: conf_entries END { return 0; } |
ffb59d24 | 101 | | CLI_MARKER cli_cmd { return 0; } |
f142750d MM |
102 | ; |
103 | ||
104 | conf_entries: | |
105 | /* EMPTY */ | |
7f400d1c | 106 | | conf_entries conf |
f142750d MM |
107 | ; |
108 | ||
7f400d1c | 109 | CF_ADDTO(conf, ';') |
f142750d | 110 | |
1103b32e | 111 | |
72380a34 | 112 | /* Constant expressions */ |
0b62c3a7 | 113 | |
1103b32e OZ |
114 | CF_ADDTO(conf, definition) |
115 | definition: | |
116 | DEFINE SYM '=' term ';' { | |
117 | struct f_val *val = cfg_alloc(sizeof(struct f_val)); | |
118 | *val = f_eval($4, cfg_mem); | |
119 | if (val->type == T_RETURN) cf_error("Runtime error"); | |
120 | cf_define_symbol($2, SYM_CONSTANT | val->type, val); | |
121 | } | |
122 | ; | |
123 | ||
c9b66706 | 124 | expr: |
0b62c3a7 | 125 | NUM |
cc590a11 | 126 | | '(' term ')' { $$ = f_eval_int($2); } |
1103b32e OZ |
127 | | SYM { |
128 | if ($1->class != (SYM_CONSTANT | T_INT)) cf_error("Number expected"); | |
129 | $$ = SYM_VAL($1).i; } | |
0b62c3a7 MM |
130 | ; |
131 | ||
6a8d3f1c | 132 | |
6a8d3f1c | 133 | expr_us: |
0e175f9f OZ |
134 | expr S { $$ = (u32) $1 * 1000000; } |
135 | | expr MS { $$ = (u32) $1 * 1000; } | |
136 | | expr US { $$ = (u32) $1 * 1; } | |
6a8d3f1c OZ |
137 | ; |
138 | ||
b8cc390e OZ |
139 | /* expr_u16: expr { check_u16($1); $$ = $1; }; */ |
140 | ||
166b9c49 MM |
141 | /* Switches */ |
142 | ||
143 | bool: | |
c8cafc8e | 144 | expr { $$ = !!$1; } |
166b9c49 MM |
145 | | ON { $$ = 1; } |
146 | | YES { $$ = 1; } | |
147 | | OFF { $$ = 0; } | |
148 | | NO { $$ = 0; } | |
149 | | /* Silence means agreement */ { $$ = 1; } | |
150 | ; | |
151 | ||
e3f2d5fc MM |
152 | /* Addresses, prefixes and netmasks */ |
153 | ||
154 | ipa: | |
155 | IPA | |
156 | | SYM { | |
1103b32e OZ |
157 | if ($1->class != (SYM_CONSTANT | T_IP)) cf_error("IP address expected"); |
158 | $$ = SYM_VAL($1).px.ip; | |
e3f2d5fc MM |
159 | } |
160 | ; | |
89d2355d | 161 | |
69a8259c OZ |
162 | ipa_scope: |
163 | /* empty */ { $$ = NULL; } | |
164 | | '%' SYM { $$ = if_get_by_name($2->name); } | |
165 | ; | |
166 | ||
758458be | 167 | prefix: |
e3f2d5fc | 168 | ipa pxlen { |
758458be MM |
169 | if (!ip_is_prefix($1, $2)) cf_error("Invalid prefix"); |
170 | $$.addr = $1; $$.len = $2; | |
171 | } | |
172 | ; | |
173 | ||
d3abfbc6 MM |
174 | prefix_or_ipa: |
175 | prefix | |
e3f2d5fc | 176 | | ipa { $$.addr = $1; $$.len = BITS_PER_IP_ADDRESS; } |
d3abfbc6 MM |
177 | ; |
178 | ||
89d2355d | 179 | pxlen: |
e3f2d5fc | 180 | '/' expr { |
6db8c5a6 | 181 | if ($2 < 0 || $2 > BITS_PER_IP_ADDRESS) cf_error("Invalid prefix length %d", $2); |
89d2355d MM |
182 | $$ = $2; |
183 | } | |
e3f2d5fc | 184 | | ':' ipa { |
88a183c6 | 185 | $$ = ipa_masklen($2); |
89d2355d MM |
186 | if ($$ < 0) cf_error("Invalid netmask %I", $2); |
187 | } | |
188 | ; | |
189 | ||
16c07e3d | 190 | datetime: |
aee539f2 | 191 | TEXT { |
0d3effcf | 192 | $$ = tm_parse_datetime($1); |
aee539f2 | 193 | if (!$$) |
0d3effcf | 194 | cf_error("Invalid date and time"); |
aee539f2 | 195 | } |
9d79fec8 PM |
196 | ; |
197 | ||
9eceab33 OZ |
198 | text: |
199 | TEXT | |
200 | | SYM { | |
201 | if ($1->class != (SYM_CONSTANT | T_STRING)) cf_error("String expected"); | |
202 | $$ = SYM_VAL($1).s; | |
203 | } | |
204 | ; | |
205 | ||
2d6d4b80 OZ |
206 | opttext: |
207 | TEXT | |
208 | | /* empty */ { $$ = NULL; } | |
209 | ; | |
210 | ||
874b8685 OZ |
211 | text_or_none: |
212 | TEXT { $$ = $1; } | |
213 | | { $$ = NULL; } | |
214 | ; | |
215 | ||
f142750d MM |
216 | CF_CODE |
217 | ||
218 | CF_END |