Statistics
| Branch: | Revision:

iof-bird-daemon / nest / config.Y @ 508d9360

History | View | Annotate | Download (18.5 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 inline void
28
reset_passwords(void)
29
{
30
  this_p_list = NULL;
31
}
32

    
33
static inline list *
34
get_passwords(void)
35
{
36
  list *rv = this_p_list;
37
  this_p_list = NULL;
38
  return rv;
39
}
40

    
41
#define DIRECT_CFG ((struct rt_dev_config *) this_proto)
42

    
43
CF_DECLS
44

    
45
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
46
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
47
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
48
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
49
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE, ROA, MAX, FLUSH)
50
CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SORTED)
51
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
52

    
53
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
54
	RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
55
CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINED)
56
CF_ENUM(T_ENUM_RTC, RTC_, UNICAST, BROADCAST, MULTICAST, ANYCAST)
57
CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT, MULTIPATH)
58
CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
59

    
60
%type <i32> idval
61
%type <f> imexport
62
%type <r> rtable
63
%type <s> optsym
64
%type <ra> r_args
65
%type <ro> roa_args
66
%type <rot> roa_table_arg
67
%type <sd> sym_args
68
%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_or_preexport roa_mode limit_action tab_sorted tos
69
%type <ps> proto_patt proto_patt2
70
%type <g> limit_spec
71

    
72
CF_GRAMMAR
73

    
74
/* Setting of router ID */
75

    
76
CF_ADDTO(conf, rtrid)
77

    
78
rtrid: 
79
   ROUTER ID idval ';' { new_config->router_id = $3; }
80
 | ROUTER ID FROM iface_patt ';' { new_config->router_id_from = this_ipatt; }
81
 ;
82

    
83
idval:
84
   NUM { $$ = $1; }
85
 | RTRID
86
 | IPA {
87
#ifndef IPV6
88
     $$ = ipa_to_u32($1);
89
#else
90
     cf_error("Router IDs must be entered as hexadecimal numbers or IPv4 addresses in IPv6 version");
91
#endif
92
   }
93
 ;
94

    
95

    
96
CF_ADDTO(conf, listen)
97

    
98
listen: LISTEN BGP listen_opts ';' ;
99

    
100
listen_opts:
101
   /* Nothing */
102
 | listen_opts listen_opt
103
 ;
104

    
105
listen_opt: 
106
   ADDRESS ipa { new_config->listen_bgp_addr = $2; }
107
 | PORT expr { new_config->listen_bgp_port = $2; }
108
 | V6ONLY { new_config->listen_bgp_flags = 0; }
109
 | DUAL { new_config->listen_bgp_flags = 1; }
110
 ;
111

    
112

    
113
/* Creation of routing tables */
114

    
115
tab_sorted:
116
          { $$ = 0; }
117
 | SORTED { $$ = 1; }
118
 ;
119

    
120
CF_ADDTO(conf, newtab)
121

    
122
newtab: TABLE SYM tab_sorted {
123
   struct rtable_config *cf;
124
   cf = rt_new_table($2);
125
   cf->sorted = $3;
126
   }
127
 ;
128

    
129
CF_ADDTO(conf, roa_table)
130

    
131
roa_table_start: ROA TABLE SYM {
132
  this_roa_table = roa_new_table_config($3);
133
};
134

    
135
roa_table_opts:
136
   /* empty */
137
 | roa_table_opts ROA prefix MAX NUM AS NUM ';' {
138
     roa_add_item_config(this_roa_table, $3.addr, $3.len, $5, $7);
139
   }
140
 ;
141

    
142
roa_table:
143
   roa_table_start
144
 | roa_table_start '{' roa_table_opts '}'
145
 ;
146

    
147
/* Definition of protocols */
148

    
149
CF_ADDTO(conf, proto)
150

    
151
proto_start:
152
   PROTOCOL { $$ = SYM_PROTO; }
153
 | TEMPLATE { $$ = SYM_TEMPLATE; }
154
 ;
