Statistics
| Branch: | Revision:

iof-bird-daemon / nest / config.Y @ 17661ff9

History | View | Annotate | Download (19.7 KB)

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

    
17
CF_DEFINES
18

    
19
static struct proto_config *this_proto;
20
static struct iface_patt *this_ipatt;
21
static struct iface_patt_node *this_ipn;
22
static struct roa_table_config *this_roa_table;
23
static list *this_p_list;
24
static struct password_item *this_p_item;
25
static int password_id;
26

    
27
static void
28
iface_patt_check(void)
29
{
30
  struct iface_patt_node *pn;
31

    
32
  WALK_LIST(pn, this_ipatt->ipn_list)
33
    if (!pn->pattern || pn->pxlen)
34
      cf_error("Interface name/mask expected, not IP prefix");
35
}
36

    
37

    
38
static inline void
39
reset_passwords(void)
40
{
41
  this_p_list = NULL;
42
}
43

    
44
static inline list *
45
get_passwords(void)
46
{
47
  list *rv = this_p_list;
48
  this_p_list = NULL;
49
  return rv;
50
}
51

    
52
#define DIRECT_CFG ((struct rt_dev_config *) this_proto)
53

    
54
CF_DECLS
55

    
56
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
57
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
58
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
59
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
60
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE, ROA)
61
CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SORTED)
62
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
63
CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS)
64

    
65
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
66
	RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
67
CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINED)
68
CF_ENUM(T_ENUM_RTC, RTC_, UNICAST, BROADCAST, MULTICAST, ANYCAST)
69
CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT, MULTIPATH)
70
CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
71

    
72
%type <i32> idval
73
%type <f> imexport
74
%type <r> rtable
75
%type <s> optsym
76
%type <ra> r_args
77
%type <ro> roa_args
78
%type <rot> roa_table_arg
79
%type <sd> sym_args
80
%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
81
%type <ps> proto_patt proto_patt2
82
%type <g> limit_spec
83

    
84
CF_GRAMMAR
85

    
86
/* Setting of router ID */
87

    
88
CF_ADDTO(conf, rtrid)
89

    
90
rtrid: 
91
   ROUTER ID idval ';' { new_config->router_id = $3; }
92
 | ROUTER ID FROM iface_patt ';' { new_config->router_id_from = this_ipatt; }
93
 ;
94

    
95
idval:
96
   NUM { $$ = $1; }
97
 | '(' term ')' { $$ = f_eval_int($2); }
98
 | RTRID
99
 | IPA {
100
#ifndef IPV6
101
     $$ = ipa_to_u32($1);
102
#else
103
     cf_error("Router IDs must be entered as hexadecimal numbers or IPv4 addresses in IPv6 version");
104
#endif
105
   }
106
 | SYM {
107
     if ($1->class == (SYM_CONSTANT | T_INT) || $1->class == (SYM_CONSTANT | T_QUAD))
108
       $$ = SYM_VAL($1).i;
109
#ifndef IPV6
110
     else if ($1->class == (SYM_CONSTANT | T_IP))
111
       $$ = SYM_VAL($1).px.ip;
112
#endif
113
     else
114
       cf_error("Number of IPv4 address constant expected");
115
   }
116
 ;
117

    
118

    
119
CF_ADDTO(conf, listen)
120

    
121
listen: LISTEN BGP listen_opts ';' ;
122

    
123
listen_opts:
124
   /* Nothing */
125
 | listen_opts listen_opt
126
 ;
127

    
128
listen_opt: 
129
   ADDRESS ipa { new_config->listen_bgp_addr = $2; }
130
 | PORT expr { new_config->listen_bgp_port = $2; }
131
 | V6ONLY { new_config->listen_bgp_flags = 0; }
132
 | DUAL { new_config->listen_bgp_flags = 1; }
133
 ;
