Annotation of embedaddon/bird/nest/config.Y, revision 1.1.1.2
1.1 misho 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)
1.1.1.2 ! misho 58: CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, DEFAULT, TABLE, STATES, ROUTES, FILTERS)
1.1 misho 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; }
1.1.1.2 ! misho 230: | VRF text { this_proto->vrf = if_get_by_name($2); this_proto->vrf_set = 1; }
! 231: | VRF DEFAULT { this_proto->vrf = NULL; this_proto->vrf_set = 1; }
1.1 misho 232: | TABLE rtable { this_proto->table = $2; }
233: | ROUTER ID idval { this_proto->router_id = $3; }
234: | DESCRIPTION text { this_proto->dsc = $2; }
235: ;
236:
237: imexport:
238: FILTER filter { $$ = $2; }
239: | where_filter
240: | ALL { $$ = FILTER_ACCEPT; }
241: | NONE { $$ = FILTER_REJECT; }
242: ;
243:
244: limit_action:
245: /* default */ { $$ = PLA_DISABLE; }
246: | ACTION WARN { $$ = PLA_WARN; }
247: | ACTION BLOCK { $$ = PLA_BLOCK; }
248: | ACTION RESTART { $$ = PLA_RESTART; }
249: | ACTION DISABLE { $$ = PLA_DISABLE; }
250: ;
251:
252: limit_spec:
253: expr limit_action {
254: struct proto_limit *l = cfg_allocz(sizeof(struct proto_limit));
255: l->limit = $1;
256: l->action = $2;
257: $$ = l;
258: }
259: | OFF { $$ = NULL; }
260: ;
261:
262: rtable:
263: SYM {
264: if ($1->class != SYM_TABLE) cf_error("Table name expected");
265: $$ = $1->def;
266: }
267: ;
268:
269: CF_ADDTO(conf, debug_default)
270:
271: debug_default:
272: DEBUG PROTOCOLS debug_mask { new_config->proto_default_debug = $3; }
273: | DEBUG COMMANDS expr { new_config->cli_debug = $3; }
274: ;
275:
276: /* MRTDUMP PROTOCOLS is in systep/unix/config.Y */
277:
278: /* Interface patterns */
279:
280: iface_patt_node_init:
281: /* EMPTY */ {
282: struct iface_patt_node *ipn = cfg_allocz(sizeof(struct iface_patt_node));
283: add_tail(&this_ipatt->ipn_list, NODE ipn);
284: this_ipn = ipn;
285: }
286: ;
287:
288: iface_patt_node_body:
289: TEXT { this_ipn->pattern = $1; this_ipn->prefix = IPA_NONE; this_ipn->pxlen = 0; }
290: | prefix_or_ipa { this_ipn->pattern = NULL; this_ipn->prefix = $1.addr; this_ipn->pxlen = $1.len; }
291: | TEXT prefix_or_ipa { this_ipn->pattern = $1; this_ipn->prefix = $2.addr; this_ipn->pxlen = $2.len; }
292: ;
293:
294: iface_negate:
295: { this_ipn->positive = 1; }
296: | '-' { this_ipn->positive = 0; }
297: ;
298:
299: iface_patt_node:
300: iface_patt_node_init iface_negate iface_patt_node_body
301: ;
302:
303:
304: iface_patt_list:
305: iface_patt_node
306: | iface_patt_list ',' iface_patt_node
307: ;
308:
309: /* For name/mask-only iface patterns */
310: iface_patt_list_nopx: iface_patt_list { iface_patt_check(); }
311:
312: iface_patt_init: {
313: /* Generic this_ipatt init */
314: this_ipatt = cfg_allocz(sizeof(struct iface_patt));
315: init_list(&this_ipatt->ipn_list);
316: }
317: ;
318:
319: iface_patt:
320: iface_patt_init iface_patt_list
321: ;
322:
323: tos:
324: CLASS expr { $$ = $2 & 0xfc; if (($2 < 0) || ($2 > 255)) cf_error("TX class must be in range 0-255"); }
325: | DSCP expr { $$ = ($2 & 0x3f) << 2; if (($2 < 0) || ($2 > 63)) cf_error("TX DSCP must be in range 0-63"); }
326: ;
327:
328: /* Direct device route protocol */
329:
330: CF_ADDTO(proto, dev_proto '}')
331:
332: dev_proto_start: proto_start DIRECT {
333: this_proto = proto_config_new(&proto_device, $1);
334: init_list(&DIRECT_CFG->iface_list);
335: }
336: ;
337:
338: dev_proto:
339: dev_proto_start proto_name '{'
340: | dev_proto proto_item ';'
341: | dev_proto dev_iface_patt ';'
342: | dev_proto CHECK LINK bool ';' { DIRECT_CFG->check_link = $4; }
343: ;
344:
345: dev_iface_init:
346: /* EMPTY */ {
347: this_ipatt = cfg_allocz(sizeof(struct iface_patt));
348: add_tail(&DIRECT_CFG->iface_list, NODE this_ipatt);
349: init_list(&this_ipatt->ipn_list);
350: }
351: ;
352:
353: dev_iface_patt:
354: INTERFACE dev_iface_init iface_patt_list
355: ;
356:
357: /* Debug flags */
358:
359: debug_mask:
360: ALL { $$ = ~0; }
361: | OFF { $$ = 0; }
362: | '{' debug_list '}' { $$ = $2; }
363: ;
364:
365: debug_list:
366: debug_flag
367: | debug_list ',' debug_flag { $$ = $1 | $3; }
368: ;
369:
370: debug_flag:
371: STATES { $$ = D_STATES; }
372: | ROUTES { $$ = D_ROUTES; }
373: | FILTERS { $$ = D_FILTERS; }
374: | INTERFACES { $$ = D_IFACES; }
375: | EVENTS { $$ = D_EVENTS; }
376: | PACKETS { $$ = D_PACKETS; }
377: ;
378:
379: /* MRTDump flags */
380:
381: mrtdump_mask:
382: ALL { $$ = ~0; }
383: | OFF { $$ = 0; }
384: | '{' mrtdump_list '}' { $$ = $2; }
385: ;
386:
387: mrtdump_list:
388: mrtdump_flag
389: | mrtdump_list ',' mrtdump_flag { $$ = $1 | $3; }
390: ;
391:
392: mrtdump_flag:
393: STATES { $$ = MD_STATES; }
394: | MESSAGES { $$ = MD_MESSAGES; }
395: ;
396:
397: /* Password lists */
398:
399: password_list:
400: PASSWORDS '{' password_items '}'
401: | password_item
402: ;
403:
404: password_items:
405: /* empty */
406: | password_item ';' password_items
407: ;
408:
409: password_item:
410: password_item_begin '{' password_item_params '}'
411: | password_item_begin
412: ;
413:
414: password_item_begin:
415: PASSWORD text {
416: if (!this_p_list) {
417: this_p_list = cfg_alloc(sizeof(list));
418: init_list(this_p_list);
419: password_id = 1;
420: }
421: this_p_item = cfg_alloc(sizeof (struct password_item));
422: this_p_item->password = $2;
423: this_p_item->length = strlen($2);
424: this_p_item->genfrom = 0;
425: this_p_item->gento = TIME_INFINITY;
426: this_p_item->accfrom = 0;
427: this_p_item->accto = TIME_INFINITY;
428: this_p_item->id = password_id++;
429: this_p_item->alg = ALG_UNDEFINED;
430: add_tail(this_p_list, &this_p_item->n);
431: }
432: ;
433:
434: password_item_params:
435: /* empty */ { }
436: | GENERATE FROM datetime ';' password_item_params { this_p_item->genfrom = $3; }
437: | GENERATE TO datetime ';' password_item_params { this_p_item->gento = $3; }
438: | ACCEPT FROM datetime ';' password_item_params { this_p_item->accfrom = $3; }
439: | ACCEPT TO datetime ';' password_item_params { this_p_item->accto = $3; }
440: | FROM datetime ';' password_item_params { this_p_item->genfrom = this_p_item->accfrom = $2; }
441: | TO datetime ';' password_item_params { this_p_item->gento = this_p_item->accto = $2; }
442: | ID expr ';' password_item_params { this_p_item->id = $2; if ($2 <= 0) cf_error("Password ID has to be greated than zero."); }
443: | ALGORITHM password_algorithm ';' password_item_params { this_p_item->alg = $2; }
444: ;
445:
446: password_algorithm:
447: KEYED MD5 { $$ = ALG_MD5; }
448: | KEYED SHA1 { $$ = ALG_SHA1; }
449: | KEYED SHA256 { $$ = ALG_SHA256; }
450: | KEYED SHA384 { $$ = ALG_SHA384; }
451: | KEYED SHA512 { $$ = ALG_SHA512; }
452: | HMAC MD5 { $$ = ALG_HMAC_MD5; }
453: | HMAC SHA1 { $$ = ALG_HMAC_SHA1; }
454: | HMAC SHA256 { $$ = ALG_HMAC_SHA256; }
455: | HMAC SHA384 { $$ = ALG_HMAC_SHA384; }
456: | HMAC SHA512 { $$ = ALG_HMAC_SHA512; }
457: ;
458:
459: /* Core commands */
460: CF_CLI_HELP(SHOW, ..., [[Show status information]])
461:
462: CF_CLI(SHOW STATUS,,, [[Show router status]])
463: { cmd_show_status(); } ;
464:
465: CF_CLI(SHOW MEMORY,,, [[Show memory usage]])
466: { cmd_show_memory(); } ;
467:
468: CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
469: { proto_apply_cmd($3, proto_cmd_show, 0, 0); } ;
470:
471: CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]])
472: { proto_apply_cmd($4, proto_cmd_show, 0, 1); } ;
473:
474: optsym:
475: SYM
476: | /* empty */ { $$ = NULL; }
477: ;
478:
479: CF_CLI(SHOW INTERFACES,,, [[Show network interfaces]])
480: { if_show(); } ;
481:
482: CF_CLI(SHOW INTERFACES SUMMARY,,, [[Show summary of network interfaces]])
483: { if_show_summary(); } ;
484:
485: CF_CLI_HELP(SHOW ROUTE, ..., [[Show routing table]])
486: 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]])
487: { rt_show($3); } ;
488:
489: r_args:
490: /* empty */ {
491: $$ = cfg_allocz(sizeof(struct rt_show_data));
492: $$->pxlen = 256;
493: $$->filter = FILTER_ACCEPT;
494: }
495: | r_args prefix {
496: $$ = $1;
497: if ($$->pxlen != 256) cf_error("Only one prefix expected");
498: $$->prefix = $2.addr;
499: $$->pxlen = $2.len;
500: }
501: | r_args FOR prefix_or_ipa {
502: $$ = $1;
503: if ($$->pxlen != 256) cf_error("Only one prefix expected");
504: $$->prefix = $3.addr;
505: $$->pxlen = $3.len;
506: $$->show_for = 1;
507: }
508: | r_args TABLE SYM {
509: $$ = $1;
510: if ($3->class != SYM_TABLE) cf_error("%s is not a table", $3->name);
511: $$->table = ((struct rtable_config *)$3->def)->table;
512: }
513: | r_args FILTER filter {
514: $$ = $1;
515: if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
516: $$->filter = $3;
517: }
518: | r_args where_filter {
519: $$ = $1;
520: if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
521: $$->filter = $2;
522: }
523: | r_args ALL {
524: $$ = $1;
525: $$->verbose = 1;
526: }
527: | r_args PRIMARY {
528: $$ = $1;
529: $$->primary_only = 1;
530: }
531: | r_args FILTERED {
532: $$ = $1;
533: $$->filtered = 1;
534: }
535: | r_args export_mode SYM {
536: struct proto_config *c = (struct proto_config *) $3->def;
537: $$ = $1;
538: if ($$->export_mode) cf_error("Protocol specified twice");
539: if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
540: $$->export_mode = $2;
541: $$->export_protocol = c->proto;
542: $$->running_on_config = c->proto->cf->global;
543: }
544: | r_args PROTOCOL SYM {
545: struct proto_config *c = (struct proto_config *) $3->def;
546: $$ = $1;
547: if ($$->show_protocol) cf_error("Protocol specified twice");
548: if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
549: $$->show_protocol = c->proto;
550: $$->running_on_config = c->proto->cf->global;
551: }
552: | r_args STATS {
553: $$ = $1;
554: $$->stats = 1;
555: }
556: | r_args COUNT {
557: $$ = $1;
558: $$->stats = 2;
559: }
560: ;
561:
562: export_mode:
563: PREEXPORT { $$ = RSEM_PREEXPORT; }
564: | EXPORT { $$ = RSEM_EXPORT; }
565: | NOEXPORT { $$ = RSEM_NOEXPORT; }
566: ;
567:
568:
569: CF_CLI_HELP(SHOW ROA, ..., [[Show ROA table]])
570: CF_CLI(SHOW ROA, roa_args, [<prefix> | in <prefix> | for <prefix>] [as <num>] [table <t>], [[Show ROA table]])
571: { roa_show($3); } ;
572:
573: roa_args:
574: /* empty */ {
575: $$ = cfg_allocz(sizeof(struct roa_show_data));
576: $$->mode = ROA_SHOW_ALL;
577: $$->table = roa_table_default;
578: if (roa_table_default == NULL)
579: cf_error("No ROA table defined");
580: }
581: | roa_args roa_mode prefix {
582: $$ = $1;
583: if ($$->mode != ROA_SHOW_ALL) cf_error("Only one prefix expected");
584: $$->prefix = $3.addr;
585: $$->pxlen = $3.len;
586: $$->mode = $2;
587: }
588: | roa_args AS NUM {
589: $$ = $1;
590: $$->asn = $3;
591: }
592: | roa_args TABLE SYM {
593: $$ = $1;
594: if ($3->class != SYM_ROA) cf_error("%s is not a ROA table", $3->name);
595: $$->table = ((struct roa_table_config *)$3->def)->table;
596: }
597: ;
598:
599: roa_mode:
600: { $$ = ROA_SHOW_PX; }
601: | IN { $$ = ROA_SHOW_IN; }
602: | FOR { $$ = ROA_SHOW_FOR; }
603: ;
604:
605:
606: CF_CLI_HELP(SHOW SYMBOLS, ..., [[Show all known symbolic names]])
607: CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|roa|<symbol>], [[Show all known symbolic names]])
608: { cmd_show_symbols($3); } ;
609:
610: sym_args:
611: /* empty */ {
612: $$ = cfg_allocz(sizeof(struct sym_show_data));
613: }
614: | sym_args TABLE { $$ = $1; $$->type = SYM_TABLE; }
615: | sym_args FUNCTION { $$ = $1; $$->type = SYM_FUNCTION; }
616: | sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; }
617: | sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; }
618: | sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; }
619: | sym_args ROA { $$ = $1; $$->type = SYM_ROA; }
620: | sym_args SYM { $$ = $1; $$->sym = $2; }
621: ;
622:
623:
624: roa_table_arg:
625: /* empty */ {
626: if (roa_table_default == NULL)
627: cf_error("No ROA table defined");
628: $$ = roa_table_default;
629: }
630: | TABLE SYM {
631: if ($2->class != SYM_ROA)
632: cf_error("%s is not a ROA table", $2->name);
633: $$ = ((struct roa_table_config *)$2->def)->table;
634: }
635: ;
636:
637: CF_CLI_HELP(ADD, roa ..., [[Add ROA record]])
638: CF_CLI(ADD ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Add ROA record]])
639: {
640: if (! cli_access_restricted())
641: { roa_add_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
642: };
643:
644: CF_CLI_HELP(DELETE, roa ..., [[Delete ROA record]])
645: CF_CLI(DELETE ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Delete ROA record]])
646: {
647: if (! cli_access_restricted())
648: { roa_delete_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
649: };
650:
651: CF_CLI_HELP(FLUSH, roa [table <name>], [[Removes all dynamic ROA records]])
652: CF_CLI(FLUSH ROA, roa_table_arg, [table <name>], [[Removes all dynamic ROA records]])
653: {
654: if (! cli_access_restricted())
655: { roa_flush($3, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
656: };
657:
658:
659: CF_CLI_HELP(DUMP, ..., [[Dump debugging information]])
660: CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]])
661: { rdump(&root_pool); cli_msg(0, ""); } ;
662: CF_CLI(DUMP SOCKETS,,, [[Dump open sockets]])
663: { sk_dump_all(); cli_msg(0, ""); } ;
664: CF_CLI(DUMP EVENTS,,, [[Dump event log]])
665: { io_log_dump(); cli_msg(0, ""); } ;
666: CF_CLI(DUMP INTERFACES,,, [[Dump interface information]])
667: { if_dump_all(); cli_msg(0, ""); } ;
668: CF_CLI(DUMP NEIGHBORS,,, [[Dump neighbor cache]])
669: { neigh_dump_all(); cli_msg(0, ""); } ;
670: CF_CLI(DUMP ATTRIBUTES,,, [[Dump attribute cache]])
671: { rta_dump_all(); cli_msg(0, ""); } ;
672: CF_CLI(DUMP ROUTES,,, [[Dump routing table]])
673: { rt_dump_all(); cli_msg(0, ""); } ;
674: CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]])
675: { protos_dump_all(); cli_msg(0, ""); } ;
676:
677: CF_CLI(EVAL, term, <expr>, [[Evaluate an expression]])
678: { cmd_eval($2); } ;
679:
680: CF_CLI_HELP(ECHO, ..., [[Control echoing of log messages]])
681: CF_CLI(ECHO, echo_mask echo_size, (all | off | { debug|trace|info|remote|warning|error|auth [, ...] }) [<buffer-size>], [[Control echoing of log messages]]) {
682: cli_set_log_echo(this_cli, $2, $3);
683: cli_msg(0, "");
684: } ;
685:
686: echo_mask:
687: ALL { $$ = ~0; }
688: | OFF { $$ = 0; }
689: | '{' log_mask_list '}' { $$ = $2; }
690: ;
691:
692: echo_size:
693: /* empty */ { $$ = 4096; }
694: | NUM {
695: if ($1 < 256 || $1 > 65536) cf_error("Invalid log buffer size");
696: $$ = $1;
697: }
698: ;
699:
1.1.1.2 ! misho 700: CF_CLI(DISABLE, proto_patt text_or_none, (<protocol> | \"<pattern>\" | all) [message], [[Disable protocol]])
! 701: { proto_apply_cmd($2, proto_cmd_disable, 1, (uintptr_t) $3); } ;
! 702: CF_CLI(ENABLE, proto_patt text_or_none, (<protocol> | \"<pattern>\" | all) [message], [[Enable protocol]])
! 703: { proto_apply_cmd($2, proto_cmd_enable, 1, (uintptr_t) $3); } ;
! 704: CF_CLI(RESTART, proto_patt text_or_none, (<protocol> | \"<pattern>\" | all) [message], [[Restart protocol]])
! 705: { proto_apply_cmd($2, proto_cmd_restart, 1, (uintptr_t) $3); } ;
1.1 misho 706: CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]])
707: { proto_apply_cmd($2, proto_cmd_reload, 1, CMD_RELOAD); } ;
708: CF_CLI(RELOAD IN, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just imported routes)]])
709: { proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_IN); } ;
710: CF_CLI(RELOAD OUT, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just exported routes)]])
711: { proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_OUT); } ;
712:
713: CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]])
714: CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | \"<pattern>\" | all) (all | off | { states|routes|filters|interfaces|events|packets [, ...] }), [[Control protocol debugging via BIRD logs]])
715: { proto_apply_cmd($2, proto_cmd_debug, 1, $3); } ;
716:
717: CF_CLI_HELP(MRTDUMP, ..., [[Control protocol debugging via MRTdump files]])
718: CF_CLI(MRTDUMP, proto_patt mrtdump_mask, (<protocol> | \"<pattern>\" | all) (all | off | { states|messages [, ...] }), [[Control protocol debugging via MRTdump format]])
719: { proto_apply_cmd($2, proto_cmd_mrtdump, 1, $3); } ;
720:
721: CF_CLI(RESTRICT,,,[[Restrict current CLI session to safe commands]])
722: { this_cli->restricted = 1; cli_msg(16, "Access restricted"); } ;
723:
724: proto_patt:
725: SYM { $$.ptr = $1; $$.patt = 0; }
726: | ALL { $$.ptr = NULL; $$.patt = 1; }
727: | TEXT { $$.ptr = $1; $$.patt = 1; }
728: ;
729:
730: proto_patt2:
731: SYM { $$.ptr = $1; $$.patt = 0; }
732: | { $$.ptr = NULL; $$.patt = 1; }
733: | TEXT { $$.ptr = $1; $$.patt = 1; }
734: ;
735:
736: CF_ADDTO(dynamic_attr, IGP_METRIC
737: { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); })
738:
739:
740: CF_CODE
741:
742: CF_END
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>