]> git.ipfire.org Git - thirdparty/bird.git/blobdiff - nest/config.Y
Filter: Some people can't pronounce "postfixify" correctly. Let's try "linearize...
[thirdparty/bird.git] / nest / config.Y
index 044aba2b3095bef90832d6094fa71185b68d6385..e4dedc66fa1c78e94622bddcd26c5df05c9547c6 100644 (file)
@@ -66,7 +66,7 @@ CF_DECLS
 
 CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
 CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, TABLE, STATES, ROUTES, FILTERS)
-CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6)
+CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS)
 CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
 CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
 CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512)
@@ -77,7 +77,7 @@ CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US)
 CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS)
 
 /* For r_args_channel */
-CF_KEYWORDS(IPV4, IPV4_MC, IPV4_MPLS, IPV6, IPV6_MC, IPV6_MPLS, VPN4, VPN4_MC, VPN4_MPLS, VPN6, VPN6_MC, VPN6_MPLS, ROA4, ROA6, FLOW4, FLOW6, MPLS, PRI, SEC)
+CF_KEYWORDS(IPV4, IPV4_MC, IPV4_MPLS, IPV6, IPV6_MC, IPV6_MPLS, IPV6_SADR, VPN4, VPN4_MC, VPN4_MPLS, VPN6, VPN6_MC, VPN6_MPLS, ROA4, ROA6, FLOW4, FLOW6, MPLS, PRI, SEC)
 
 CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
        RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE, BABEL)
@@ -88,7 +88,7 @@ CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
 %type <i32> idval
 %type <f> imexport
 %type <r> rtable
-%type <s> optsym
+%type <s> optproto
 %type <ra> r_args
 %type <sd> sym_args
 %type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode limit_action net_type table_sorted tos password_algorithm
@@ -103,7 +103,7 @@ CF_GRAMMAR
 
 /* Setting of router ID */
 
-CF_ADDTO(conf, rtrid)
+conf: rtrid ;
 
 rtrid:
    ROUTER ID idval ';' { new_config->router_id = $3; }
@@ -112,9 +112,9 @@ rtrid:
 
 idval:
    NUM { $$ = $1; }
- | '(' term ')' { $$ = f_eval_int($2); }
+ | '(' term ')' { $$ = f_eval_int(f_linearize($2)); }
  | IP4 { $$ = ip4_to_u32($1); }
- | SYM {
+ | CF_SYM_KNOWN {
      if ($1->class == (SYM_CONSTANT | T_INT) || $1->class == (SYM_CONSTANT | T_QUAD))
        $$ = SYM_VAL($1).i;
      else if (($1->class == (SYM_CONSTANT | T_IP)) && ipa_is_ip4(SYM_VAL($1).ip))
@@ -124,7 +124,7 @@ idval:
    }
  ;
 
-CF_ADDTO(conf, gr_opts)
+conf: gr_opts ;
 
 gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->gr_wait = $4; } ;
 
@@ -134,6 +134,7 @@ gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->gr_wait = $4; } ;
 net_type:
    IPV4 { $$ = NET_IP4; }
  | IPV6 { $$ = NET_IP6; }
+ | IPV6 SADR { $$ = NET_IP6_SADR; }
  | VPN4 { $$ = NET_VPN4; }
  | VPN6 { $$ = NET_VPN6; }
  | ROA4 { $$ = NET_ROA4; }
@@ -143,19 +144,19 @@ net_type:
  | MPLS { $$ = NET_MPLS; }
  ;
 
-CF_ENUM(T_ENUM_NETTYPE, NET_, IP4, IP6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6)
+CF_ENUM(T_ENUM_NETTYPE, NET_, IP4, IP6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, IP6_SADR)
 
 
 /* Creation of routing tables */
 
-CF_ADDTO(conf, table)
+conf: table ;
 
 table_sorted:
-          { $$ = 0; }
+         { $$ = 0; }
  | SORTED { $$ = 1; }
  ;
 
