diff --git a/conf/confbase.Y b/conf/confbase.Y index 195efff1..40ea16de 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -123,7 +123,7 @@ CF_DECLS %type bytestring %type symbol symbol_known toksym -%type bytestring_text +%type bytestring_text text_or_ipa %type bytestring_expr %nonassoc PREFIX_DUMMY @@ -412,6 +412,24 @@ opttext: | /* empty */ { $$ = NULL; } ; +text_or_ipa: + TEXT { $$.type = T_STRING; $$.val.s = $1; } + | IP4 { $$.type = T_IP; $$.val.ip = ipa_from_ip4($1); } + | IP6 { $$.type = T_IP; $$.val.ip = ipa_from_ip6($1); } + | CF_SYM_KNOWN { + if (($1->class == (SYM_CONSTANT | T_STRING)) || + ($1->class == (SYM_CONSTANT | T_IP))) + $$ = *($1->val); + else + cf_error("String or IP constant expected"); + } + | '(' term ')' { + $$ = *cf_eval($2, T_VOID); + if (($$.type != T_BYTESTRING) && ($$.type != T_STRING)) + cf_error("Bytestring or string value expected"); + } + ; + bytestring: BYTETEXT | bytestring_expr { $$ = cf_eval($1, T_BYTESTRING)->val.bs; } diff --git a/filter/config.Y b/filter/config.Y index 238a1c46..53884bb7 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -337,7 +337,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, %nonassoc ELSE %type cmds_int cmd_prep -%type term term_bs cmd cmd_var cmds cmds_scoped constant constructor print_list var var_init var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail +%type term term_bs cmd cmd_var cmds cmds_scoped constant constructor print_list var var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail %type static_attr %type filter where_filter %type filter_body function_body @@ -913,16 +913,16 @@ print_list: /* EMPTY */ { $$ = NULL; } } ; -var_init: - /* empty */ { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { }); } - | '=' term { $$ = $2; } - ; - var: - type symbol var_init ';' { + type symbol '=' term ';' { struct symbol *sym = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope)); - $$ = f_new_inst(FI_VAR_INIT, $3, sym); + $$ = f_new_inst(FI_VAR_INIT, $4, sym); } + | type symbol ';' { + struct symbol *sym = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope)); + $$ = f_new_inst(FI_VAR_INIT0, sym); + } + ; for_var: type symbol { $$ = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope)); } diff --git a/filter/f-inst.c b/filter/f-inst.c index f467ea47..bc5477a3 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -513,6 +513,7 @@ RESULT(T_BOOL, i, ipa_is_ip4(v1.val.ip)); } + /* Add initialized variable */ INST(FI_VAR_INIT, 1, 0) { NEVER_CONSTANT; ARG_ANY(1); @@ -525,6 +526,17 @@ fstk->vcnt = pos + 1; } + /* Add uninitialized variable */ + INST(FI_VAR_INIT0, 0, 0) { + NEVER_CONSTANT; + SYMBOL; + + /* New variable is always the last on stack */ + uint pos = curline.vbase + sym->offset; + fstk->vstk[pos] = (struct f_val) { }; + fstk->vcnt = pos + 1; + } + /* Set to indirect value prepared in v1 */ INST(FI_VAR_SET, 1, 0) { NEVER_CONSTANT; diff --git a/filter/test.conf b/filter/test.conf index 812191f1..20d67f43 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -740,8 +740,8 @@ bt_test_suite(t_prefix_set, "Testing prefix sets"); */ function t_prefix6() -prefix px; { + prefix px; px = 1020::/18; bt_assert(format(px) = "1020::/18"); bt_assert(1020:3040:5060:: ~ 1020:3040:5000::/40); @@ -1086,8 +1086,8 @@ bt_test_suite(t_clist, "Testing lists of communities"); */ function t_ec() -ec cc; { + ec cc; cc = (rt, 12345, 200000); bt_assert(format(cc) = "(rt, 12345, 200000)"); diff --git a/proto/rpki/config.Y b/proto/rpki/config.Y index 743b5b42..0cc34b35 100644 --- a/proto/rpki/config.Y +++ b/proto/rpki/config.Y @@ -90,20 +90,22 @@ rpki_keep_interval: rpki_proto_item_port: PORT expr { check_u16($2); RPKI_CFG->port = $2; }; -rpki_cache_addr: - text { - rpki_check_unused_hostname(); - RPKI_CFG->hostname = $1; - } - | ipa { - rpki_check_unused_hostname(); - RPKI_CFG->ip = $1; - /* Ensure hostname is filled */ - char *hostname = cfg_allocz(INET6_ADDRSTRLEN + 1); - bsnprintf(hostname, INET6_ADDRSTRLEN+1, "%I", RPKI_CFG->ip); - RPKI_CFG->hostname = hostname; - } - ; +rpki_cache_addr: text_or_ipa +{ + rpki_check_unused_hostname(); + if ($1.type == T_STRING) + RPKI_CFG->hostname = $1.val.s; + else if ($1.type == T_IP) + { + RPKI_CFG->ip = $1.val.ip; + + /* Ensure hostname is filled */ + char *hostname = cfg_allocz(INET6_ADDRSTRLEN + 1); + bsnprintf(hostname, INET6_ADDRSTRLEN+1, "%I", RPKI_CFG->ip); + RPKI_CFG->hostname = hostname; + } + else bug("Bad text_or_ipa"); +}; rpki_transport: TCP rpki_transport_tcp_init