]> git.ipfire.org Git - thirdparty/bird.git/blob - nest/config.Y
Filter: Instruction codes named as enum
[thirdparty/bird.git] / nest / config.Y
1 /*
2 * BIRD -- Core Configuration
3 *
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
5 * (c) 2004 Ondrej Filip <feela@network.cz>
6 *
7 * Can be freely distributed and used under the terms of the GNU GPL.
8 */
9
10 CF_HDR
11
12 #include "nest/rt-dev.h"
13 #include "nest/password.h"
14 #include "nest/cmds.h"
15 #include "lib/lists.h"
16 #include "lib/mac.h"
17
18 CF_DEFINES
19
20 static struct proto_config *this_proto;
21 static struct iface_patt *this_ipatt;
22 static struct iface_patt_node *this_ipn;
23 static struct roa_table_config *this_roa_table;
24 static list *this_p_list;
25 static struct password_item *this_p_item;
26 static int password_id;
27
28 static void
29 iface_patt_check(void)
30 {
31 struct iface_patt_node *pn;
32
33 WALK_LIST(pn, this_ipatt->ipn_list)
34 if (!pn->pattern || pn->pxlen)
35 cf_error("Interface name/mask expected, not IP prefix");
36 }
37
38
39 static inline void
40 reset_passwords(void)
41 {
42 this_p_list = NULL;
43 }
44
45 static inline list *
46 get_passwords(void)
47 {
48 list *rv = this_p_list;
49 this_p_list = NULL;
50 return rv;
51 }
52
53 #define DIRECT_CFG ((struct rt_dev_config *) this_proto)
54
55 CF_DECLS
56
57 CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
58 CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, TABLE, STATES, ROUTES, FILTERS)
59 CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
60 CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
61 CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512)
62 CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE, ROA)
63 CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SORTED)
64 CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
65 CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS)
66
67 CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
68 RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE, BABEL)
69 CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINED)
70 CF_ENUM(T_ENUM_RTC, RTC_, UNICAST, BROADCAST, MULTICAST, ANYCAST)
71 CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT, MULTIPATH)
72 CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
73
74 %type <i32> idval
75 %type <f> imexport
76 %type <r> rtable
77 %type <s> optsym
78 %type <ra> r_args
79 %type <ro> roa_args
80 %type <rot> roa_table_arg
81 %type <sd> sym_args
82 %type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode roa_mode limit_action tab_sorted tos password_algorithm
83 %type <ps> proto_patt proto_patt2
84 %type <g> limit_spec
85
86 CF_GRAMMAR
87
88 /* Setting of router ID */
89
90 CF_ADDTO(conf, rtrid)
91
92 rtrid:
93 ROUTER ID idval ';' { new_config->router_id = $3; }
94 | ROUTER ID FROM iface_patt ';' { new_config->router_id_from = this_ipatt; }
95 ;
96
97 idval:
98 NUM { $$ = $1; }
99 | '(' term ')' { $$ = f_eval_int($2); }
100 | RTRID
101 | IPA {
102 #ifndef IPV6
103 $$ = ipa_to_u32($1);
104 #else
105 cf_error("Router IDs must be entered as hexadecimal numbers or IPv4 addresses in IPv6 version");
106 #endif
107 }
108 | SYM {
109 if ($1->class == (SYM_CONSTANT | T_INT) || $1->class == (SYM_CONSTANT | T_QUAD))
110 $$ = SYM_VAL($1).i;
111 #ifndef IPV6
112 else if ($1->class == (SYM_CONSTANT | T_IP))
113 $$ = ipa_to_u32(SYM_VAL($1).px.ip);
114 #endif
115 else
116 cf_error("Number or IPv4 address constant expected");
117 }
118 ;
119
120
121 CF_ADDTO(conf, listen)
122
123 listen: LISTEN BGP listen_opts ';' ;
124
125 listen_opts:
126 /* Nothing */
127 | listen_opts listen_opt
128 ;
129
130 listen_opt:
131 ADDRESS ipa { new_config->listen_bgp_addr = $2; }
132 | PORT expr { new_config->listen_bgp_port = $2; }
133 | V6ONLY { new_config->listen_bgp_flags = 0; }
134 | DUAL { new_config->listen_bgp_flags = 1; }
135 ;
136
137
138 CF_ADDTO(conf, gr_opts)
139
140 gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->gr_wait = $4; } ;
141
142
143 /* Creation of routing tables */
144
145 tab_sorted:
146 { $$ = 0; }
147 | SORTED { $$ = 1; }
148 ;
149
150 CF_ADDTO(conf, newtab)
151
152 newtab: TABLE SYM tab_sorted {
153 struct rtable_config *cf;
154 cf = rt_new_table($2);
155 cf->sorted = $3;
156 }
157 ;
158
159 CF_ADDTO(conf, roa_table)
160
161 roa_table_start: ROA TABLE SYM {
162 this_roa_table = roa_new_table_config($3);
163 };
164
165 roa_table_opts:
166 /* empty */
167 | roa_table_opts ROA prefix MAX NUM AS NUM ';' {
168 roa_add_item_config(this_roa_table, $3.addr, $3.len, $5, $7);
169 }
170 ;
171
172 roa_table:
173 roa_table_start
174 | roa_table_start '{' roa_table_opts '}'
175 ;
176
177 /* Definition of protocols */
178
179 CF_ADDTO(conf, proto)
180
181 proto_start:
182 PROTOCOL { $$ = SYM_PROTO; }
183 | TEMPLATE { $$ = SYM_TEMPLATE; }
184 ;
185
186 proto_name:
187 /* EMPTY */ {
188 struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
189 s->class = this_proto->class;
190 s->def = this_proto;
191 this_proto->name = s->name;
192 }
193 | SYM {
194 cf_define_symbol($1, this_proto->class, this_proto);
195 this_proto->name = $1->name;
196 }
197 | FROM SYM {
198 struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
199 s->class = this_proto->class;
200 s->def = this_proto;
201 this_proto->name = s->name;
202
203 if (($2->class != SYM_TEMPLATE) && ($2->class != SYM_PROTO)) cf_error("Template or protocol name expected");
204 proto_copy_config(this_proto, $2->def);
205 }
206 | SYM FROM SYM {
207 cf_define_symbol($1, this_proto->class, this_proto);
208 this_proto->name = $1->name;
209
210 if (($3->class != SYM_TEMPLATE) && ($3->class != SYM_PROTO)) cf_error("Template or protocol name expected");
211 proto_copy_config(this_proto, $3->def);
212 }
213 ;
214
215 proto_item:
216 /* EMPTY */
217 | PREFERENCE expr {
218 if ($2 < 0 || $2 > 0xFFFF) cf_error("Invalid preference");
219 this_proto->preference = $2;
220 }
221 | DISABLED bool { this_proto->disabled = $2; }
222 | DEBUG debug_mask { this_proto->debug = $2; }
223 | MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; }
224 | IMPORT imexport { this_proto->in_filter = $2; }
225 | EXPORT imexport { this_proto->out_filter = $2; }
226 | RECEIVE LIMIT limit_spec { this_proto->rx_limit = $3; }
227 | IMPORT LIMIT limit_spec { this_proto->in_limit = $3; }
228 | EXPORT LIMIT limit_spec { this_proto->out_limit = $3; }
229 | IMPORT KEEP FILTERED bool { this_proto->in_keep_filtered = $4; }
230 | VRF text { this_proto->vrf = if_get_by_name($2); }
231 | TABLE rtable { this_proto->table = $2; }
232 | ROUTER ID idval { this_proto->router_id = $3; }
233 | DESCRIPTION text { this_proto->dsc = $2; }
234 ;
235
236 imexport:
237 FILTER filter { $$ = $2; }
238 | where_filter
239 | ALL { $$ = FILTER_ACCEPT; }
240 | NONE { $$ = FILTER_REJECT; }
241 ;
242
243 limit_action:
244 /* default */ { $$ = PLA_DISABLE; }
245 | ACTION WARN { $$ = PLA_WARN; }
246 | ACTION BLOCK { $$ = PLA_BLOCK; }
247 | ACTION RESTART { $$ = PLA_RESTART; }
248 | ACTION DISABLE { $$ = PLA_DISABLE; }
249 ;
250
251 limit_spec:
252 expr limit_action {
253 struct proto_limit *l = cfg_allocz(sizeof(struct proto_limit));
254 l->limit = $1;
255 l->action = $2;
256 $$ = l;
257 }
258 | OFF { $$ = NULL; }
259 ;
260
261 rtable:
262 SYM {
263 if ($1->class != SYM_TABLE) cf_error("Table name expected");
264 $$ = $1->def;
265 }
266 ;
267
268 CF_ADDTO(conf, debug_default)
269
270 debug_default:
271 DEBUG PROTOCOLS debug_mask { new_config->proto_default_debug = $3; }
272 | DEBUG COMMANDS expr { new_config->cli_debug = $3; }
273 ;
274
275 /* MRTDUMP PROTOCOLS is in systep/unix/config.Y */
276
277 /* Interface patterns */
278
279 iface_patt_node_init:
280 /* EMPTY */ {
281 struct iface_patt_node *ipn = cfg_allocz(sizeof(struct iface_patt_node));
282 add_tail(&this_ipatt->ipn_list, NODE ipn);
283 this_ipn = ipn;
284 }
285 ;
286
287 iface_patt_node_body:
288 TEXT { this_ipn->pattern = $1; this_ipn->prefix = IPA_NONE; this_ipn->pxlen = 0; }
289 | prefix_or_ipa { this_ipn->pattern = NULL; this_ipn->prefix = $1.addr; this_ipn->pxlen = $1.len; }
290 | TEXT prefix_or_ipa { this_ipn->pattern = $1; this_ipn->prefix = $2.addr; this_ipn->pxlen = $2.len; }
291 ;
292
293 iface_negate:
294 { this_ipn->positive = 1; }
295 | '-' { this_ipn->positive = 0; }
296 ;
297
298 iface_patt_node:
299 iface_patt_node_init iface_negate iface_patt_node_body
300 ;
301
302
303 iface_patt_list:
304 iface_patt_node
305 | iface_patt_list ',' iface_patt_node
306 ;
307
308 /* For name/mask-only iface patterns */
309 iface_patt_list_nopx: iface_patt_list { iface_patt_check(); }
310
311 iface_patt_init: {
312 /* Generic this_ipatt init */
313 this_ipatt = cfg_allocz(sizeof(struct iface_patt));
314 init_list(&this_ipatt->ipn_list);
315 }
316 ;
317
318 iface_patt:
319 iface_patt_init iface_patt_list
320 ;
321
322 tos:
323 CLASS expr { $$ = $2 & 0xfc; if (($2 < 0) || ($2 > 255)) cf_error("TX class must be in range 0-255"); }
324 | DSCP expr { $$ = ($2 & 0x3f) << 2; if (($2 < 0) || ($2 > 63)) cf_error("TX DSCP must be in range 0-63"); }
325 ;
326
327 /* Direct device route protocol */
328
329 CF_ADDTO(proto, dev_proto '}')
330
331 dev_proto_start: proto_start DIRECT {
332 this_proto = proto_config_new(&proto_device, $1);
333 init_list(&DIRECT_CFG->iface_list);
334 }
335 ;
336
337 dev_proto:
338 dev_proto_start proto_name '{'
339 | dev_proto proto_item ';'
340 | dev_proto dev_iface_patt ';'
341 | dev_proto CHECK LINK bool ';' { DIRECT_CFG->check_link = $4; }
342 ;
343
344 dev_iface_init:
345 /* EMPTY */ {
346 this_ipatt = cfg_allocz(sizeof(struct iface_patt));
347 add_tail(&DIRECT_CFG->iface_list, NODE this_ipatt);
348 init_list(&this_ipatt->ipn_list);
349 }
350 ;
351
352 dev_iface_patt:
353 INTERFACE dev_iface_init iface_patt_list
354 ;
355
356 /* Debug flags */
357
358 debug_mask:
359 ALL { $$ = ~0; }
360 | OFF { $$ = 0; }
361 | '{' debug_list '}' { $$ = $2; }
362 ;
363
364 debug_list:
365 debug_flag
366 | debug_list ',' debug_flag { $$ = $1 | $3; }
367 ;
368
369 debug_flag:
370 STATES { $$ = D_STATES; }
371 | ROUTES { $$ = D_ROUTES; }
372 | FILTERS { $$ = D_FILTERS; }
373 | INTERFACES { $$ = D_IFACES; }
374 | EVENTS { $$ = D_EVENTS; }
375 | PACKETS { $$ = D_PACKETS; }
376 ;
377
378 /* MRTDump flags */
379
380 mrtdump_mask:
381 ALL { $$ = ~0; }
382 | OFF { $$ = 0; }
383 | '{' mrtdump_list '}' { $$ = $2; }
384 ;
385
386 mrtdump_list:
387 mrtdump_flag
388 | mrtdump_list ',' mrtdump_flag { $$ = $1 | $3; }
389 ;
390
391 mrtdump_flag:
392 STATES { $$ = MD_STATES; }
393 | MESSAGES { $$ = MD_MESSAGES; }
394 ;
395
396 /* Password lists */
397
398 password_list:
399 PASSWORDS '{' password_items '}'
400 | password_item
401 ;
402
403 password_items:
404 /* empty */
405 | password_item ';' password_items
406 ;
407
408 password_item:
409 password_item_begin '{' password_item_params '}'
410 | password_item_begin
411 ;
412
413 password_item_begin:
414 PASSWORD text {
415 if (!this_p_list) {
416 this_p_list = cfg_alloc(sizeof(list));
417 init_list(this_p_list);
418 password_id = 1;
419 }
420 this_p_item = cfg_alloc(sizeof (struct password_item));
421 this_p_item->password = $2;
422 this_p_item->length = strlen($2);
423 this_p_item->genfrom = 0;
424 this_p_item->gento = TIME_INFINITY;
425 this_p_item->accfrom = 0;
426 this_p_item->accto = TIME_INFINITY;
427 this_p_item->id = password_id++;
428 this_p_item->alg = ALG_UNDEFINED;
429 add_tail(this_p_list, &this_p_item->n);
430 }
431 ;
432
433 password_item_params:
434 /* empty */ { }
435 | GENERATE FROM datetime ';' password_item_params { this_p_item->genfrom = $3; }
436 | GENERATE TO datetime ';' password_item_params { this_p_item->gento = $3; }
437 | ACCEPT FROM datetime ';' password_item_params { this_p_item->accfrom = $3; }
438 | ACCEPT TO datetime ';' password_item_params { this_p_item->accto = $3; }
439 | FROM datetime ';' password_item_params { this_p_item->genfrom = this_p_item->accfrom = $2; }
440 | TO datetime ';' password_item_params { this_p_item->gento = this_p_item->accto = $2; }
441 | ID expr ';' password_item_params { this_p_item->id = $2; if ($2 <= 0) cf_error("Password ID has to be greated than zero."); }
442 | ALGORITHM password_algorithm ';' password_item_params { this_p_item->alg = $2; }
443 ;
444
445 password_algorithm:
446 KEYED MD5 { $$ = ALG_MD5; }
447 | KEYED SHA1 { $$ = ALG_SHA1; }
448 | KEYED SHA256 { $$ = ALG_SHA256; }
449 | KEYED SHA384 { $$ = ALG_SHA384; }
450 | KEYED SHA512 { $$ = ALG_SHA512; }
451 | HMAC MD5 { $$ = ALG_HMAC_MD5; }
452 | HMAC SHA1 { $$ = ALG_HMAC_SHA1; }
453 | HMAC SHA256 { $$ = ALG_HMAC_SHA256; }
454 | HMAC SHA384 { $$ = ALG_HMAC_SHA384; }
455 | HMAC SHA512 { $$ = ALG_HMAC_SHA512; }
456 ;
457
458 /* Core commands */
459 CF_CLI_HELP(SHOW, ..., [[Show status information]])
460
461 CF_CLI(SHOW STATUS,,, [[Show router status]])
462 { cmd_show_status(); } ;
463
464 CF_CLI(SHOW MEMORY,,, [[Show memory usage]])
465 { cmd_show_memory(); } ;
466
467 CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
468 { proto_apply_cmd($3, proto_cmd_show, 0, 0); } ;
469
470 CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]])
471 { proto_apply_cmd($4, proto_cmd_show, 0, 1); } ;
472
473 optsym:
474 SYM
475 | /* empty */ { $$ = NULL; }
476 ;
477
478 CF_CLI(SHOW INTERFACES,,, [[Show network interfaces]])
479 { if_show(); } ;
480
481 CF_CLI(SHOW INTERFACES SUMMARY,,, [[Show summary of network interfaces]])
482 { if_show_summary(); } ;
483
484 CF_CLI_HELP(SHOW ROUTE, ..., [[Show routing table]])
485 CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>] [table <t>] [filter <f>|where <cond>] [all] [primary] [filtered] [(export|preexport|noexport) <p>] [protocol <p>] [stats|count]]], [[Show routing table]])
486 { rt_show($3); } ;
487
488 r_args:
489 /* empty */ {
490 $$ = cfg_allocz(sizeof(struct rt_show_data));
491 $$->pxlen = 256;
492 $$->filter = FILTER_ACCEPT;
493 }
494 | r_args prefix {
495 $$ = $1;
496 if ($$->pxlen != 256) cf_error("Only one prefix expected");
497 $$->prefix = $2.addr;
498 $$->pxlen = $2.len;
499 }
500 | r_args FOR prefix_or_ipa {
501 $$ = $1;
502 if ($$->pxlen != 256) cf_error("Only one prefix expected");
503 $$->prefix = $3.addr;
504 $$->pxlen = $3.len;
505 $$->show_for = 1;
506 }
507 | r_args TABLE SYM {
508 $$ = $1;
509 if ($3->class != SYM_TABLE) cf_error("%s is not a table", $3->name);
510 $$->table = ((struct rtable_config *)$3->def)->table;
511 }
512 | r_args FILTER filter {
513 $$ = $1;
514 if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
515 $$->filter = $3;
516 }
517 | r_args where_filter {
518 $$ = $1;
519 if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
520 $$->filter = $2;
521 }
522 | r_args ALL {
523 $$ = $1;
524 $$->verbose = 1;
525 }
526 | r_args PRIMARY {
527 $$ = $1;
528 $$->primary_only = 1;
529 }
530 | r_args FILTERED {
531 $$ = $1;
532 $$->filtered = 1;
533 }
534 | r_args export_mode SYM {
535 struct proto_config *c = (struct proto_config *) $3->def;
536 $$ = $1;
537 if ($$->export_mode) cf_error("Protocol specified twice");
538 if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
539 $$->export_mode = $2;
540 $$->export_protocol = c->proto;
541 $$->running_on_config = c->proto->cf->global;
542 }
543 | r_args PROTOCOL SYM {
544 struct proto_config *c = (struct proto_config *) $3->def;
545 $$ = $1;
546 if ($$->show_protocol) cf_error("Protocol specified twice");
547 if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
548 $$->show_protocol = c->proto;
549 $$->running_on_config = c->proto->cf->global;
550 }
551 | r_args STATS {
552 $$ = $1;
553 $$->stats = 1;
554 }
555 | r_args COUNT {
556 $$ = $1;
557 $$->stats = 2;
558 }
559 ;
560
561 export_mode:
562 PREEXPORT { $$ = RSEM_PREEXPORT; }
563 | EXPORT { $$ = RSEM_EXPORT; }
564 | NOEXPORT { $$ = RSEM_NOEXPORT; }
565 ;
566
567
568 CF_CLI_HELP(SHOW ROA, ..., [[Show ROA table]])
569 CF_CLI(SHOW ROA, roa_args, [<prefix> | in <prefix> | for <prefix>] [as <num>] [table <t>], [[Show ROA table]])
570 { roa_show($3); } ;
571
572 roa_args:
573 /* empty */ {
574 $$ = cfg_allocz(sizeof(struct roa_show_data));
575 $$->mode = ROA_SHOW_ALL;
576 $$->table = roa_table_default;
577 if (roa_table_default == NULL)
578 cf_error("No ROA table defined");
579 }
580 | roa_args roa_mode prefix {
581 $$ = $1;
582 if ($$->mode != ROA_SHOW_ALL) cf_error("Only one prefix expected");
583 $$->prefix = $3.addr;
584 $$->pxlen = $3.len;
585 $$->mode = $2;
586 }
587 | roa_args AS NUM {
588 $$ = $1;
589 $$->asn = $3;
590 }
591 | roa_args TABLE SYM {
592 $$ = $1;
593 if ($3->class != SYM_ROA) cf_error("%s is not a ROA table", $3->name);
594 $$->table = ((struct roa_table_config *)$3->def)->table;
595 }
596 ;
597
598 roa_mode:
599 { $$ = ROA_SHOW_PX; }
600 | IN { $$ = ROA_SHOW_IN; }
601 | FOR { $$ = ROA_SHOW_FOR; }
602 ;
603
604
605 CF_CLI_HELP(SHOW SYMBOLS, ..., [[Show all known symbolic names]])
606 CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|roa|<symbol>], [[Show all known symbolic names]])
607 { cmd_show_symbols($3); } ;
608
609 sym_args:
610 /* empty */ {
611 $$ = cfg_allocz(sizeof(struct sym_show_data));
612 }
613 | sym_args TABLE { $$ = $1; $$->type = SYM_TABLE; }
614 | sym_args FUNCTION { $$ = $1; $$->type = SYM_FUNCTION; }
615 | sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; }
616 | sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; }
617 | sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; }
618 | sym_args ROA { $$ = $1; $$->type = SYM_ROA; }
619 | sym_args SYM { $$ = $1; $$->sym = $2; }
620 ;
621
622
623 roa_table_arg:
624 /* empty */ {
625 if (roa_table_default == NULL)
626 cf_error("No ROA table defined");
627 $$ = roa_table_default;
628 }
629 | TABLE SYM {
630 if ($2->class != SYM_ROA)
631 cf_error("%s is not a ROA table", $2->name);
632 $$ = ((struct roa_table_config *)$2->def)->table;
633 }
634 ;
635
636 CF_CLI_HELP(ADD, roa ..., [[Add ROA record]])
637 CF_CLI(ADD ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Add ROA record]])
638 {
639 if (! cli_access_restricted())
640 { roa_add_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
641 };
642
643 CF_CLI_HELP(DELETE, roa ..., [[Delete ROA record]])
644 CF_CLI(DELETE ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Delete ROA record]])
645 {
646 if (! cli_access_restricted())
647 { roa_delete_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
648 };
649
650 CF_CLI_HELP(FLUSH, roa [table <name>], [[Removes all dynamic ROA records]])
651 CF_CLI(FLUSH ROA, roa_table_arg, [table <name>], [[Removes all dynamic ROA records]])
652 {
653 if (! cli_access_restricted())
654 { roa_flush($3, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
655 };
656
657
658 CF_CLI_HELP(DUMP, ..., [[Dump debugging information]])
659 CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]])
660 { rdump(&root_pool); cli_msg(0, ""); } ;
661 CF_CLI(DUMP SOCKETS,,, [[Dump open sockets]])
662 { sk_dump_all(); cli_msg(0, ""); } ;
663 CF_CLI(DUMP EVENTS,,, [[Dump event log]])
664 { io_log_dump(); cli_msg(0, ""); } ;
665 CF_CLI(DUMP INTERFACES,,, [[Dump interface information]])
666 { if_dump_all(); cli_msg(0, ""); } ;
667 CF_CLI(DUMP NEIGHBORS,,, [[Dump neighbor cache]])
668 { neigh_dump_all(); cli_msg(0, ""); } ;
669 CF_CLI(DUMP ATTRIBUTES,,, [[Dump attribute cache]])
670 { rta_dump_all(); cli_msg(0, ""); } ;
671 CF_CLI(DUMP ROUTES,,, [[Dump routing table]])
672 { rt_dump_all(); cli_msg(0, ""); } ;
673 CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]])
674 { protos_dump_all(); cli_msg(0, ""); } ;
675
676 CF_CLI(EVAL, term, <expr>, [[Evaluate an expression]])
677 { cmd_eval($2); } ;
678
679 CF_CLI_HELP(ECHO, ..., [[Control echoing of log messages]])
680 CF_CLI(ECHO, echo_mask echo_size, (all | off | { debug|trace|info|remote|warning|error|auth [, ...] }) [<buffer-size>], [[Control echoing of log messages]]) {
681 cli_set_log_echo(this_cli, $2, $3);
682 cli_msg(0, "");
683 } ;
684
685 echo_mask:
686 ALL { $$ = ~0; }
687 | OFF { $$ = 0; }
688 | '{' log_mask_list '}' { $$ = $2; }
689 ;
690
691 echo_size:
692 /* empty */ { $$ = 4096; }
693 | NUM {
694 if ($1 < 256 || $1 > 65536) cf_error("Invalid log buffer size");
695 $$ = $1;
696 }
697 ;
698
699 CF_CLI(DISABLE, proto_patt text_or_none, (<protocol> | \"<pattern>\" | all) [message], [[Disable protocol]])
700 { proto_apply_cmd($2, proto_cmd_disable, 1, (uintptr_t) $3); } ;
701 CF_CLI(ENABLE, proto_patt text_or_none, (<protocol> | \"<pattern>\" | all) [message], [[Enable protocol]])
702 { proto_apply_cmd($2, proto_cmd_enable, 1, (uintptr_t) $3); } ;
703 CF_CLI(RESTART, proto_patt text_or_none, (<protocol> | \"<pattern>\" | all) [message], [[Restart protocol]])
704 { proto_apply_cmd($2, proto_cmd_restart, 1, (uintptr_t) $3); } ;
705 CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]])
706 { proto_apply_cmd($2, proto_cmd_reload, 1, CMD_RELOAD); } ;
707 CF_CLI(RELOAD IN, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just imported routes)]])
708 { proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_IN); } ;
709 CF_CLI(RELOAD OUT, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just exported routes)]])
710 { proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_OUT); } ;
711
712 CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]])
713 CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | \"<pattern>\" | all) (all | off | { states|routes|filters|interfaces|events|packets [, ...] }), [[Control protocol debugging via BIRD logs]])
714 { proto_apply_cmd($2, proto_cmd_debug, 1, $3); } ;
715
716 CF_CLI_HELP(MRTDUMP, ..., [[Control protocol debugging via MRTdump files]])
717 CF_CLI(MRTDUMP, proto_patt mrtdump_mask, (<protocol> | \"<pattern>\" | all) (all | off | { states|messages [, ...] }), [[Control protocol debugging via MRTdump format]])
718 { proto_apply_cmd($2, proto_cmd_mrtdump, 1, $3); } ;
719
720 CF_CLI(RESTRICT,,,[[Restrict current CLI session to safe commands]])
721 { this_cli->restricted = 1; cli_msg(16, "Access restricted"); } ;
722
723 proto_patt:
724 SYM { $$.ptr = $1; $$.patt = 0; }
725 | ALL { $$.ptr = NULL; $$.patt = 1; }
726 | TEXT { $$.ptr = $1; $$.patt = 1; }
727 ;
728
729 proto_patt2:
730 SYM { $$.ptr = $1; $$.patt = 0; }
731 | { $$.ptr = NULL; $$.patt = 1; }
732 | TEXT { $$.ptr = $1; $$.patt = 1; }
733 ;
734
735 CF_ADDTO(dynamic_attr, IGP_METRIC
736 { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); })
737
738
739 CF_CODE
740
741 CF_END