134

    
135

    
136
CF_ADDTO(conf, gr_opts)
137

    
138
gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->gr_wait = $4; } ;
139

    
140

    
141
/* Creation of routing tables */
142

    
143
tab_sorted:
144
          { $$ = 0; }
145
 | SORTED { $$ = 1; }
146
 ;
147

    
148
CF_ADDTO(conf, newtab)
149

    
150
newtab: TABLE SYM tab_sorted {
151
   struct rtable_config *cf;
152
   cf = rt_new_table($2);
153
   cf->sorted = $3;
154
   }
155
 ;
156

    
157
CF_ADDTO(conf, roa_table)
158

    
159
roa_table_start: ROA TABLE SYM {
160
  this_roa_table = roa_new_table_config($3);
161
};
162

    
163
roa_table_opts:
164
   /* empty */
165
 | roa_table_opts ROA prefix MAX NUM AS NUM ';' {
166
     roa_add_item_config(this_roa_table, $3.addr, $3.len, $5, $7);
167
   }
168
 ;
169

    
170
roa_table:
171
   roa_table_start
172
 | roa_table_start '{' roa_table_opts '}'
173
 ;
174

    
175
/* Definition of protocols */
176

    
177
CF_ADDTO(conf, proto)
178

    
179
proto_start:
180
   PROTOCOL { $$ = SYM_PROTO; }
181
 | TEMPLATE { $$ = SYM_TEMPLATE; }
182
 ;
183

    
184
proto_name:
185
   /* EMPTY */ {
186
     struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
187
     s->class = this_proto->class;
188
     s->def = this_proto;
189
     this_proto->name = s->name;
190
     }
191
 | SYM {
192
     cf_define_symbol($1, this_proto->class, this_proto);
193
     this_proto->name = $1->name;
194
   }
195
 | FROM SYM {
196
     struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
197
     s->class = this_proto->class;
198
     s->def = this_proto;
199
     this_proto->name = s->name;
200

    
201
     if (($2->class != SYM_TEMPLATE) && ($2->class != SYM_PROTO)) cf_error("Template or protocol name expected");
202
     proto_copy_config(this_proto, $2->def);
203
   }
204
 | SYM FROM SYM {
205
     cf_define_symbol($1, this_proto->class, this_proto);
206
     this_proto->name = $1->name;
207

    
208
     if (($3->class != SYM_TEMPLATE) && ($3->class != SYM_PROTO)) cf_error("Template or protocol name expected");
209
     proto_copy_config(this_proto, $3->def);
210
   }
211
 ;
212

    
213
proto_item:
214
   /* EMPTY */
215
 | PREFERENCE expr {
216
     if ($2 < 0 || $2 > 0xFFFF) cf_error("Invalid preference");
217
     this_proto->preference = $2;
218
   }
219
 | DISABLED bool { this_proto->disabled = $2; }
220
 | DEBUG debug_mask { this_proto->debug = $2; }
221
 | MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; }
222
 | IMPORT imexport { this_proto->in_filter = $2; }
223
 | EXPORT imexport { this_proto->out_filter = $2; }
224
 | RECEIVE LIMIT limit_spec { this_proto->rx_limit = $3; }
225
 | IMPORT LIMIT limit_spec { this_proto->in_limit = $3; }
226
 | EXPORT LIMIT limit_spec { this_proto->out_limit = $3; }
227
 | IMPORT KEEP FILTERED bool { this_proto->in_keep_filtered = $4; }
228
 | TABLE rtable { this_proto->table = $2; }
229
 | ROUTER ID idval { this_proto->router_id = $3; }
230
 | DESCRIPTION text { this_proto->dsc = $2; }
231
 ;
232

    
233
imexport:
234
   FILTER filter { $$ = $2; }
235
 | where_filter
236
 | ALL { $$ = FILTER_ACCEPT; }
237
 | NONE { $$ = FILTER_REJECT; }
238
 ;
239

    
240
limit_action:
241
   /* default */ { $$ = PLA_DISABLE; }
242
 | ACTION WARN { $$ = PLA_WARN; }
