File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird / nest / config.Y
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 19:50:23 2021 UTC (3 years, 4 months ago) by misho
Branches: bird, MAIN
CVS tags: v1_6_8p3, HEAD
bird 1.6.8

    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, DEFAULT, 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); this_proto->vrf_set = 1; }
  231:  | VRF DEFAULT { this_proto->vrf = NULL; this_proto->vrf_set = 1; }
  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: 
  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); } ;
  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>