]> git.ipfire.org Git - thirdparty/bird.git/blame - nest/config.Y
Core multipath support.
[thirdparty/bird.git] / nest / config.Y
CommitLineData
da877822
MM
1/*
2 * BIRD -- Core Configuration
3 *
4b87e256 4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
bc956fca 5 * (c) 2004 Ondrej Filip <feela@network.cz>
da877822
MM
6 *
7 * Can be freely distributed and used under the terms of the GNU GPL.
8 */
9
10CF_HDR
11
50d8424a 12#include "nest/rt-dev.h"
1a2ded45 13#include "nest/password.h"
4b87e256 14#include "nest/cmds.h"
5236fb03 15#include "lib/lists.h"
50d8424a 16
2edb31b0
MM
17CF_DEFINES
18
19static struct proto_config *this_proto;
20static struct iface_patt *this_ipatt;
20e94fb8 21static struct iface_patt_node *this_ipn;
5236fb03
OF
22static list *this_p_list;
23static struct password_item *this_p_item;
b21f68b4
OZ
24static int password_id;
25
024c310b
OZ
26static inline void
27reset_passwords(void)
28{
29 this_p_list = NULL;
30}
31
32static inline list *
b21f68b4
OZ
33get_passwords(void)
34{
35 list *rv = this_p_list;
36 this_p_list = NULL;
37 return rv;
38}
39
2edb31b0 40
da877822
MM
41CF_DECLS
42
7e5f5ffd 43CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
96d8e3bf 44CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
6a9f28b0 45CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
ea2ae6dd 46CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE)
fcf5a4f4 47CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION)
ba5e5940 48CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC)
da877822 49
7d509304 50CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
98ac6176 51 RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
26c09e1d
PM
52CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE)
53CF_ENUM(T_ENUM_RTC, RTC_, UNICAST, BROADCAST, MULTICAST, ANYCAST)
7e95c05d 54CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT, MULTIPATH)
7d509304 55
dce26783 56%type <i32> idval
5056c559 57%type <f> imexport
0e02abfd 58%type <r> rtable
ae97b946 59%type <s> optsym
730f2e2c 60%type <ra> r_args
cf31112f 61%type <i> echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_or_preexport
e304fd4b 62%type <ps> proto_patt proto_patt2
da877822
MM
63
64CF_GRAMMAR
65
c74c0e3c
MM
66/* Setting of router ID */
67
da877822 68CF_ADDTO(conf, rtrid)
0e02abfd 69
7f400d1c 70rtrid: ROUTER ID idval ';' {
31b3e1bb 71 new_config->router_id = $3;
c74c0e3c 72 }
da877822
MM
73 ;
74
75idval:
dce26783
MM
76 NUM { $$ = $1; }
77 | RTRID
78 | IPA {
79#ifndef IPV6
80 $$ = ipa_to_u32($1);
81#else
e79671a7 82 cf_error("Router IDs must be entered as hexadecimal numbers or IPv4 addresses in IPv6 version");
dce26783
MM
83#endif
84 }
da877822
MM
85 ;
86
789772ed 87
d72cdff4 88CF_ADDTO(conf, listen)
789772ed 89
d72cdff4 90listen: LISTEN BGP listen_opts ';' ;
789772ed 91
d72cdff4 92listen_opts:
789772ed 93 /* Nothing */
d72cdff4 94 | listen_opts listen_opt
789772ed
OZ
95 ;
96
d72cdff4
OZ
97listen_opt:
98 ADDRESS ipa { new_config->listen_bgp_addr = $2; }
99 | PORT expr { new_config->listen_bgp_port = $2; }
fcf5a4f4
OZ
100 | V6ONLY { new_config->listen_bgp_flags = 0; }
101 | DUAL { new_config->listen_bgp_flags = 1; }
789772ed
OZ
102 ;
103
104
0e02abfd
MM
105/* Creation of routing tables */
106
107CF_ADDTO(conf, newtab)
108
109newtab: TABLE SYM {
b9626ec6 110 rt_new_table($2);
0e02abfd
MM
111 }
112 ;
113
c74c0e3c
MM
114/* Definition of protocols */
115
116CF_ADDTO(conf, proto)
117
118proto_start: PROTOCOL
de10a974 119 ;
c74c0e3c
MM
120
121proto_name:
122 /* EMPTY */ {
d272fe22 123 struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
c74c0e3c
MM
124 s->class = SYM_PROTO;
125 s->def = this_proto;
126 this_proto->name = s->name;
127 }
128 | SYM {
0e02abfd 129 cf_define_symbol($1, SYM_PROTO, this_proto);
c74c0e3c
MM
130 this_proto->name = $1->name;
131 }
132 ;
133
134proto_item:
135 /* EMPTY */
0b62c3a7 136 | PREFERENCE expr {
f4c6ca8c 137 if ($2 < 0 || $2 > 0xFFFF) cf_error("Invalid preference");
c74c0e3c
MM
138 this_proto->preference = $2;
139 }
ca77641d 140 | DISABLED bool { this_proto->disabled = $2; }
96d8e3bf 141 | DEBUG debug_mask { this_proto->debug = $2; }
cf31112f 142 | MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; }
5056c559
MM
143 | IMPORT imexport { this_proto->in_filter = $2; }
144 | EXPORT imexport { this_proto->out_filter = $2; }
0e02abfd 145 | TABLE rtable { this_proto->table = $2; }
4cdd0784 146 | ROUTER ID idval { this_proto->router_id = $3; }
3f9b7bfe 147 | DESCRIPTION TEXT { this_proto->dsc = $2; }
5056c559
MM
148 ;
149
150imexport:
151 FILTER filter { $$ = $2; }
f8809249 152 | where_filter
5056c559
MM
153 | ALL { $$ = FILTER_ACCEPT; }
154 | NONE { $$ = FILTER_REJECT; }
c74c0e3c
MM
155 ;
156
0e02abfd
MM
157rtable:
158 SYM {
159 if ($1->class != SYM_TABLE) cf_error("Table name expected");
160 $$ = $1->def;
161 }
162 ;
163
f30b86f9
MM
164CF_ADDTO(conf, debug_default)
165
166debug_default:
167 DEBUG PROTOCOLS debug_mask { new_config->proto_default_debug = $3; }
4761efdb 168 | DEBUG COMMANDS expr { new_config->cli_debug = $3; }
f30b86f9
MM
169 ;
170
cf31112f
OZ
171/* MRTDUMP PROTOCOLS is in systep/unix/config.Y */
172
8edf2361
MM
173/* Interface patterns */
174
20e94fb8
OZ
175iface_patt_node_init:
176 /* EMPTY */ {
177 struct iface_patt_node *ipn = cfg_allocz(sizeof(struct iface_patt_node));
178 add_tail(&this_ipatt->ipn_list, NODE ipn);
179 this_ipn = ipn;
180 }
181 ;
182
183iface_patt_node_body:
184 TEXT { this_ipn->pattern = $1; this_ipn->prefix = IPA_NONE; this_ipn->pxlen = 0; }
5d53b807
OZ
185 | prefix_or_ipa { this_ipn->pattern = NULL; this_ipn->prefix = $1.addr; this_ipn->pxlen = $1.len; }
186 | TEXT prefix_or_ipa { this_ipn->pattern = $1; this_ipn->prefix = $2.addr; this_ipn->pxlen = $2.len; }
20e94fb8
OZ
187 ;
188
189iface_negate:
190 { this_ipn->positive = 1; }
191 | '-' { this_ipn->positive = 0; }
192 ;
193
194iface_patt_node:
195 iface_patt_node_init iface_negate iface_patt_node_body
196 ;
197
198
199iface_patt_list:
200 iface_patt_node
201 | iface_patt_list ',' iface_patt_node
8edf2361
MM
202 ;
203
20e94fb8 204
7e5f5ffd 205/* Direct device route protocol */
50d8424a
MM
206
207CF_ADDTO(proto, dev_proto '}')
208
7e5f5ffd
MM
209dev_proto_start: proto_start DIRECT {
210 struct rt_dev_config *p = proto_config_new(&proto_device, sizeof(struct rt_dev_config));
7e5f5ffd
MM
211 this_proto = &p->c;
212 p->c.preference = DEF_PREF_DIRECT;
213 init_list(&p->iface_list);
50d8424a
MM
214 }
215 ;
216
217dev_proto:
7e5f5ffd 218 dev_proto_start proto_name '{'
50d8424a 219 | dev_proto proto_item ';'
20e94fb8 220 | dev_proto dev_iface_patt ';'
50d8424a
MM
221 ;
222
20e94fb8 223dev_iface_init:
8edf2361
MM
224 /* EMPTY */ {
225 struct rt_dev_config *p = (void *) this_proto;
20e94fb8
OZ
226 this_ipatt = cfg_allocz(sizeof(struct iface_patt));
227 add_tail(&p->iface_list, NODE this_ipatt);
228 init_list(&this_ipatt->ipn_list);
50d8424a 229 }
50d8424a
MM
230 ;
231
20e94fb8
OZ
232dev_iface_patt:
233 INTERFACE dev_iface_init iface_patt_list
8edf2361
MM
234 ;
235
96d8e3bf
MM
236/* Debug flags */
237
238debug_mask:
239 ALL { $$ = ~0; }
240 | OFF { $$ = 0; }
241 | '{' debug_list '}' { $$ = $2; }
242 ;
243
244debug_list:
245 debug_flag
246 | debug_list ',' debug_flag { $$ = $1 | $3; }
247 ;
248
249debug_flag:
250 STATES { $$ = D_STATES; }
251 | ROUTES { $$ = D_ROUTES; }
252 | FILTERS { $$ = D_FILTERS; }
6a9f28b0 253 | INTERFACES { $$ = D_IFACES; }
96d8e3bf
MM
254 | EVENTS { $$ = D_EVENTS; }
255 | PACKETS { $$ = D_PACKETS; }
256 ;
257
cf31112f
OZ
258/* MRTDump flags */
259
260mrtdump_mask:
261 ALL { $$ = ~0; }
262 | OFF { $$ = 0; }
263 | '{' mrtdump_list '}' { $$ = $2; }
264 ;
265
266mrtdump_list:
267 mrtdump_flag
268 | mrtdump_list ',' mrtdump_flag { $$ = $1 | $3; }
269 ;
270
271mrtdump_flag:
272 STATES { $$ = MD_STATES; }
273 | MESSAGES { $$ = MD_MESSAGES; }
274 ;
275
8edf2361
MM
276/* Password lists */
277
b21f68b4
OZ
278password_list:
279 PASSWORDS '{' password_items '}'
280 | password_item
281;
282
5236fb03
OF
283password_items:
284 /* empty */
285 | password_item ';' password_items
286;
287
288password_item:
289 password_item_begin '{' password_item_params '}'
290 | password_item_begin
291;
292
293password_item_begin:
1a2ded45 294 PASSWORD TEXT {
b21f68b4
OZ
295 if (!this_p_list) {
296 this_p_list = cfg_alloc(sizeof(list));
297 init_list(this_p_list);
298 password_id = 1;
299 }
5236fb03
OF
300 this_p_item = cfg_alloc(sizeof (struct password_item));
301 this_p_item->password = $2;
302 this_p_item->genfrom = 0;
303 this_p_item->gento = TIME_INFINITY;
304 this_p_item->accfrom = 0;
305 this_p_item->accto = TIME_INFINITY;
b21f68b4 306 this_p_item->id = password_id++;
5236fb03 307 add_tail(this_p_list, &this_p_item->n);
1a2ded45 308 }
5236fb03 309;
1a2ded45 310
5236fb03 311password_item_params:
1a2ded45 312 /* empty */ { }
5236fb03
OF
313 | GENERATE FROM datetime ';' password_item_params { this_p_item->genfrom = $3; }
314 | GENERATE TO datetime ';' password_item_params { this_p_item->gento = $3; }
315 | ACCEPT FROM datetime ';' password_item_params { this_p_item->accfrom = $3; }
316 | ACCEPT TO datetime ';' password_item_params { this_p_item->accto = $3; }
bc956fca 317 | ID expr ';' password_item_params { this_p_item->id = $2; if ($2 <= 0) cf_error("Password ID has to be greated than zero."); }
1a2ded45
PM
318 ;
319
1a2ded45 320
87d7fd97 321
bc2fb680 322/* Core commands */
fae0396e 323CF_CLI_HELP(SHOW, ..., [[Show status information]])
ae97b946 324
4b87e256 325CF_CLI(SHOW STATUS,,, [[Show router status]])
de10a974 326{ cmd_show_status(); } ;
ae97b946 327
acb60628
OZ
328CF_CLI(SHOW MEMORY,,, [[Show memory usage]])
329{ cmd_show_memory(); } ;
330
e304fd4b 331CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
e0a45fb4 332{ proto_apply_cmd($3, proto_cmd_show, 0, 0); } ;
0d3e6bce 333
e304fd4b 334CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]])
e0a45fb4 335{ proto_apply_cmd($4, proto_cmd_show, 0, 1); } ;
ae97b946 336
730f2e2c
MM
337optsym:
338 SYM
339 | /* empty */ { $$ = NULL; }
340 ;
341
ae97b946
MM
342CF_CLI(SHOW INTERFACES,,, [[Show network interfaces]])
343{ if_show(); } ;
344
345CF_CLI(SHOW INTERFACES SUMMARY,,, [[Show summary of network interfaces]])
346{ if_show_summary(); } ;
347
ea2ae6dd 348CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>] [table <t>] [filter <f>|where <cond>] [all] [primary] [(export|preexport) <p>] [protocol <p>] [stats|count]]], [[Show routing table]])
730f2e2c
MM
349{ rt_show($3); } ;
350
351r_args:
352 /* empty */ {
353 $$ = cfg_allocz(sizeof(struct rt_show_data));
354 $$->pxlen = 256;
355 $$->filter = FILTER_ACCEPT;
356 $$->table = config->master_rtc->table;
357 }
758458be 358 | r_args prefix {
730f2e2c
MM
359 $$ = $1;
360 if ($$->pxlen != 256) cf_error("Only one prefix expected");
758458be
MM
361 $$->prefix = $2.addr;
362 $$->pxlen = $2.len;
730f2e2c 363 }
9449c91a
MM
364 | r_args FOR prefix_or_ipa {
365 $$ = $1;
366 if ($$->pxlen != 256) cf_error("Only one prefix expected");
367 $$->prefix = $3.addr;
368 $$->pxlen = $3.len;
369 $$->show_for = 1;
370 }
730f2e2c
MM
371 | r_args TABLE SYM {
372 $$ = $1;
373 if ($3->class != SYM_TABLE) cf_error("%s is not a table", $3->name);
374 $$->table = ((struct rtable_config *)$3->def)->table;
375 }
376 | r_args FILTER filter {
377 $$ = $1;
430da60f 378 if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
730f2e2c
MM
379 $$->filter = $3;
380 }
430da60f
MM
381 | r_args where_filter {
382 $$ = $1;
383 if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
384 $$->filter = $2;
385 }
730f2e2c
MM
386 | r_args ALL {
387 $$ = $1;
388 $$->verbose = 1;
389 }
ce1da96e
MM
390 | r_args PRIMARY {
391 $$ = $1;
392 $$->primary_only = 1;
393 }
ea2ae6dd 394 | r_args export_or_preexport SYM {
ce1da96e
MM
395 struct proto_config *c = (struct proto_config *) $3->def;
396 $$ = $1;
ea2ae6dd 397 if ($$->export_mode) cf_error("Protocol specified twice");
ce1da96e 398 if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
ea2ae6dd 399 $$->export_mode = $2;
ce1da96e 400 $$->primary_only = 1;
ea2ae6dd 401 $$->export_protocol = c->proto;
ce1da96e
MM
402 $$->running_on_config = c->proto->cf->global;
403 }
4d176e14
OF
404 | r_args PROTOCOL SYM {
405 struct proto_config *c = (struct proto_config *) $3->def;
406 $$ = $1;
407 if ($$->show_protocol) cf_error("Protocol specified twice");
408 if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
409 $$->show_protocol = c->proto;
410 $$->running_on_config = c->proto->cf->global;
ce1da96e 411 }
23693958
MM
412 | r_args STATS {
413 $$ = $1;
414 $$->stats = 1;
415 }
33a368ad
MM
416 | r_args COUNT {
417 $$ = $1;
418 $$->stats = 2;
419 }
ce1da96e
MM
420 ;
421
ea2ae6dd
OZ
422export_or_preexport:
423 PREEXPORT { $$ = 1; }
424 | EXPORT { $$ = 2; }
730f2e2c
MM
425 ;
426
4b87e256
MM
427CF_CLI(SHOW SYMBOLS, optsym, [<symbol>], [[Show all known symbolic names]])
428{ cmd_show_symbols($3); } ;
429
96d8e3bf
MM
430CF_CLI_HELP(DUMP, ..., [[Dump debugging information]])
431CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]])
34350a52 432{ rdump(&root_pool); cli_msg(0, ""); } ;
96d8e3bf 433CF_CLI(DUMP SOCKETS,,, [[Dump open sockets]])
34350a52 434{ sk_dump_all(); cli_msg(0, ""); } ;
96d8e3bf 435CF_CLI(DUMP INTERFACES,,, [[Dump interface information]])
34350a52 436{ if_dump_all(); cli_msg(0, ""); } ;
96d8e3bf 437CF_CLI(DUMP NEIGHBORS,,, [[Dump neighbor cache]])
34350a52 438{ neigh_dump_all(); cli_msg(0, ""); } ;
96d8e3bf 439CF_CLI(DUMP ATTRIBUTES,,, [[Dump attribute cache]])
34350a52 440{ rta_dump_all(); cli_msg(0, ""); } ;
96d8e3bf 441CF_CLI(DUMP ROUTES,,, [[Dump routing table]])
34350a52 442{ rt_dump_all(); cli_msg(0, ""); } ;
96d8e3bf 443CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]])
34350a52
MM
444{ protos_dump_all(); cli_msg(0, ""); } ;
445
446CF_CLI(ECHO, echo_mask echo_size, [all | off | <mask>] [<buffer-size>], [[Configure echoing of log messages]]) {
447 cli_set_log_echo(this_cli, $2, $3);
448 cli_msg(0, "");
449} ;
450
451echo_mask:
452 ALL { $$ = ~0; }
453 | OFF { $$ = 0; }
454 | NUM
455 ;
456
457echo_size:
458 /* empty */ { $$ = 4096; }
459 | NUM {
460 if ($1 < 256 || $1 > 65536) cf_error("Invalid log buffer size");
461 $$ = $1;
462 }
463 ;
bc2fb680 464
49569a8b 465CF_CLI(DISABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Disable protocol]])
e0a45fb4 466{ proto_apply_cmd($2, proto_cmd_disable, 1, 0); } ;
49569a8b 467CF_CLI(ENABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Enable protocol]])
e0a45fb4 468{ proto_apply_cmd($2, proto_cmd_enable, 1, 0); } ;
49569a8b 469CF_CLI(RESTART, proto_patt, <protocol> | \"<pattern>\" | all, [[Restart protocol]])
e0a45fb4 470{ proto_apply_cmd($2, proto_cmd_restart, 1, 0); } ;
bf47fe4b 471CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]])
e0a45fb4 472{ proto_apply_cmd($2, proto_cmd_reload, 1, CMD_RELOAD); } ;
8a7fb885 473CF_CLI(RELOAD IN, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just imported routes)]])
e0a45fb4 474{ proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_IN); } ;
8a7fb885 475CF_CLI(RELOAD OUT, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just exported routes)]])
e0a45fb4 476{ proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_OUT); } ;
f14a4bec 477
cf31112f 478CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]])
353729f5 479CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | <pattern> | all) (all | off | { states | routes | filters | interfaces | events | packets }), [[Control protocol debugging via BIRD logs]])
e0a45fb4 480{ proto_apply_cmd($2, proto_cmd_debug, 1, $3); } ;
cf31112f
OZ
481
482CF_CLI_HELP(MRTDUMP, ..., [[Control protocol debugging via MRTdump files]])
483CF_CLI(MRTDUMP, proto_patt mrtdump_mask, (<protocol> | <pattern> | all) (all | off | { states | messages }), [[Control protocol debugging via MRTdump format]])
e0a45fb4
OZ
484{ proto_apply_cmd($2, proto_cmd_mrtdump, 1, $3); } ;
485
486CF_CLI(RESTRICT,,,[[Restrict current CLI session to safe commands]])
487{ this_cli->restricted = 1; cli_msg(16, "Access restricted"); } ;
96d8e3bf 488
f14a4bec 489proto_patt:
e304fd4b
OZ
490 SYM { $$.ptr = $1; $$.patt = 0; }
491 | ALL { $$.ptr = NULL; $$.patt = 1; }
492 | TEXT { $$.ptr = $1; $$.patt = 1; }
f14a4bec
MM
493 ;
494
e304fd4b
OZ
495proto_patt2:
496 SYM { $$.ptr = $1; $$.patt = 0; }
497 | { $$.ptr = NULL; $$.patt = 1; }
498 | TEXT { $$.ptr = $1; $$.patt = 1; }
499 ;
500
ba5e5940
OZ
501CF_ADDTO(dynamic_attr, IGP_METRIC
502 { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); })
503
e304fd4b 504
da877822
MM
505CF_CODE
506
507CF_END