155

    
156
proto_name:
157
   /* EMPTY */ {
158
     struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
159
     s->class = this_proto->class;
160
     s->def = this_proto;
161
     this_proto->name = s->name;
162
     }
163
 | SYM {
164
     cf_define_symbol($1, this_proto->class, this_proto);
165
     this_proto->name = $1->name;
166
   }
167
 | SYM FROM SYM {
168
     if (($3->class != SYM_TEMPLATE) && ($3->class != SYM_PROTO)) cf_error("Template or protocol name expected");
169

    
170
     cf_define_symbol($1, this_proto->class, this_proto);
171
     this_proto->name = $1->name;
172

    
173
     proto_copy_config(this_proto, $3->def);
174
   }
175
 ;
176

    
177
proto_item:
178
   /* EMPTY */
179
 | PREFERENCE expr {
180
     if ($2 < 0 || $2 > 0xFFFF) cf_error("Invalid preference");
181
     this_proto->preference = $2;
182
   }
183
 | DISABLED bool { this_proto->disabled = $2; }
184
 | DEBUG debug_mask { this_proto->debug = $2; }
185
 | MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; }
186
 | IMPORT imexport { this_proto->in_filter = $2; }
187
 | EXPORT imexport { this_proto->out_filter = $2; }
188
 | RECEIVE LIMIT limit_spec { this_proto->rx_limit = $3; }
189
 | IMPORT LIMIT limit_spec { this_proto->in_limit = $3; }
190
 | EXPORT LIMIT limit_spec { this_proto->out_limit = $3; }
191
 | IMPORT KEEP FILTERED bool { this_proto->in_keep_filtered = $4; }
192
 | TABLE rtable { this_proto->table = $2; }
193
 | ROUTER ID idval { this_proto->router_id = $3; }
194
 | DESCRIPTION TEXT { this_proto->dsc = $2; }
195
 ;
196

    
197
imexport:
198
   FILTER filter { $$ = $2; }
199
 | where_filter
200
 | ALL { $$ = FILTER_ACCEPT; }
201
 | NONE { $$ = FILTER_REJECT; }
202
 ;
203

    
204
limit_action:
205
   /* default */ { $$ = PLA_DISABLE; }
206
 | ACTION WARN { $$ = PLA_WARN; }
207
 | ACTION BLOCK { $$ = PLA_BLOCK; }
208
 | ACTION RESTART { $$ = PLA_RESTART; }
209
 | ACTION DISABLE { $$ = PLA_DISABLE; }
210
 ;
211

    
212
limit_spec:
213
   expr limit_action {
214
     struct proto_limit *l = cfg_allocz(sizeof(struct proto_limit));
215
     l->limit = $1;
216
     l->action = $2;
217
     $$ = l;
218
   }
219
 | OFF { $$ = NULL; }
220
 ;
221

    
222
rtable:
223
   SYM {
224
     if ($1->class != SYM_TABLE) cf_error("Table name expected");
225
     $$ = $1->def;
226
   }
227
 ;
228

    
229
CF_ADDTO(conf, debug_default)
230

    
231
debug_default:
232
   DEBUG PROTOCOLS debug_mask { new_config->proto_default_debug = $3; }
233
 | DEBUG COMMANDS expr { new_config->cli_debug = $3; }
234
 ;
235

    
236
/* MRTDUMP PROTOCOLS is in systep/unix/config.Y */
237

    
238
/* Interface patterns */
239

    
240
iface_patt_node_init:
241
   /* EMPTY */ {
242
     struct iface_patt_node *ipn = cfg_allocz(sizeof(struct iface_patt_node));
243
     add_tail(&this_ipatt->ipn_list, NODE ipn);
244
     this_ipn = ipn;
245
   }
246
 ;
247

    
248
iface_patt_node_body:
249
   TEXT { this_ipn->pattern = $1; this_ipn->prefix = IPA_NONE; this_ipn->pxlen = 0; }
250
 | prefix_or_ipa { this_ipn->pattern = NULL; this_ipn->prefix = $1.addr; this_ipn->pxlen = $1.len; }
251
 | TEXT prefix_or_ipa { this_ipn->pattern = $1; this_ipn->prefix = $2.addr; this_ipn->pxlen = $2.len; }