243
 | ACTION BLOCK { $$ = PLA_BLOCK; }
244
 | ACTION RESTART { $$ = PLA_RESTART; }
245
 | ACTION DISABLE { $$ = PLA_DISABLE; }
246
 ;
247

    
248
limit_spec:
249
   expr limit_action {
250
     struct proto_limit *l = cfg_allocz(sizeof(struct proto_limit));
251
     l->limit = $1;
252
     l->action = $2;
253
     $$ = l;
254
   }
255
 | OFF { $$ = NULL; }
256
 ;
257

    
258
rtable:
259
   SYM {
260
     if ($1->class != SYM_TABLE) cf_error("Table name expected");
261
     $$ = $1->def;
262
   }
263
 ;
264

    
265
CF_ADDTO(conf, debug_default)
266

    
267
debug_default:
268
   DEBUG PROTOCOLS debug_mask { new_config->proto_default_debug = $3; }
269
 | DEBUG COMMANDS expr { new_config->cli_debug = $3; }
270
 ;
271

    
272
/* MRTDUMP PROTOCOLS is in systep/unix/config.Y */
273

    
274
/* Interface patterns */
275

    
276
iface_patt_node_init:
277
   /* EMPTY */ {
278
     struct iface_patt_node *ipn = cfg_allocz(sizeof(struct iface_patt_node));
279
     add_tail(&this_ipatt->ipn_list, NODE ipn);
280
     this_ipn = ipn;
281
   }
282
 ;
283

    
284
iface_patt_node_body:
285
   TEXT { this_ipn->pattern = $1; this_ipn->prefix = IPA_NONE; this_ipn->pxlen = 0; }
286
 | prefix_or_ipa { this_ipn->pattern = NULL; this_ipn->prefix = $1.addr; this_ipn->pxlen = $1.len; }
287
 | TEXT prefix_or_ipa { this_ipn->pattern = $1; this_ipn->prefix = $2.addr; this_ipn->pxlen = $2.len; }
288
 ;
289

    
290
iface_negate:
291
       { this_ipn->positive = 1; }
292
 | '-' { this_ipn->positive = 0; }
293
 ;
294

    
295
iface_patt_node:
296
   iface_patt_node_init iface_negate iface_patt_node_body 
297
 ;
298

    
299

    
300
iface_patt_list:
301
   iface_patt_node
302
 | iface_patt_list ',' iface_patt_node
303
 ;
304

    
305
/* For name/mask-only iface patterns */
306
iface_patt_list_nopx: iface_patt_list { iface_patt_check(); }
307

    
308
iface_patt_init: {
309
   /* Generic this_ipatt init */
310
   this_ipatt = cfg_allocz(sizeof(struct iface_patt));
311
   init_list(&this_ipatt->ipn_list);
312
 }
313
 ;
314

    
315
iface_patt:
316
   iface_patt_init iface_patt_list
317
 ;
318

    
319
tos:
320
   CLASS expr { $$ = $2 & 0xfc;        if (($2 < 0) || ($2 > 255)) cf_error("TX class must be in range 0-255"); }
321
 | DSCP expr  { $$ = ($2 & 0x3f) << 2; if (($2 < 0) || ($2 > 63))  cf_error("TX DSCP must be in range 0-63"); }
322
 ;
323

    
324
/* Direct device route protocol */
325

    
326
CF_ADDTO(proto, dev_proto '}')
327

    
328
dev_proto_start: proto_start DIRECT {
329
     this_proto = proto_config_new(&proto_device, $1);
330
     init_list(&DIRECT_CFG->iface_list);
331
   }
332
 ;
333

    
334
dev_proto:
335
   dev_proto_start proto_name '{'
336
 | dev_proto proto_item ';'
337
 | dev_proto dev_iface_patt ';'
338
 ;
