Annotation of embedaddon/bird2/conf/confbase.Y, revision 1.1

1.1     ! misho       1: /*
        !             2:  *     BIRD -- Configuration Parser Top
        !             3:  *
        !             4:  *     (c) 1998--2000 Martin Mares <mj@ucw.cz>
        !             5:  *
        !             6:  *     Can be freely distributed and used under the terms of the GNU GPL.
        !             7:  */
        !             8: 
        !             9: CF_HDR
        !            10: 
        !            11: #define PARSER 1
        !            12: 
        !            13: #include "nest/bird.h"
        !            14: #include "conf/conf.h"
        !            15: #include "lib/resource.h"
        !            16: #include "lib/socket.h"
        !            17: #include "lib/timer.h"
        !            18: #include "lib/string.h"
        !            19: #include "nest/protocol.h"
        !            20: #include "nest/iface.h"
        !            21: #include "nest/route.h"
        !            22: #include "nest/cli.h"
        !            23: #include "filter/filter.h"
        !            24: 
        !            25: /* FIXME: Turn on YYERROR_VERBOSE and work around lots of bison bugs? */
        !            26: 
        !            27: CF_DEFINES
        !            28: 
        !            29: static void
        !            30: check_u16(uint val)
        !            31: {
        !            32:   if (val > 0xFFFF)
        !            33:     cf_error("Value %u out of range (0-65535)", val);
        !            34: }
        !            35: 
        !            36: #define cf_assert(cond, ...) do { if (!(cond)) cf_error(__VA_ARGS__); } while (0)
        !            37: static inline void cf_assert_symbol(const struct symbol *sym, uint class) {
        !            38:   switch (class) {
        !            39:     case SYM_PROTO: cf_assert(sym->class == SYM_PROTO, "Protocol name required"); break;
        !            40:     case SYM_TEMPLATE: cf_assert(sym->class == SYM_TEMPLATE, "Protocol template name required"); break;
        !            41:     case SYM_FUNCTION: cf_assert(sym->class == SYM_FUNCTION, "Function name required"); break;
        !            42:     case SYM_FILTER: cf_assert(sym->class == SYM_FILTER, "Filter name required"); break;
        !            43:     case SYM_TABLE: cf_assert(sym->class == SYM_TABLE, "Table name required"); break;
        !            44:     case SYM_ATTRIBUTE: cf_assert(sym->class == SYM_ATTRIBUTE, "Custom attribute name required"); break;
        !            45:     case SYM_VARIABLE: cf_assert((sym->class & ~0xff) == SYM_VARIABLE, "Variable name required"); break;
        !            46:     case SYM_CONSTANT: cf_assert((sym->class & ~0xff) == SYM_CONSTANT, "Constant name required"); break;
        !            47:     default: bug("This shall not happen");
        !            48:   }
        !            49: }
        !            50: 
        !            51: CF_DECLS
        !            52: 
        !            53: %union {
        !            54:   uint i;
        !            55:   u32 i32;
        !            56:   u64 i64;
        !            57:   ip_addr a;
        !            58:   ip4_addr ip4;
        !            59:   ip6_addr ip6;
        !            60:   net_addr net;
        !            61:   net_addr *net_ptr;
        !            62:   struct symbol *s;
        !            63:   char *t;
        !            64:   struct rtable_config *r;
        !            65:   struct channel_config *cc;
        !            66:   struct f_inst *x;
        !            67:   struct {
        !            68:     struct f_inst *begin, *end;
        !            69:   } xp;
        !            70:   enum filter_return fret;
        !            71:   enum ec_subtype ecs;
        !            72:   struct f_dynamic_attr fda;
        !            73:   struct f_static_attr fsa;
        !            74:   struct f_lval flv;
        !            75:   struct f_line *fl;
        !            76:   const struct filter *f;
        !            77:   struct f_tree *e;
        !            78:   struct f_trie *trie;
        !            79:   struct f_val v;
        !            80:   struct password_item *p;
        !            81:   struct rt_show_data *ra;
        !            82:   struct sym_show_data *sd;
        !            83:   struct lsadb_show_data *ld;
        !            84:   struct mrt_dump_data *md;
        !            85:   struct iface *iface;
        !            86:   void *g;
        !            87:   btime time;
        !            88:   struct f_prefix px;
        !            89:   struct proto_spec ps;
        !            90:   struct channel_limit cl;
        !            91:   struct timeformat *tf;
        !            92:   mpls_label_stack *mls;
        !            93: }
        !            94: 
        !            95: %token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT
        !            96: %token GEQ LEQ NEQ AND OR
        !            97: %token PO PC
        !            98: %token <i> NUM ENUM
        !            99: %token <ip4> IP4
        !           100: %token <ip6> IP6
        !           101: %token <i64> VPN_RD
        !           102: %token <s> CF_SYM_KNOWN CF_SYM_UNDEFINED
        !           103: %token <t> TEXT
        !           104: %type <iface> ipa_scope
        !           105: 
        !           106: %type <i> expr bool pxlen4
        !           107: %type <time> expr_us time
        !           108: %type <a> ipa
        !           109: %type <net> net_ip4_ net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa
        !           110: %type <net_ptr> net_ net_any net_vpn4_ net_vpn6_ net_vpn_ net_roa4_ net_roa6_ net_roa_ net_ip6_sadr_ net_mpls_
        !           111: %type <mls> label_stack_start label_stack
        !           112: 
        !           113: %type <t> text opttext
        !           114: %type <s> symbol
        !           115: 
        !           116: %nonassoc PREFIX_DUMMY
        !           117: %left AND OR
        !           118: %nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA PO PC
        !           119: %left '+' '-'
        !           120: %left '*' '/' '%'
        !           121: %left '!'
        !           122: %nonassoc '.'
        !           123: 
        !           124: %start config
        !           125: 
        !           126: CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, VPN, MPLS, FROM)
        !           127: 
        !           128: CF_GRAMMAR
        !           129: 
        !           130: /* Basic config file structure */
        !           131: 
        !           132: config: conf_entries END { return 0; }
        !           133:  | CLI_MARKER cli_cmd { return 0; }
        !           134:  ;
        !           135: 
        !           136: conf_entries:
        !           137:    /* EMPTY */
        !           138:  | conf_entries conf
        !           139:  ;
        !           140: 
        !           141: conf: ';' ;
        !           142: 
        !           143: 
        !           144: /* Constant expressions */
        !           145: 
        !           146: conf: definition ;
        !           147: 
        !           148: definition:
        !           149:    DEFINE symbol '=' term ';' {
        !           150:      struct f_val *val = cfg_alloc(sizeof(struct f_val));
        !           151:      if (f_eval(f_linearize($4), cfg_mem, val) > F_RETURN) cf_error("Runtime error");
        !           152:      cf_define_symbol($2, SYM_CONSTANT | val->type, val, val);
        !           153:    }
        !           154:  ;
        !           155: 
        !           156: expr:
        !           157:    NUM
        !           158:  | '(' term ')' { $$ = f_eval_int(f_linearize($2)); }
        !           159:  | CF_SYM_KNOWN {
        !           160:      if ($1->class != (SYM_CONSTANT | T_INT)) cf_error("Number constant expected");
        !           161:      $$ = SYM_VAL($1).i; }
        !           162:  ;
        !           163: 
        !           164: expr_us:
        !           165:    expr S  { $$ = $1 S_; }
        !           166:  | expr MS { $$ = $1 MS_; }
        !           167:  | expr US { $$ = $1 US_; }
        !           168:  ;
        !           169: 
        !           170: symbol: CF_SYM_UNDEFINED | CF_SYM_KNOWN ;
        !           171: 
        !           172: /* Switches */
        !           173: 
        !           174: bool:
        !           175:    expr { $$ = !!$1; }
        !           176:  | ON { $$ = 1; }
        !           177:  | YES { $$ = 1; }
        !           178:  | OFF { $$ = 0; }
        !           179:  | NO { $$ = 0; }
        !           180:  | /* Silence means agreement */ { $$ = 1; }
        !           181:  ;
        !           182: 
        !           183: 
        !           184: /* Addresses */
        !           185: 
        !           186: ipa:
        !           187:    IP4 { $$ = ipa_from_ip4($1); }
        !           188:  | IP6 { $$ = ipa_from_ip6($1); }
        !           189:  | CF_SYM_KNOWN {
        !           190:      if ($1->class != (SYM_CONSTANT | T_IP)) cf_error("IP address constant expected");
        !           191:      $$ = SYM_VAL($1).ip;
        !           192:    }
        !           193:  ;
        !           194: 
        !           195: ipa_scope:
        !           196:    /* empty */ { $$ = NULL; }
        !           197:  | '%' symbol { $$ = if_get_by_name($2->name); }
        !           198:  ;
        !           199: 
        !           200: 
        !           201: /* Networks - internal */
        !           202: 
        !           203: pxlen4:
        !           204:    '/' NUM {
        !           205:      if ($2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %u", $2);
        !           206:      $$ = $2;
        !           207:    }
        !           208:  ;
        !           209: 
        !           210: net_ip4_: IP4 pxlen4
        !           211: {
        !           212:   net_fill_ip4(&($$), $1, $2);
        !           213: 
        !           214:   net_addr_ip4 *n = (void *) &($$);
        !           215:   if (!net_validate_ip4(n))
        !           216:     cf_error("Invalid IPv4 prefix %I4/%d, maybe you wanted %I4/%d",
        !           217:             n->prefix, n->pxlen, ip4_and(n->prefix, ip4_mkmask(n->pxlen)), n->pxlen);
        !           218: };
        !           219: 
        !           220: net_ip6_: IP6 '/' NUM
        !           221: {
        !           222:   if ($3 > IP6_MAX_PREFIX_LENGTH)
        !           223:     cf_error("Invalid prefix length %u", $3);
        !           224: 
        !           225:   net_fill_ip6(&($$), $1, $3);
        !           226: 
        !           227:   net_addr_ip6 *n = (void *) &($$);
        !           228:   if (!net_validate_ip6(n))
        !           229:     cf_error("Invalid IPv6 prefix %I6/%d, maybe you wanted %I6/%d",
        !           230:             n->prefix, n->pxlen, ip6_and(n->prefix, ip6_mkmask(n->pxlen)), n->pxlen);
        !           231: };
        !           232: 
        !           233: net_ip6_sadr_: IP6 '/' NUM FROM IP6 '/' NUM
        !           234: {
        !           235:   if ($3 > IP6_MAX_PREFIX_LENGTH)
        !           236:     cf_error("Invalid prefix length %u", $3);
        !           237: 
        !           238:   if ($7 > IP6_MAX_PREFIX_LENGTH)
        !           239:     cf_error("Invalid prefix length %u", $7);
        !           240: 
        !           241:   $$ = cfg_alloc(sizeof(net_addr_ip6_sadr));
        !           242:   net_fill_ip6_sadr($$, $1, $3, $5, $7);
        !           243: 
        !           244:   net_addr_ip6_sadr *n = (void *) $$;
        !           245:   if (!net_validate_ip6_sadr(n))
        !           246:     cf_error("Invalid SADR IPv6 prefix %I6/%d from %I6/%d, maybe you wanted %I6/%d from %I6/%d",
        !           247:             n->dst_prefix, n->dst_pxlen, n->src_prefix, n->src_pxlen,
        !           248:             ip6_and(n->dst_prefix, ip6_mkmask(n->dst_pxlen)), n->dst_pxlen,
        !           249:             ip6_and(n->src_prefix, ip6_mkmask(n->src_pxlen)), n->src_pxlen);
        !           250: };
        !           251: 
        !           252: net_vpn4_: VPN_RD net_ip4_
        !           253: {
        !           254:   $$ = cfg_alloc(sizeof(net_addr_vpn4));
        !           255:   net_fill_vpn4($$, net4_prefix(&$2), net4_pxlen(&$2), $1);
        !           256: }
        !           257: 
        !           258: net_vpn6_: VPN_RD net_ip6_
        !           259: {
        !           260:   $$ = cfg_alloc(sizeof(net_addr_vpn6));
        !           261:   net_fill_vpn6($$, net6_prefix(&$2), net6_pxlen(&$2), $1);
        !           262: }
        !           263: 
        !           264: net_roa4_: net_ip4_ MAX NUM AS NUM
        !           265: {
        !           266:   $$ = cfg_alloc(sizeof(net_addr_roa4));
        !           267:   net_fill_roa4($$, net4_prefix(&$1), net4_pxlen(&$1), $3, $5);
        !           268:   if ($3 < net4_pxlen(&$1) || $3 > IP4_MAX_PREFIX_LENGTH)
        !           269:     cf_error("Invalid max prefix length %u", $3);
        !           270: };
        !           271: 
        !           272: net_roa6_: net_ip6_ MAX NUM AS NUM
        !           273: {
        !           274:   $$ = cfg_alloc(sizeof(net_addr_roa6));
        !           275:   net_fill_roa6($$, net6_prefix(&$1), net6_pxlen(&$1), $3, $5);
        !           276:   if ($3 < net6_pxlen(&$1) || $3 > IP6_MAX_PREFIX_LENGTH)
        !           277:     cf_error("Invalid max prefix length %u", $3);
        !           278: };
        !           279: 
        !           280: net_mpls_: MPLS NUM
        !           281: {
        !           282:   $$ = cfg_alloc(sizeof(net_addr_roa6));
        !           283:   net_fill_mpls($$, $2);
        !           284: }
        !           285: 
        !           286: net_ip_: net_ip4_ | net_ip6_ ;
        !           287: net_vpn_: net_vpn4_ | net_vpn6_ ;
        !           288: net_roa_: net_roa4_ | net_roa6_ ;
        !           289: 
        !           290: net_:
        !           291:    net_ip_ { $$ = cfg_alloc($1.length); net_copy($$, &($1)); }
        !           292:  | net_vpn_
        !           293:  | net_roa_
        !           294:  | net_flow_
        !           295:  | net_ip6_sadr_
        !           296:  | net_mpls_
        !           297:  ;
        !           298: 
        !           299: 
        !           300: /* Networks - regular */
        !           301: 
        !           302: net_ip6:
        !           303:    net_ip6_
        !           304:  | CF_SYM_KNOWN {
        !           305:      if (($1->class != (SYM_CONSTANT | T_NET)) || (SYM_VAL($1).net->type != NET_IP6))
        !           306:        cf_error("IPv6 network constant expected");
        !           307:      $$ = * SYM_VAL($1).net;
        !           308:    }
        !           309:  ;
        !           310: 
        !           311: net_ip:
        !           312:    net_ip_
        !           313:  | CF_SYM_KNOWN {
        !           314:      if (($1->class != (SYM_CONSTANT | T_NET)) || !net_is_ip(SYM_VAL($1).net))
        !           315:        cf_error("IP network constant expected");
        !           316:      $$ = * SYM_VAL($1).net;
        !           317:    }
        !           318:  ;
        !           319: 
        !           320: net_any:
        !           321:    net_
        !           322:  | CF_SYM_KNOWN {
        !           323:      if ($1->class != (SYM_CONSTANT | T_NET))
        !           324:        cf_error("Network constant expected");
        !           325:      $$ = (net_addr *) SYM_VAL($1).net; /* Avoid const warning */
        !           326:    }
        !           327:  ;
        !           328: 
        !           329: net_or_ipa:
        !           330:    net_ip4_
        !           331:  | net_ip6_
        !           332:  | IP4 { net_fill_ip4(&($$), $1, IP4_MAX_PREFIX_LENGTH); }
        !           333:  | IP6 { net_fill_ip6(&($$), $1, IP6_MAX_PREFIX_LENGTH); }
        !           334:  | CF_SYM_KNOWN {
        !           335:      if ($1->class == (SYM_CONSTANT | T_IP))
        !           336:        net_fill_ip_host(&($$), SYM_VAL($1).ip);
        !           337:      else if (($1->class == (SYM_CONSTANT | T_NET)) && net_is_ip(SYM_VAL($1).net))
        !           338:        $$ = * SYM_VAL($1).net;
        !           339:      else
        !           340:        cf_error("IP address or network constant expected");
        !           341:    }
        !           342:  ;
        !           343: 
        !           344: label_stack_start: NUM
        !           345: {
        !           346:   $$ = cfg_allocz(sizeof(mpls_label_stack));
        !           347:   $$->len = 1;
        !           348:   $$->stack[0] = $1;
        !           349: };
        !           350: 
        !           351: label_stack:
        !           352:     label_stack_start
        !           353:   | label_stack '/' NUM {
        !           354:     if ($1->len >= MPLS_MAX_LABEL_STACK)
        !           355:       cf_error("Too many labels in stack");
        !           356:     $1->stack[$1->len++] = $3;
        !           357:     $$ = $1;
        !           358:   }
        !           359: ;
        !           360: 
        !           361: time:
        !           362:    TEXT {
        !           363:      $$ = tm_parse_time($1);
        !           364:      if (!$$)
        !           365:        cf_error("Invalid date/time");
        !           366:    }
        !           367:  ;
        !           368: 
        !           369: text:
        !           370:    TEXT
        !           371:  | CF_SYM_KNOWN {
        !           372:      if ($1->class != (SYM_CONSTANT | T_STRING)) cf_error("String constant expected");
        !           373:      $$ = SYM_VAL($1).s;
        !           374:    }
        !           375:  ;
        !           376: 
        !           377: opttext:
        !           378:     TEXT
        !           379:  | /* empty */ { $$ = NULL; }
        !           380:  ;
        !           381: 
        !           382: 
        !           383: CF_CODE
        !           384: 
        !           385: CF_END

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