252
 ;
253

    
254
iface_negate:
255
       { this_ipn->positive = 1; }
256
 | '-' { this_ipn->positive = 0; }
257
 ;
258

    
259
iface_patt_node:
260
   iface_patt_node_init iface_negate iface_patt_node_body 
261
 ;
262

    
263

    
264
iface_patt_list:
265
   iface_patt_node
266
 | iface_patt_list ',' iface_patt_node
267
 ;
268

    
269
iface_patt_init: {
270
   /* Generic this_ipatt init */
271
   this_ipatt = cfg_allocz(sizeof(struct iface_patt));
272
   init_list(&this_ipatt->ipn_list);
273
 }
274
 ;
275

    
276
iface_patt:
277
   iface_patt_init iface_patt_list
278
 ;
279

    
280
tos:
281
   CLASS expr { $$ = $2 & 0xfc;        if (($2 < 0) || ($2 > 255)) cf_error("TX class must be in range 0-255"); }
282
 | DSCP expr  { $$ = ($2 & 0x3f) << 2; if (($2 < 0) || ($2 > 63))  cf_error("TX DSCP must be in range 0-63"); }
283
 ;
284

    
285
/* Direct device route protocol */
286

    
287
CF_ADDTO(proto, dev_proto '}')
288

    
289
dev_proto_start: proto_start DIRECT {
290
     this_proto = proto_config_new(&proto_device, sizeof(struct rt_dev_config), $1);
291
     init_list(&DIRECT_CFG->iface_list);
292
   }
293
 ;
294

    
295
dev_proto:
296
   dev_proto_start proto_name '{'
297
 | dev_proto proto_item ';'
298
 | dev_proto dev_iface_patt ';'
299
 ;
300

    
301
dev_iface_init:
302
   /* EMPTY */ {
303
     this_ipatt = cfg_allocz(sizeof(struct iface_patt));
304
     add_tail(&DIRECT_CFG->iface_list, NODE this_ipatt);
305
     init_list(&this_ipatt->ipn_list);
306
   }
307
 ;
308

    
309
dev_iface_patt:
310
   INTERFACE dev_iface_init iface_patt_list
311
 ;
312

    
313
/* Debug flags */
314

    
315
debug_mask:
316
   ALL { $$ = ~0; }
317
 | OFF { $$ = 0; }
318
 | '{' debug_list '}' { $$ = $2; }
319
 ;
320

    
321
debug_list:
322
   debug_flag
323
 | debug_list ',' debug_flag { $$ = $1 | $3; }
324
 ;
325

    
326
debug_flag:
327
   STATES	{ $$ = D_STATES; }
328
 | ROUTES	{ $$ = D_ROUTES; }
329
 | FILTERS	{ $$ = D_FILTERS; }
330
 | INTERFACES	{ $$ = D_IFACES; }
331
 | EVENTS	{ $$ = D_EVENTS; }
332
 | PACKETS	{ $$ = D_PACKETS; }
333
 ;
334

    
335
/* MRTDump flags */
336

    
337
mrtdump_mask:
338
   ALL { $$ = ~0; }
339
 | OFF { $$ = 0; }
340
 | '{' mrtdump_list '}' { $$ = $2; }
341
 ;
342

    
343
mrtdump_list:
344
   mrtdump_flag
345
 | mrtdump_list ',' mrtdump_flag { $$ = $1 | $3; }
346
 ;
347

    
348
mrtdump_flag:
349
   STATES	{ $$ = MD_STATES; }
350
 | MESSAGES	{ $$ = MD_MESSAGES; }
351
 ;
352

    
353
/* Password lists */
354

    
355
password_list:
356
   PASSWORDS '{' password_items '}'
357
 | password_item
358
;
359

    
360
password_items: 
361
    /* empty */
362
  | password_item ';' password_items
363
;
364

    
365
password_item:
366
    password_item_begin '{' password_item_params '}'
367
  | password_item_begin