339

    
340
dev_iface_init:
341
   /* EMPTY */ {
342
     this_ipatt = cfg_allocz(sizeof(struct iface_patt));
343
     add_tail(&DIRECT_CFG->iface_list, NODE this_ipatt);
344
     init_list(&this_ipatt->ipn_list);
345
   }
346
 ;
347

    
348
dev_iface_patt:
349
   INTERFACE dev_iface_init iface_patt_list
350
 ;
351

    
352
/* Debug flags */
353

    
354
debug_mask:
355
   ALL { $$ = ~0; }
356
 | OFF { $$ = 0; }
357
 | '{' debug_list '}' { $$ = $2; }
358
 ;
359

    
360
debug_list:
361
   debug_flag
362
 | debug_list ',' debug_flag { $$ = $1 | $3; }
363
 ;
364

    
365
debug_flag:
366
   STATES	{ $$ = D_STATES; }
367
 | ROUTES	{ $$ = D_ROUTES; }
368
 | FILTERS	{ $$ = D_FILTERS; }
369
 | INTERFACES	{ $$ = D_IFACES; }
370
 | EVENTS	{ $$ = D_EVENTS; }
371
 | PACKETS	{ $$ = D_PACKETS; }
372
 ;
373

    
374
/* MRTDump flags */
375

    
376
mrtdump_mask:
377
   ALL { $$ = ~0; }
378
 | OFF { $$ = 0; }
379
 | '{' mrtdump_list '}' { $$ = $2; }
380
 ;
381

    
382
mrtdump_list:
383
   mrtdump_flag
384
 | mrtdump_list ',' mrtdump_flag { $$ = $1 | $3; }
385
 ;
386

    
387
mrtdump_flag:
388
   STATES	{ $$ = MD_STATES; }
389
 | MESSAGES	{ $$ = MD_MESSAGES; }
390
 ;
391

    
392
/* Password lists */
393

    
394
password_list:
395
   PASSWORDS '{' password_items '}'
396
 | password_item
397
;
398

    
399
password_items: 
400
    /* empty */
401
  | password_item ';' password_items
402
;
403

    
404
password_item:
405
    password_item_begin '{' password_item_params '}'
406
  | password_item_begin
407
;
408

    
409
password_item_begin:
410
   PASSWORD text {
411
     if (!this_p_list) {
412
     	this_p_list = cfg_alloc(sizeof(list));
413
     	init_list(this_p_list);
414
        password_id = 1;
415
     }
416
     this_p_item = cfg_alloc(sizeof (struct password_item));
417
     this_p_item->password = $2;
418
     this_p_item->genfrom = 0;
419
     this_p_item->gento = TIME_INFINITY;
420
     this_p_item->accfrom = 0;
421
     this_p_item->accto = TIME_INFINITY;
422
     this_p_item->id = password_id++;
423
     add_tail(this_p_list, &this_p_item->n);
424
   }
425
;
426

    
427
password_item_params:
428
   /* empty */ { } 
429
 | GENERATE FROM datetime ';' password_item_params { this_p_item->genfrom = $3; }
430
 | GENERATE TO datetime ';' password_item_params { this_p_item->gento = $3; }
431
 | ACCEPT FROM datetime ';' password_item_params { this_p_item->accfrom = $3; }
432
 | ACCEPT TO datetime ';' password_item_params { this_p_item->accto = $3; }
433
 | ID expr ';' password_item_params { this_p_item->id = $2; if ($2 <= 0) cf_error("Password ID has to be greated than zero."); }
434
 ;
435

    
436

    
437

    
438
/* Core commands */
439
CF_CLI_HELP(SHOW, ..., [[Show status information]])
440

    
441
CF_CLI(SHOW STATUS,,, [[Show router status]])
442
{ cmd_show_status(); } ;
443

    
444
CF_CLI(SHOW MEMORY,,, [[Show memory usage]])
445
{ cmd_show_memory(); } ;
446

    
447
CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
448
{ proto_apply_cmd($3, proto_cmd_show, 0, 0); } ;
449

    
450
CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]])
451
{ proto_apply_cmd($4, proto_cmd_show, 0, 1); } ;
452

    
453
optsym:
454
   SYM
