Annotation of embedaddon/bird/nest/config.Y, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>