368
;
369

    
370
password_item_begin:
371
   PASSWORD TEXT {
372
     if (!this_p_list) {
373
     	this_p_list = cfg_alloc(sizeof(list));
374
     	init_list(this_p_list);
375
        password_id = 1;
376
     }
377
     this_p_item = cfg_alloc(sizeof (struct password_item));
378
     this_p_item->password = $2;
379
     this_p_item->genfrom = 0;
380
     this_p_item->gento = TIME_INFINITY;
381
     this_p_item->accfrom = 0;
382
     this_p_item->accto = TIME_INFINITY;
383
     this_p_item->id = password_id++;
384
     add_tail(this_p_list, &this_p_item->n);
385
   }
386
;
387

    
388
password_item_params:
389
   /* empty */ { } 
390
 | GENERATE FROM datetime ';' password_item_params { this_p_item->genfrom = $3; }
391
 | GENERATE TO datetime ';' password_item_params { this_p_item->gento = $3; }
392
 | ACCEPT FROM datetime ';' password_item_params { this_p_item->accfrom = $3; }
393
 | ACCEPT TO datetime ';' password_item_params { this_p_item->accto = $3; }
394
 | ID expr ';' password_item_params { this_p_item->id = $2; if ($2 <= 0) cf_error("Password ID has to be greated than zero."); }
395
 ;
396

    
397

    
398

    
399
/* Core commands */
400
CF_CLI_HELP(SHOW, ..., [[Show status information]])
401

    
402
CF_CLI(SHOW STATUS,,, [[Show router status]])
403
{ cmd_show_status(); } ;
404

    
405
CF_CLI(SHOW MEMORY,,, [[Show memory usage]])
406
{ cmd_show_memory(); } ;
407

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

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

    
414
optsym:
415
   SYM
416
 | /* empty */ { $$ = NULL; }
417
 ;
418

    
419
CF_CLI(SHOW INTERFACES,,, [[Show network interfaces]])
420
{ if_show(); } ;
421

    
422
CF_CLI(SHOW INTERFACES SUMMARY,,, [[Show summary of network interfaces]])
423
{ if_show_summary(); } ;
424

    
425
CF_CLI_HELP(SHOW ROUTE, ..., [[Show routing table]])
426
CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>] [table <t>] [filter <f>|where <cond>] [all] [primary] [filtered] [(export|preexport) <p>] [protocol <p>] [stats|count]]], [[Show routing table]])
427
{ rt_show($3); } ;
428

    
429
r_args:
430
   /* empty */ {
431
     $$ = cfg_allocz(sizeof(struct rt_show_data));
432
     $$->pxlen = 256;
433
     $$->filter = FILTER_ACCEPT;
434
   }
435
 | r_args prefix {
436
     $$ = $1;
437
     if ($$->pxlen != 256) cf_error("Only one prefix expected");
438
     $$->prefix = $2.addr;
439
     $$->pxlen = $2.len;
440
   }
441
 | r_args FOR prefix_or_ipa {
442
     $$ = $1;
443
     if ($$->pxlen != 256) cf_error("Only one prefix expected");
444
     $$->prefix = $3.addr;
445
     $$->pxlen = $3.len;
446
     $$->show_for = 1;
447
   }
448
 | r_args TABLE SYM {
449
     $$ = $1;
450
     if ($3->class != SYM_TABLE) cf_error("%s is not a table", $3->name);
451
     $$->table = ((struct rtable_config *)$3->def)->table;
452
   }
453
 | r_args FILTER filter {
454
     $$ = $1;
455
     if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
456
     $$->filter = $3;
457
   }
458
 | r_args where_filter {
459
     $$ = $1;
460
     if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
461
     $$->filter = $2;
462
   }
463
 | r_args ALL {
464
     $$ = $1;
465
     $$->verbose = 1;
466
   }
467
 | r_args PRIMARY {
468
     $$ = $1;
469
     $$->primary_only = 1;
470
   }
471
 | r_args FILTERED {
472
     $$ = $1;
473
     $$->filtered = 1;
474
   }