455
 | /* empty */ { $$ = NULL; }
456
 ;
457

    
458
CF_CLI(SHOW INTERFACES,,, [[Show network interfaces]])
459
{ if_show(); } ;
460

    
461
CF_CLI(SHOW INTERFACES SUMMARY,,, [[Show summary of network interfaces]])
462
{ if_show_summary(); } ;
463

    
464
CF_CLI_HELP(SHOW ROUTE, ..., [[Show routing table]])
465
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]])
466
{ rt_show($3); } ;
467

    
468
r_args:
469
   /* empty */ {
470
     $$ = cfg_allocz(sizeof(struct rt_show_data));
471
     $$->pxlen = 256;
472
     $$->filter = FILTER_ACCEPT;
473
   }
474
 | r_args prefix {
475
     $$ = $1;
476
     if ($$->pxlen != 256) cf_error("Only one prefix expected");
477
     $$->prefix = $2.addr;
478
     $$->pxlen = $2.len;
479
   }
480
 | r_args FOR prefix_or_ipa {
481
     $$ = $1;
482
     if ($$->pxlen != 256) cf_error("Only one prefix expected");
483
     $$->prefix = $3.addr;
484
     $$->pxlen = $3.len;
485
     $$->show_for = 1;
486
   }
487
 | r_args TABLE SYM {
488
     $$ = $1;
489
     if ($3->class != SYM_TABLE) cf_error("%s is not a table", $3->name);
490
     $$->table = ((struct rtable_config *)$3->def)->table;
491
   }
492
 | r_args FILTER filter {
493
     $$ = $1;
494
     if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
495
     $$->filter = $3;
496
   }
497
 | r_args where_filter {
498
     $$ = $1;
499
     if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
500
     $$->filter = $2;
501
   }
502
 | r_args ALL {
503
     $$ = $1;
504
     $$->verbose = 1;
505
   }
506
 | r_args PRIMARY {
507
     $$ = $1;
508
     $$->primary_only = 1;
509
   }
510
 | r_args FILTERED {
511
     $$ = $1;
512
     $$->filtered = 1;
513
   }
514
 | r_args export_mode SYM {
515
     struct proto_config *c = (struct proto_config *) $3->def;
516
     $$ = $1;
517
     if ($$->export_mode) cf_error("Protocol specified twice");
518
     if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
519
     $$->export_mode = $2;
520
     $$->export_protocol = c->proto;
521
     $$->running_on_config = c->proto->cf->global;
522
   }
523
 | r_args PROTOCOL SYM {
524
     struct proto_config *c = (struct proto_config *) $3->def;
525
     $$ = $1;
526
     if ($$->show_protocol) cf_error("Protocol specified twice");
527
     if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
528
     $$->show_protocol = c->proto;
529
     $$->running_on_config = c->proto->cf->global;
530
   }
531
 | r_args STATS {
532
     $$ = $1;
533
     $$->stats = 1;
534
   }
535
 | r_args COUNT {
536
     $$ = $1;
537
     $$->stats = 2;
538
   }
539
 ;
540

    
541
export_mode:
542
   PREEXPORT	{ $$ = RSEM_PREEXPORT; }
543
 | EXPORT	{ $$ = RSEM_EXPORT; }
544
 | NOEXPORT	{ $$ = RSEM_NOEXPORT; }
545
 ;
546

    
547

    
548
CF_CLI_HELP(SHOW ROA, ..., [[Show ROA table]])
549
CF_CLI(SHOW ROA, roa_args, [<prefix> | in <prefix> | for <prefix>] [as <num>] [table <t>], [[Show ROA table]])
550
{ roa_show($3); } ;
551

    
552
roa_args:
553
   /* empty */ {
554
     $$ = cfg_allocz(sizeof(struct roa_show_data));
555
     $$->mode = ROA_SHOW_ALL;
556
     $$->table = roa_table_default;
557
     if (roa_table_default == NULL)
558
       cf_error("No ROA table defined");
559
   }
