Annotation of embedaddon/bird/nest/config.Y, revision 1.1.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>