475
 | r_args export_or_preexport SYM {
476
     struct proto_config *c = (struct proto_config *) $3->def;
477
     $$ = $1;
478
     if ($$->export_mode) cf_error("Protocol specified twice");
479
     if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
480
     $$->export_mode = $2;
481
     $$->primary_only = 1;
482
     $$->export_protocol = c->proto;
483
     $$->running_on_config = c->proto->cf->global;
484
   }
485
 | r_args PROTOCOL SYM {
486
     struct proto_config *c = (struct proto_config *) $3->def;
487
     $$ = $1;
488
     if ($$->show_protocol) cf_error("Protocol specified twice");
489
     if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
490
     $$->show_protocol = c->proto;
491
     $$->running_on_config = c->proto->cf->global;
492
   }
493
 | r_args STATS {
494
     $$ = $1;
495
     $$->stats = 1;
496
   }
497
 | r_args COUNT {
498
     $$ = $1;
499
     $$->stats = 2;
500
   }
501
 ;
502

    
503
export_or_preexport:
504
   PREEXPORT { $$ = 1; }
505
 | EXPORT { $$ = 2; }
506
 ;
507

    
508

    
509
CF_CLI_HELP(SHOW ROA, ..., [[Show ROA table]])
510
CF_CLI(SHOW ROA, roa_args, [<prefix> | in <prefix> | for <prefix>] [as <num>] [table <t>], [[Show ROA table]])
511
{ roa_show($3); } ;
512

    
513
roa_args:
514
   /* empty */ {
515
     $$ = cfg_allocz(sizeof(struct roa_show_data));
516
     $$->mode = ROA_SHOW_ALL;
517
     $$->table = roa_table_default;
518
     if (roa_table_default == NULL)
519
       cf_error("No ROA table defined");
520
   }
521
 | roa_args roa_mode prefix {
522
     $$ = $1;
523
     if ($$->mode != ROA_SHOW_ALL) cf_error("Only one prefix expected");
524
     $$->prefix = $3.addr;
525
     $$->pxlen = $3.len;
526
     $$->mode = $2;
527
   }
528
 | roa_args AS NUM {
529
     $$ = $1;
530
     $$->asn = $3;
531
   }
532
 | roa_args TABLE SYM {
533
     $$ = $1;
534
     if ($3->class != SYM_ROA) cf_error("%s is not a ROA table", $3->name);
535
     $$->table = ((struct roa_table_config *)$3->def)->table;
536
   }
537
 ;
538

    
539
roa_mode:
540
       { $$ = ROA_SHOW_PX; }
541
 | IN  { $$ = ROA_SHOW_IN; }
542
 | FOR { $$ = ROA_SHOW_FOR; }
543
 ;
544

    
545

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

    
550
sym_args:
551
   /* empty */ {
552
     $$ = cfg_allocz(sizeof(struct sym_show_data));
553
   }
554
 | sym_args TABLE { $$ = $1; $$->type = SYM_TABLE; }
555
 | sym_args FUNCTION { $$ = $1; $$->type = SYM_FUNCTION; }
556
 | sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; }
557
 | sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; }
558
 | sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; }
559
 | sym_args ROA { $$ = $1; $$->type = SYM_ROA; }
560
 | sym_args SYM { $$ = $1; $$->sym = $2; }
561
 ;
562

    
563

    
564
roa_table_arg:
565
   /* empty */ { 
566
     if (roa_table_default == NULL)
567
       cf_error("No ROA table defined");
568
     $$ = roa_table_default;
569
   }
570
 | TABLE SYM {
571
     if ($2->class != SYM_ROA)
572
       cf_error("%s is not a ROA table", $2->name);
573
     $$ = ((struct roa_table_config *)$2->def)->table;
574
   }
575
 ;