560
 | roa_args roa_mode prefix {
561
     $$ = $1;
562
     if ($$->mode != ROA_SHOW_ALL) cf_error("Only one prefix expected");
563
     $$->prefix = $3.addr;
564
     $$->pxlen = $3.len;
565
     $$->mode = $2;
566
   }
567
 | roa_args AS NUM {
568
     $$ = $1;
569
     $$->asn = $3;
570
   }
571
 | roa_args TABLE SYM {
572
     $$ = $1;
573
     if ($3->class != SYM_ROA) cf_error("%s is not a ROA table", $3->name);
574
     $$->table = ((struct roa_table_config *)$3->def)->table;
575
   }
576
 ;
577

    
578
roa_mode:
579
       { $$ = ROA_SHOW_PX; }
580
 | IN  { $$ = ROA_SHOW_IN; }
581
 | FOR { $$ = ROA_SHOW_FOR; }
582
 ;
583

    
584

    
585
CF_CLI_HELP(SHOW SYMBOLS, ..., [[Show all known symbolic names]])
586
CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|roa|<symbol>], [[Show all known symbolic names]])
587
{ cmd_show_symbols($3); } ;
588

    
589
sym_args:
590
   /* empty */ {
591
     $$ = cfg_allocz(sizeof(struct sym_show_data));
592
   }
593
 | sym_args TABLE { $$ = $1; $$->type = SYM_TABLE; }
594
 | sym_args FUNCTION { $$ = $1; $$->type = SYM_FUNCTION; }
595
 | sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; }
596
 | sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; }
597
 | sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; }
598
 | sym_args ROA { $$ = $1; $$->type = SYM_ROA; }
599
 | sym_args SYM { $$ = $1; $$->sym = $2; }
600
 ;
601

    
602

    
603
roa_table_arg:
604
   /* empty */ { 
605
     if (roa_table_default == NULL)
606
       cf_error("No ROA table defined");
607
     $$ = roa_table_default;
608
   }
609
 | TABLE SYM {
610
     if ($2->class != SYM_ROA)
611
       cf_error("%s is not a ROA table", $2->name);
612
     $$ = ((struct roa_table_config *)$2->def)->table;
613
   }
614
 ;
615

    
616
CF_CLI_HELP(ADD, roa ..., [[Add ROA record]])
617
CF_CLI(ADD ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Add ROA record]])
618
{
619
  if (! cli_access_restricted())
620
    { roa_add_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
621
};
622

    
623
CF_CLI_HELP(DELETE, roa ..., [[Delete ROA record]])
624
CF_CLI(DELETE ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Delete ROA record]])
625
{
626
  if (! cli_access_restricted())
627
    { roa_delete_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
628
};
629

    
630
CF_CLI_HELP(FLUSH, roa [table <name>], [[Removes all dynamic ROA records]])
631
CF_CLI(FLUSH ROA, roa_table_arg, [table <name>], [[Removes all dynamic ROA records]])
632
{
633
  if (! cli_access_restricted())
634
    { roa_flush($3, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
635
};
636

    
637

    
638
CF_CLI_HELP(DUMP, ..., [[Dump debugging information]])
639
CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]])
640
{ rdump(&root_pool); cli_msg(0, ""); } ;
641
CF_CLI(DUMP SOCKETS,,, [[Dump open sockets]])
642
{ sk_dump_all(); cli_msg(0, ""); } ;
643
CF_CLI(DUMP EVENTS,,, [[Dump event log]])
644
{ io_log_dump(); cli_msg(0, ""); } ;
645
CF_CLI(DUMP INTERFACES,,, [[Dump interface information]])
646
{ if_dump_all(); cli_msg(0, ""); } ;
647
CF_CLI(DUMP NEIGHBORS,,, [[Dump neighbor cache]])
648
{ neigh_dump_all(); cli_msg(0, ""); } ;
649
CF_CLI(DUMP ATTRIBUTES,,, [[Dump attribute cache]])
650
{ rta_dump_all(); cli_msg(0, ""); } ;
651
CF_CLI(DUMP ROUTES,,, [[Dump routing table]])
652
{ rt_dump_all(); cli_msg(0, ""); } ;
653
CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]])
654
{ protos_dump_all(); cli_msg(0, ""); } ;
655

    
656
CF_CLI(EVAL, term, <expr>, [[Evaluate an expression]])
657
{ cmd_eval($2); } ;
658

    
659
CF_CLI_HELP(ECHO, ..., [[Control echoing of log messages]])
660
CF_CLI(ECHO, echo_mask echo_size, (all | off | { debug | trace | info | remote | warning | error | auth }) [<buffer-size>], [[Control echoing of log messages]]) {
661
  cli_set_log_echo(this_cli, $2, $3);
662
  cli_msg(0, "");
663
} ;
664

    
665
echo_mask:
666
   ALL { $$ = ~0; }