-table: net_type TABLE SYM table_sorted {
+table: net_type TABLE CF_SYM_VOID table_sorted {
    struct rtable_config *cf;
    cf = rt_new_table($3, $1);
    cf->sorted = $4;
@@ -165,7 +166,7 @@ table: net_type TABLE SYM table_sorted {
 
 /* Definition of protocols */
 
-CF_ADDTO(conf, proto { proto_postconfig(); })
+conf: proto { proto_postconfig(); } ;
 
 proto_start:
    PROTOCOL { $$ = SYM_PROTO; }
@@ -176,28 +177,30 @@ proto_name:
    /* EMPTY */ {
      struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
      s->class = this_proto->class;
-     s->def = this_proto;
+     s->proto = this_proto;
      this_proto->name = s->name;
      }
- | SYM {
-     cf_define_symbol($1, this_proto->class, this_proto);
+ | CF_SYM_VOID {
+     cf_define_symbol($1, this_proto->class, proto, this_proto);
      this_proto->name = $1->name;
    }
- | FROM SYM {
+ | FROM CF_SYM_KNOWN {
+     if (($2->class != SYM_TEMPLATE) && ($2->class != SYM_PROTO)) cf_error("Template or protocol name expected");
+
      struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
      s->class = this_proto->class;
-     s->def = this_proto;
+     s->proto = this_proto;
      this_proto->name = s->name;
 
-     if (($2->class != SYM_TEMPLATE) && ($2->class != SYM_PROTO)) cf_error("Template or protocol name expected");
-     proto_copy_config(this_proto, $2->def);
+     proto_copy_config(this_proto, $2->proto);
    }
- | SYM FROM SYM {
-     cf_define_symbol($1, this_proto->class, this_proto);
+ | CF_SYM_VOID FROM CF_SYM_KNOWN {
+     if (($3->class != SYM_TEMPLATE) && ($3->class != SYM_PROTO)) cf_error("Template or protocol name expected");
+
+     cf_define_symbol($1, this_proto->class, proto, this_proto);
      this_proto->name = $1->name;
 
-     if (($3->class != SYM_TEMPLATE) && ($3->class != SYM_PROTO)) cf_error("Template or protocol name expected");
-     proto_copy_config(this_proto, $3->def);
+     proto_copy_config(this_proto, $3->proto);
    }
  ;
 
@@ -253,12 +256,7 @@ channel_end:
 proto_channel: channel_start channel_opt_list channel_end;
 
 
-rtable:
-   SYM {
-     if ($1->class != SYM_TABLE) cf_error("Table expected");
-     $$ = $1->def;
-   }
- ;
+rtable: CF_SYM_KNOWN { cf_assert_symbol($1, SYM_TABLE); $$ = $1->table; } ;
 
 imexport:
    FILTER filter { $$ = $2; }
@@ -281,7 +279,7 @@ limit_spec:
  ;
 
 
-CF_ADDTO(conf, debug_default)
+conf: debug_default ;
 
 debug_default:
    DEBUG PROTOCOLS debug_mask { new_config->proto_default_debug = $3; }
@@ -290,7 +288,7 @@ debug_default:
 
 /* MRTDUMP PROTOCOLS is in systep/unix/config.Y */
 
-CF_ADDTO(conf, timeformat_base)
+conf: timeformat_base ;
 
 timeformat_which:
    ROUTE { $$ = &new_config->tf_route; }
@@ -366,7 +364,7 @@ tos:
 
 /* Direct device route protocol */
 
-CF_ADDTO(proto, dev_proto '}')
+proto: dev_proto '}' ;
 
 dev_proto_start: proto_start DIRECT {
      this_proto = proto_config_new(&proto_device, $1);
@@ -454,9 +452,9 @@ password_item:
 password_item_begin:
    PASSWORD text {
      if (!this_p_list) {
-       this_p_list = cfg_alloc(sizeof(list));
-       init_list(this_p_list);
-        password_id = 1;
+       this_p_list = cfg_alloc(sizeof(list));
+       init_list(this_p_list);
+       password_id = 1;
      }
      this_p_item = cfg_alloc(sizeof (struct password_item));
      this_p_item->password = $2;
@@ -511,8 +509,8 @@ CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing
 CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]])
 { proto_apply_cmd($4, proto_cmd_show, 0, 1); } ;
 
-optsym:
-   SYM
+optproto:
+   CF_SYM_KNOWN { cf_assert_symbol($1, SYM_PROTO); $$ = $1; }
  | /* empty */ { $$ = NULL; }
  ;
 
@@ -531,6 +529,7 @@ r_args:
      $$ = cfg_allocz(sizeof(struct rt_show_data));
      init_list(&($$->tables));
      $$->filter = FILTER_ACCEPT;
+     $$->running_on_config = new_config->fallback;
    }
  | r_args net_any {
      $$ = $1;
@@ -543,10 +542,10 @@ r_args:
      $$->show_for = 1;
      $$->addr = $3;
    }
- | r_args TABLE SYM {
+ | r_args TABLE CF_SYM_KNOWN {
+     cf_assert_symbol($3, SYM_TABLE);
      $$ = $1;
-     if ($3->class != SYM_TABLE) cf_error("%s is not a table", $3->name);
-     rt_show_add_table($$, ((struct rtable_config *)$3->def)->table);
+     rt_show_add_table($$, $3->table->table);
      $$->tables_defined_by = RSD_TDB_DIRECT;
    }
  | r_args TABLE ALL {
@@ -556,6 +555,17 @@ r_args:
        rt_show_add_table($$, t->table);
      $$->tables_defined_by = RSD_TDB_ALL;
    }
+ | r_args IMPORT TABLE CF_SYM_KNOWN '.' r_args_channel {
+     cf_assert_symbol($4, SYM_PROTO);
+     $$ = $1;
+     struct proto_config *cf = $4->proto;
+     if (!cf->proto) cf_error("%s is not a protocol", $4->name);
+     struct channel *c = proto_find_channel_by_name(cf->proto, $6);
+     if (!c) cf_error("Channel %s.%s not found", $4->name, $6);
+     if (!c->in_table) cf_error("No import table in channel %s.%s", $4->name, $6);
+     rt_show_add_table($$, c->in_table);
+     $$->tables_defined_by = RSD_TDB_DIRECT;
+   }
  | r_args FILTER filter {
      $$ = $1;
      if ($$->filter != FILTER_ACCEPT) cf_error("Filter specified twice");
@@ -578,34 +588,34 @@ r_args:
      $$ = $1;
      $$->filtered = 1;
    }
- | r_args export_mode SYM {
-     struct proto_config *c = (struct proto_config *) $3->def;
+ | r_args export_mode CF_SYM_KNOWN {
+     cf_assert_symbol($3, SYM_PROTO);
+     struct proto_config *c = (struct proto_config *) $3->proto;
      $$ = $1;
      if ($$->export_mode) cf_error("Export specified twice");
-     if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
+     if (!c->proto) cf_error("%s is not a protocol", $3->name);
      $$->export_mode = $2;
      $$->export_protocol = c->proto;
-     $$->running_on_config = c->proto->cf->global;
      $$->tables_defined_by = RSD_TDB_INDIRECT;
    }
- | r_args export_mode SYM '.' r_args_channel {
-     struct proto_config *c = (struct proto_config *) $3->def;
+ | r_args export_mode CF_SYM_KNOWN '.' r_args_channel {
+     cf_assert_symbol($3, SYM_PROTO);
+     struct proto_config *c = (struct proto_config *) $3->proto;
      $$ = $1;
      if ($$->export_mode) cf_error("Export specified twice");
-     if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
+     if (!c->proto) cf_error("%s is not a protocol", $3->name);
      $$->export_mode = $2;
      $$->export_channel = proto_find_channel_by_name(c->proto, $5);
      if (!$$->export_channel) cf_error("Export channel not found");
-     $$->running_on_config = c->proto->cf->global;
      $$->tables_defined_by = RSD_TDB_INDIRECT;
    }
- | r_args PROTOCOL SYM {
-     struct proto_config *c = (struct proto_config *) $3->def;
+ | r_args PROTOCOL CF_SYM_KNOWN {
+     cf_assert_symbol($3, SYM_PROTO);
+     struct proto_config *c = (struct proto_config *) $3->proto;
      $$ = $1;
      if ($$->show_protocol) cf_error("Protocol specified twice");
-     if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
+     if (!c->proto) cf_error("%s is not a protocol", $3->name);
      $$->show_protocol = c->proto;
-     $$->running_on_config = c->proto->cf->global;
      $$->tables_defined_by = RSD_TDB_INDIRECT;
    }
  | r_args STATS {
@@ -625,6 +635,7 @@ r_args_for:
   }
  | net_vpn4_
  | net_vpn6_
+ | net_ip6_sadr_
  | VPN_RD IP4 {
     $$ = cfg_alloc(sizeof(net_addr_vpn4));
     net_fill_vpn4($$, $2, IP4_MAX_PREFIX_LENGTH, $1);
@@ -633,7 +644,11 @@ r_args_for:
     $$ = cfg_alloc(sizeof(net_addr_vpn6));
     net_fill_vpn6($$, $2, IP6_MAX_PREFIX_LENGTH, $1);
   }
- | SYM {
+ | IP6 FROM IP6 {
+    $$ = cfg_alloc(sizeof(net_addr_ip6_sadr));
+    net_fill_ip6_sadr($$, $1, IP6_MAX_PREFIX_LENGTH, $3, IP6_MAX_PREFIX_LENGTH);
+  }
+ | CF_SYM_KNOWN {
      if ($1->class == (SYM_CONSTANT | T_IP))
      {
        $$ = cfg_alloc(ipa_is_ip4(SYM_VAL($1).ip) ? sizeof(net_addr_ip4) : sizeof(net_addr_ip6));
@@ -642,7 +657,7 @@ r_args_for:
      else if (($1->class == (SYM_CONSTANT | T_NET)) && net_type_match(SYM_VAL($1).net, NB_IP | NB_VPN))
        $$ = (net_addr *) SYM_VAL($1).net; /* Avoid const warning */
      else
-       cf_error("IP address or network expected");
+       cf_error("IP address or network constant expected");
    }
  ;
 
@@ -666,6 +681,7 @@ r_args_channel:
  | IPV6                { $$ = "ipv6"; }
  | IPV6_MC     { $$ = "ipv6-mc"; }
  | IPV6_MPLS   { $$ = "ipv6-mpls"; }
+ | IPV6_SADR   { $$ = "ipv6-sadr"; }
  | VPN4                { $$ = "vpn4"; }
  | VPN4_MC     { $$ = "vpn4-mc"; }
  | VPN4_MPLS   { $$ = "vpn4-mpls"; }
@@ -694,7 +710,7 @@ sym_args:
  | sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; }
  | sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; }
  | sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; }
- | sym_args SYM { $$ = $1; $$->sym = $2; }
+ | sym_args symbol { $$ = $1; $$->sym = $2; }
  ;
 
 
@@ -717,7 +733,7 @@ CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]])
 { protos_dump_all(); cli_msg(0, ""); } ;
 
 CF_CLI(EVAL, term, <expr>, [[Evaluate an expression]])
-{ cmd_eval($2); } ;
+{ cmd_eval(f_linearize($2)); } ;
 
 CF_CLI_HELP(ECHO, ..., [[Control echoing of log messages]])
 CF_CLI(ECHO, echo_mask echo_size, (all | off | { debug|trace|info|remote|warning|error|auth [, ...] }) [<buffer-size>], [[Control echoing of log messages]]) {
@@ -764,19 +780,18 @@ CF_CLI(RESTRICT,,,[[Restrict current CLI session to safe commands]])
 { this_cli->restricted = 1; cli_msg(16, "Access restricted"); } ;
 
 proto_patt:
-   SYM  { $$.ptr = $1; $$.patt = 0; }
+   CF_SYM_KNOWN { cf_assert_symbol($1, SYM_PROTO); $$.ptr = $1; $$.patt = 0; }
  | ALL  { $$.ptr = NULL; $$.patt = 1; }
  | TEXT { $$.ptr = $1; $$.patt = 1; }
  ;
 
 proto_patt2:
-   SYM  { $$.ptr = $1; $$.patt = 0; }
+   CF_SYM_KNOWN { cf_assert_symbol($1, SYM_PROTO); $$.ptr = $1; $$.patt = 0; }
  |      { $$.ptr = NULL; $$.patt = 1; }
  | TEXT { $$.ptr = $1; $$.patt = 1; }
  ;
 
-CF_ADDTO(dynamic_attr, IGP_METRIC
-       { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); })
+dynamic_attr: IGP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, 0, T_INT, EA_GEN_IGP_METRIC); } ;
 
 
 CF_CODE