576

    
577
CF_CLI_HELP(ADD, roa ..., [[Add ROA record]])
578
CF_CLI(ADD ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Add ROA record]])
579
{
580
  if (! cli_access_restricted())
581
    { roa_add_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
582
};
583

    
584
CF_CLI_HELP(DELETE, roa ..., [[Delete ROA record]])
585
CF_CLI(DELETE ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Delete ROA record]])
586
{
587
  if (! cli_access_restricted())
588
    { roa_delete_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
589
};
590

    
591
CF_CLI_HELP(FLUSH, roa [table <name>], [[Removes all dynamic ROA records]])
592
CF_CLI(FLUSH ROA, roa_table_arg, [table <name>], [[Removes all dynamic ROA records]])
593
{
594
  if (! cli_access_restricted())
595
    { roa_flush($3, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
596
};
597

    
598

    
599
CF_CLI_HELP(DUMP, ..., [[Dump debugging information]])
600
CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]])
601
{ rdump(&root_pool); cli_msg(0, ""); } ;
602
CF_CLI(DUMP SOCKETS,,, [[Dump open sockets]])
603
{ sk_dump_all(); cli_msg(0, ""); } ;
604
CF_CLI(DUMP INTERFACES,,, [[Dump interface information]])
605
{ if_dump_all(); cli_msg(0, ""); } ;
606
CF_CLI(DUMP NEIGHBORS,,, [[Dump neighbor cache]])
607
{ neigh_dump_all(); cli_msg(0, ""); } ;
608
CF_CLI(DUMP ATTRIBUTES,,, [[Dump attribute cache]])
609
{ rta_dump_all(); cli_msg(0, ""); } ;
610
CF_CLI(DUMP ROUTES,,, [[Dump routing table]])
611
{ rt_dump_all(); cli_msg(0, ""); } ;
612
CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]])
613
{ protos_dump_all(); cli_msg(0, ""); } ;
614

    
615
CF_CLI(EVAL, term, <expr>, [[Evaluate an expression]])
616
{ cmd_eval($2); } ;
617

    
618
CF_CLI_HELP(ECHO, ..., [[Control echoing of log messages]])
619
CF_CLI(ECHO, echo_mask echo_size, (all | off | { debug | trace | info | remote | warning | error | auth }) [<buffer-size>], [[Control echoing of log messages]]) {
620
  cli_set_log_echo(this_cli, $2, $3);
621
  cli_msg(0, "");
622
} ;
623

    
624
echo_mask:
625
   ALL { $$ = ~0; }
626
 | OFF { $$ = 0; }
627
 | '{' log_mask_list '}' { $$ = $2; }
628
 ;
629

    
630
echo_size:
631
   /* empty */ { $$ = 4096; }
632
 | NUM {
633
     if ($1 < 256 || $1 > 65536) cf_error("Invalid log buffer size");
634
     $$ = $1;
635
   }
636
 ;
637

    
638
CF_CLI(DISABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Disable protocol]])
639
{ proto_apply_cmd($2, proto_cmd_disable, 1, 0); } ;
640
CF_CLI(ENABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Enable protocol]])
641
{ proto_apply_cmd($2, proto_cmd_enable, 1, 0); } ;
642
CF_CLI(RESTART, proto_patt, <protocol> | \"<pattern>\" | all, [[Restart protocol]])
643
{ proto_apply_cmd($2, proto_cmd_restart, 1, 0); } ;
644
CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]])
645
{ proto_apply_cmd($2, proto_cmd_reload, 1, CMD_RELOAD); } ;
646
CF_CLI(RELOAD IN, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just imported routes)]])
647
{ proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_IN); } ;
648
CF_CLI(RELOAD OUT, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just exported routes)]])
649
{ proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_OUT); } ;
650

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

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

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

    
662
proto_patt:
663
   SYM  { $$.ptr = $1; $$.patt = 0; }
664
 | ALL  { $$.ptr = NULL; $$.patt = 1; }
665
 | TEXT { $$.ptr = $1; $$.patt = 1; }
666
 ;
667

    
668
proto_patt2:
669
   SYM  { $$.ptr = $1; $$.patt = 0; }
670
 |      { $$.ptr = NULL; $$.patt = 1; }
671
 | TEXT { $$.ptr = $1; $$.patt = 1; }
672
 ;
673

    
674
CF_ADDTO(dynamic_attr, IGP_METRIC
675
	{ $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); })
676

    
677

    
678
CF_CODE
679

    
680
CF_END