667
 | OFF { $$ = 0; }
668
 | '{' log_mask_list '}' { $$ = $2; }
669
 ;
670

    
671
echo_size:
672
   /* empty */ { $$ = 4096; }
673
 | NUM {
674
     if ($1 < 256 || $1 > 65536) cf_error("Invalid log buffer size");
675
     $$ = $1;
676
   }
677
 ;
678

    
679
CF_CLI(DISABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Disable protocol]])
680
{ proto_apply_cmd($2, proto_cmd_disable, 1, 0); } ;
681
CF_CLI(ENABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Enable protocol]])
682
{ proto_apply_cmd($2, proto_cmd_enable, 1, 0); } ;
683
CF_CLI(RESTART, proto_patt, <protocol> | \"<pattern>\" | all, [[Restart protocol]])
684
{ proto_apply_cmd($2, proto_cmd_restart, 1, 0); } ;
685
CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]])
686
{ proto_apply_cmd($2, proto_cmd_reload, 1, CMD_RELOAD); } ;
687
CF_CLI(RELOAD IN, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just imported routes)]])
688
{ proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_IN); } ;
689
CF_CLI(RELOAD OUT, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just exported routes)]])
690
{ proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_OUT); } ;
691

    
692
CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]])
693
CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | <pattern> | all) (all | off | { states | routes | filters | interfaces | events | packets }), [[Control protocol debugging via BIRD logs]])
694
{ proto_apply_cmd($2, proto_cmd_debug, 1, $3); } ;
695

    
696
CF_CLI_HELP(MRTDUMP, ..., [[Control protocol debugging via MRTdump files]])
697
CF_CLI(MRTDUMP, proto_patt mrtdump_mask, (<protocol> | <pattern> | all) (all | off | { states | messages }), [[Control protocol debugging via MRTdump format]])
698
{ proto_apply_cmd($2, proto_cmd_mrtdump, 1, $3); } ;
699

    
700
CF_CLI(RESTRICT,,,[[Restrict current CLI session to safe commands]])
701
{ this_cli->restricted = 1; cli_msg(16, "Access restricted"); } ;
702

    
703
proto_patt:
704
   SYM  { $$.ptr = $1; $$.patt = 0; }
705
 | ALL  { $$.ptr = NULL; $$.patt = 1; }
706
 | TEXT { $$.ptr = $1; $$.patt = 1; }
707
 ;
708

    
709
proto_patt2:
710
   SYM  { $$.ptr = $1; $$.patt = 0; }
711
 |      { $$.ptr = NULL; $$.patt = 1; }
712
 | TEXT { $$.ptr = $1; $$.patt = 1; }
713
 ;
714

    
715
CF_ADDTO(dynamic_attr, IGP_METRIC
716
	{ $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); })
717

    
718

    
719
CF_CODE
720

    
721
CF_END