]>
Commit | Line | Data |
---|---|---|
da877822 MM |
1 | /* |
2 | * BIRD -- Core Configuration | |
3 | * | |
4b87e256 | 4 | * (c) 1998--2000 Martin Mares <mj@ucw.cz> |
da877822 MM |
5 | * |
6 | * Can be freely distributed and used under the terms of the GNU GPL. | |
7 | */ | |
8 | ||
9 | CF_HDR | |
10 | ||
50d8424a | 11 | #include "nest/rt-dev.h" |
1a2ded45 | 12 | #include "nest/password.h" |
4b87e256 | 13 | #include "nest/cmds.h" |
5236fb03 | 14 | #include "lib/lists.h" |
50d8424a | 15 | |
2edb31b0 MM |
16 | CF_DEFINES |
17 | ||
18 | static struct proto_config *this_proto; | |
19 | static struct iface_patt *this_ipatt; | |
5236fb03 OF |
20 | static list *this_p_list; |
21 | static struct password_item *this_p_item; | |
2edb31b0 | 22 | |
da877822 MM |
23 | CF_DECLS |
24 | ||
7e5f5ffd | 25 | CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT) |
96d8e3bf | 26 | CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS) |
6a9f28b0 | 27 | CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES) |
5236fb03 | 28 | CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREIMPORT, GENERATE) |
da877822 | 29 | |
7d509304 | 30 | CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT, |
98ac6176 | 31 | RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE) |
26c09e1d PM |
32 | CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE) |
33 | CF_ENUM(T_ENUM_RTC, RTC_, UNICAST, BROADCAST, MULTICAST, ANYCAST) | |
34 | CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT) | |
7d509304 | 35 | |
dce26783 | 36 | %type <i32> idval |
5056c559 | 37 | %type <f> imexport |
0e02abfd | 38 | %type <r> rtable |
5236fb03 | 39 | %type <p> password_list password_begin password_begin_list |
ae97b946 | 40 | %type <s> optsym |
730f2e2c | 41 | %type <ra> r_args |
ce1da96e | 42 | %type <i> echo_mask echo_size debug_mask debug_list debug_flag import_or_proto |
f14a4bec | 43 | %type <t> proto_patt |
da877822 MM |
44 | |
45 | CF_GRAMMAR | |
46 | ||
c74c0e3c MM |
47 | /* Setting of router ID */ |
48 | ||
da877822 | 49 | CF_ADDTO(conf, rtrid) |
0e02abfd | 50 | |
7f400d1c | 51 | rtrid: ROUTER ID idval ';' { |
31b3e1bb | 52 | new_config->router_id = $3; |
c74c0e3c | 53 | } |
da877822 MM |
54 | ; |
55 | ||
56 | idval: | |
dce26783 MM |
57 | NUM { $$ = $1; } |
58 | | RTRID | |
59 | | IPA { | |
60 | #ifndef IPV6 | |
61 | $$ = ipa_to_u32($1); | |
62 | #else | |
e79671a7 | 63 | cf_error("Router IDs must be entered as hexadecimal numbers or IPv4 addresses in IPv6 version"); |
dce26783 MM |
64 | #endif |
65 | } | |
da877822 MM |
66 | ; |
67 | ||
0e02abfd MM |
68 | /* Creation of routing tables */ |
69 | ||
70 | CF_ADDTO(conf, newtab) | |
71 | ||
72 | newtab: TABLE SYM { | |
b9626ec6 | 73 | rt_new_table($2); |
0e02abfd MM |
74 | } |
75 | ; | |
76 | ||
c74c0e3c MM |
77 | /* Definition of protocols */ |
78 | ||
79 | CF_ADDTO(conf, proto) | |
80 | ||
81 | proto_start: PROTOCOL | |
de10a974 | 82 | ; |
c74c0e3c MM |
83 | |
84 | proto_name: | |
85 | /* EMPTY */ { | |
d272fe22 | 86 | struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter); |
c74c0e3c MM |
87 | s->class = SYM_PROTO; |
88 | s->def = this_proto; | |
89 | this_proto->name = s->name; | |
90 | } | |
91 | | SYM { | |
0e02abfd | 92 | cf_define_symbol($1, SYM_PROTO, this_proto); |
c74c0e3c MM |
93 | this_proto->name = $1->name; |
94 | } | |
95 | ; | |
96 | ||
97 | proto_item: | |
98 | /* EMPTY */ | |
0b62c3a7 | 99 | | PREFERENCE expr { |
c74c0e3c MM |
100 | if ($2 < 0 || $2 > 255) cf_error("Invalid preference"); |
101 | this_proto->preference = $2; | |
102 | } | |
ca77641d | 103 | | DISABLED bool { this_proto->disabled = $2; } |
96d8e3bf | 104 | | DEBUG debug_mask { this_proto->debug = $2; } |
5056c559 MM |
105 | | IMPORT imexport { this_proto->in_filter = $2; } |
106 | | EXPORT imexport { this_proto->out_filter = $2; } | |
0e02abfd | 107 | | TABLE rtable { this_proto->table = $2; } |
5056c559 MM |
108 | ; |
109 | ||
110 | imexport: | |
111 | FILTER filter { $$ = $2; } | |
f8809249 | 112 | | where_filter |
5056c559 MM |
113 | | ALL { $$ = FILTER_ACCEPT; } |
114 | | NONE { $$ = FILTER_REJECT; } | |
c74c0e3c MM |
115 | ; |
116 | ||
0e02abfd MM |
117 | rtable: |
118 | SYM { | |
119 | if ($1->class != SYM_TABLE) cf_error("Table name expected"); | |
120 | $$ = $1->def; | |
121 | } | |
122 | ; | |
123 | ||
f30b86f9 MM |
124 | CF_ADDTO(conf, debug_default) |
125 | ||
126 | debug_default: | |
127 | DEBUG PROTOCOLS debug_mask { new_config->proto_default_debug = $3; } | |
4761efdb | 128 | | DEBUG COMMANDS expr { new_config->cli_debug = $3; } |
f30b86f9 MM |
129 | ; |
130 | ||
8edf2361 MM |
131 | /* Interface patterns */ |
132 | ||
133 | iface_patt: | |
134 | TEXT { this_ipatt->pattern = $1; this_ipatt->prefix = IPA_NONE; this_ipatt->pxlen = 0; } | |
758458be MM |
135 | | prefix { this_ipatt->pattern = NULL; this_ipatt->prefix = $1.addr; this_ipatt->pxlen = $1.len; } |
136 | | TEXT prefix { this_ipatt->pattern = $1; this_ipatt->prefix = $2.addr; this_ipatt->pxlen = $2.len; } | |
8edf2361 MM |
137 | ; |
138 | ||
7e5f5ffd | 139 | /* Direct device route protocol */ |
50d8424a MM |
140 | |
141 | CF_ADDTO(proto, dev_proto '}') | |
142 | ||
7e5f5ffd MM |
143 | dev_proto_start: proto_start DIRECT { |
144 | struct rt_dev_config *p = proto_config_new(&proto_device, sizeof(struct rt_dev_config)); | |
7e5f5ffd MM |
145 | this_proto = &p->c; |
146 | p->c.preference = DEF_PREF_DIRECT; | |
147 | init_list(&p->iface_list); | |
50d8424a MM |
148 | } |
149 | ; | |
150 | ||
151 | dev_proto: | |
7e5f5ffd | 152 | dev_proto_start proto_name '{' |
50d8424a MM |
153 | | dev_proto proto_item ';' |
154 | | dev_proto dev_iface_list ';' | |
155 | ; | |
156 | ||
8edf2361 MM |
157 | dev_iface_entry_init: |
158 | /* EMPTY */ { | |
159 | struct rt_dev_config *p = (void *) this_proto; | |
160 | struct iface_patt *k = cfg_allocz(sizeof(struct iface_patt)); | |
161 | add_tail(&p->iface_list, &k->n); | |
162 | this_ipatt = k; | |
50d8424a | 163 | } |
50d8424a MM |
164 | ; |
165 | ||
8edf2361 MM |
166 | dev_iface_entry: |
167 | dev_iface_entry_init iface_patt | |
168 | ; | |
169 | ||
170 | dev_iface_list: | |
171 | INTERFACE dev_iface_entry | |
172 | | dev_iface_list ',' dev_iface_entry | |
173 | ; | |
174 | ||
96d8e3bf MM |
175 | /* Debug flags */ |
176 | ||
177 | debug_mask: | |
178 | ALL { $$ = ~0; } | |
179 | | OFF { $$ = 0; } | |
180 | | '{' debug_list '}' { $$ = $2; } | |
181 | ; | |
182 | ||
183 | debug_list: | |
184 | debug_flag | |
185 | | debug_list ',' debug_flag { $$ = $1 | $3; } | |
186 | ; | |
187 | ||
188 | debug_flag: | |
189 | STATES { $$ = D_STATES; } | |
190 | | ROUTES { $$ = D_ROUTES; } | |
191 | | FILTERS { $$ = D_FILTERS; } | |
6a9f28b0 | 192 | | INTERFACES { $$ = D_IFACES; } |
96d8e3bf MM |
193 | | EVENTS { $$ = D_EVENTS; } |
194 | | PACKETS { $$ = D_PACKETS; } | |
195 | ; | |
196 | ||
8edf2361 MM |
197 | /* Password lists */ |
198 | ||
5236fb03 OF |
199 | password_items: |
200 | /* empty */ | |
201 | | password_item ';' password_items | |
202 | ; | |
203 | ||
204 | password_item: | |
205 | password_item_begin '{' password_item_params '}' | |
206 | | password_item_begin | |
207 | ; | |
208 | ||
209 | password_item_begin: | |
1a2ded45 | 210 | PASSWORD TEXT { |
5236fb03 OF |
211 | static int id = 0; |
212 | this_p_item = cfg_alloc(sizeof (struct password_item)); | |
213 | this_p_item->password = $2; | |
214 | this_p_item->genfrom = 0; | |
215 | this_p_item->gento = TIME_INFINITY; | |
216 | this_p_item->accfrom = 0; | |
217 | this_p_item->accto = TIME_INFINITY; | |
218 | this_p_item->id = id++; | |
219 | add_tail(this_p_list, &this_p_item->n); | |
1a2ded45 | 220 | } |
5236fb03 | 221 | ; |
1a2ded45 | 222 | |
5236fb03 | 223 | password_item_params: |
1a2ded45 | 224 | /* empty */ { } |
5236fb03 OF |
225 | | GENERATE FROM datetime ';' password_item_params { this_p_item->genfrom = $3; } |
226 | | GENERATE TO datetime ';' password_item_params { this_p_item->gento = $3; } | |
227 | | ACCEPT FROM datetime ';' password_item_params { this_p_item->accfrom = $3; } | |
228 | | ACCEPT TO datetime ';' password_item_params { this_p_item->accto = $3; } | |
229 | | ID expr ';' password_item_params { this_p_item->id = $2; } | |
1a2ded45 PM |
230 | ; |
231 | ||
5236fb03 OF |
232 | password_list: |
233 | password_begin_list '{' password_items '}' { | |
ac40c888 | 234 | $$ = $1; |
1a2ded45 | 235 | } |
5236fb03 OF |
236 | | password_begin |
237 | ; | |
238 | ||
239 | password_begin_list: | |
240 | PASSWORDS { | |
241 | this_p_list = cfg_alloc(sizeof(list)); | |
242 | init_list(this_p_list); | |
243 | $$ = this_p_list; | |
244 | } | |
245 | ; | |
246 | ||
247 | password_begin: | |
248 | PASSWORD TEXT { | |
249 | this_p_list = cfg_alloc(sizeof(list)); | |
250 | init_list(this_p_list); | |
251 | this_p_item = cfg_alloc(sizeof (struct password_item)); | |
252 | this_p_item->password = $2; | |
253 | this_p_item->genfrom = 0; | |
254 | this_p_item->gento = TIME_INFINITY; | |
255 | this_p_item->accfrom = 0; | |
256 | this_p_item->accto = TIME_INFINITY; | |
257 | this_p_item->id = 0; | |
258 | add_tail(this_p_list, &this_p_item->n); | |
259 | $$ = this_p_list; | |
260 | } | |
261 | ; | |
1a2ded45 | 262 | |
bc2fb680 | 263 | /* Core commands */ |
fae0396e | 264 | CF_CLI_HELP(SHOW, ..., [[Show status information]]) |
ae97b946 | 265 | |
4b87e256 | 266 | CF_CLI(SHOW STATUS,,, [[Show router status]]) |
de10a974 | 267 | { cmd_show_status(); } ; |
ae97b946 MM |
268 | |
269 | CF_CLI(SHOW PROTOCOLS, optsym, [<name>], [[Show routing protocols]]) | |
0d3e6bce MM |
270 | { proto_show($3, 0); } ; |
271 | ||
28e01f85 | 272 | CF_CLI(SHOW PROTOCOLS ALL, optsym, [<name>], [[Show routing protocol details]]) |
0d3e6bce | 273 | { proto_show($4, 1); } ; |
ae97b946 | 274 | |
730f2e2c MM |
275 | optsym: |
276 | SYM | |
277 | | /* empty */ { $$ = NULL; } | |
278 | ; | |
279 | ||
ae97b946 MM |
280 | CF_CLI(SHOW INTERFACES,,, [[Show network interfaces]]) |
281 | { if_show(); } ; | |
282 | ||
283 | CF_CLI(SHOW INTERFACES SUMMARY,,, [[Show summary of network interfaces]]) | |
284 | { if_show_summary(); } ; | |
285 | ||
49569a8b | 286 | CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>] [table <t>] [filter <f>|where <cond>] [all] [primary] [(import|protocol) <p>] [stats|count]]], [[Show routing table]]) |
730f2e2c MM |
287 | { rt_show($3); } ; |
288 | ||
289 | r_args: | |
290 | /* empty */ { | |
291 | $$ = cfg_allocz(sizeof(struct rt_show_data)); | |
292 | $$->pxlen = 256; | |
293 | $$->filter = FILTER_ACCEPT; | |
294 | $$->table = config->master_rtc->table; | |
295 | } | |
758458be | 296 | | r_args prefix { |
730f2e2c MM |
297 | $$ = $1; |
298 | if ($$->pxlen != 256) cf_error("Only one prefix expected"); | |
758458be MM |
299 | $$->prefix = $2.addr; |
300 | $$->pxlen = $2.len; | |
730f2e2c | 301 | } |
9449c91a MM |
302 | | r_args FOR prefix_or_ipa { |
303 | $$ = $1; | |
304 | if ($$->pxlen != 256) cf_error("Only one prefix expected"); | |
305 | $$->prefix = $3.addr; | |
306 | $$->pxlen = $3.len; | |
307 | $$->show_for = 1; | |
308 | } | |
730f2e2c MM |
309 | | r_args TABLE SYM { |
310 | $$ = $1; | |
311 | if ($3->class != SYM_TABLE) cf_error("%s is not a table", $3->name); | |
312 | $$->table = ((struct rtable_config *)$3->def)->table; | |
313 | } | |
314 | | r_args FILTER filter { | |
315 | $$ = $1; | |
430da60f | 316 | if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice"); |
730f2e2c MM |
317 | $$->filter = $3; |
318 | } | |
430da60f MM |
319 | | r_args where_filter { |
320 | $$ = $1; | |
321 | if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice"); | |
322 | $$->filter = $2; | |
323 | } | |
730f2e2c MM |
324 | | r_args ALL { |
325 | $$ = $1; | |
326 | $$->verbose = 1; | |
327 | } | |
ce1da96e MM |
328 | | r_args PRIMARY { |
329 | $$ = $1; | |
330 | $$->primary_only = 1; | |
331 | } | |
332 | | r_args import_or_proto SYM { | |
333 | struct proto_config *c = (struct proto_config *) $3->def; | |
334 | $$ = $1; | |
335 | if ($$->import_mode) cf_error("Protocol specified twice"); | |
336 | if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name); | |
337 | $$->import_mode = $2; | |
338 | $$->primary_only = 1; | |
339 | $$->import_protocol = c->proto; | |
340 | $$->running_on_config = c->proto->cf->global; | |
341 | } | |
23693958 MM |
342 | | r_args STATS { |
343 | $$ = $1; | |
344 | $$->stats = 1; | |
345 | } | |
33a368ad MM |
346 | | r_args COUNT { |
347 | $$ = $1; | |
348 | $$->stats = 2; | |
349 | } | |
ce1da96e MM |
350 | ; |
351 | ||
352 | import_or_proto: | |
c90ac711 OF |
353 | PREIMPORT { $$ = 1; } |
354 | | IMPORT { $$ = 2; } | |
730f2e2c MM |
355 | ; |
356 | ||
4b87e256 MM |
357 | CF_CLI(SHOW SYMBOLS, optsym, [<symbol>], [[Show all known symbolic names]]) |
358 | { cmd_show_symbols($3); } ; | |
359 | ||
96d8e3bf MM |
360 | CF_CLI_HELP(DUMP, ..., [[Dump debugging information]]) |
361 | CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]]) | |
34350a52 | 362 | { rdump(&root_pool); cli_msg(0, ""); } ; |
96d8e3bf | 363 | CF_CLI(DUMP SOCKETS,,, [[Dump open sockets]]) |
34350a52 | 364 | { sk_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 365 | CF_CLI(DUMP INTERFACES,,, [[Dump interface information]]) |
34350a52 | 366 | { if_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 367 | CF_CLI(DUMP NEIGHBORS,,, [[Dump neighbor cache]]) |
34350a52 | 368 | { neigh_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 369 | CF_CLI(DUMP ATTRIBUTES,,, [[Dump attribute cache]]) |
34350a52 | 370 | { rta_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 371 | CF_CLI(DUMP ROUTES,,, [[Dump routing table]]) |
34350a52 | 372 | { rt_dump_all(); cli_msg(0, ""); } ; |
96d8e3bf | 373 | CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]]) |
34350a52 MM |
374 | { protos_dump_all(); cli_msg(0, ""); } ; |
375 | ||
376 | CF_CLI(ECHO, echo_mask echo_size, [all | off | <mask>] [<buffer-size>], [[Configure echoing of log messages]]) { | |
377 | cli_set_log_echo(this_cli, $2, $3); | |
378 | cli_msg(0, ""); | |
379 | } ; | |
380 | ||
381 | echo_mask: | |
382 | ALL { $$ = ~0; } | |
383 | | OFF { $$ = 0; } | |
384 | | NUM | |
385 | ; | |
386 | ||
387 | echo_size: | |
388 | /* empty */ { $$ = 4096; } | |
389 | | NUM { | |
390 | if ($1 < 256 || $1 > 65536) cf_error("Invalid log buffer size"); | |
391 | $$ = $1; | |
392 | } | |
393 | ; | |
bc2fb680 | 394 | |
49569a8b | 395 | CF_CLI(DISABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Disable protocol]]) |
f14a4bec | 396 | { proto_xxable($2, 0); } ; |
49569a8b | 397 | CF_CLI(ENABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Enable protocol]]) |
f14a4bec | 398 | { proto_xxable($2, 1); } ; |
49569a8b | 399 | CF_CLI(RESTART, proto_patt, <protocol> | \"<pattern>\" | all, [[Restart protocol]]) |
f14a4bec MM |
400 | { proto_xxable($2, 2); } ; |
401 | ||
96d8e3bf MM |
402 | CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging]]) |
403 | CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | <pattern> | all) (all | off | { states | routes | filters | events | packets }), [[Control protocol debugging]]) | |
404 | { proto_debug($2, $3); } | |
de10a974 | 405 | ; |
96d8e3bf | 406 | |
f14a4bec MM |
407 | proto_patt: |
408 | SYM { $$ = $1->name; } | |
409 | | ALL { $$ = "*"; } | |
410 | | TEXT | |
411 | ; | |
412 | ||
da877822 MM |
413 | CF_CODE |
414 | ||
415 | CF_END |