From 116285f2b000a4b78044f1bcf1eb1d6655f1d2fe Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 25 Aug 2023 04:32:01 +0200 Subject: [PATCH 1/2] RPKI: Fix conflict in config grammar --- conf/confbase.Y | 20 +++++++++++++++++++- proto/rpki/config.Y | 30 ++++++++++++++++-------------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/conf/confbase.Y b/conf/confbase.Y index f8d24415..a6b4b1ee 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -121,7 +121,7 @@ CF_DECLS %type symbol %type kw_sym -%type bytestring_text +%type bytestring_text text_or_ipa %type bytestring_expr %nonassoc PREFIX_DUMMY @@ -399,6 +399,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/proto/rpki/config.Y b/proto/rpki/config.Y index d6d326b8..c28cab7a 100644 --- a/proto/rpki/config.Y +++ b/proto/rpki/config.Y @@ -89,20 +89,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 From cce48c6cdd9484c606879ea76d4c633fce12ba36 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 25 Aug 2023 23:14:36 +0200 Subject: [PATCH 2/2] Filter: Add separate instruction for uninitialized variable declaration The previous approach (use VOID constant for variable initialization) failed due to dynamic type check failure. Thanks to Alexander Zubkov for the bugreport. --- filter/config.Y | 16 ++++++++-------- filter/f-inst.c | 12 ++++++++++++ filter/test.conf | 4 ++-- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/filter/config.Y b/filter/config.Y index 2a298843..e02af182 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -324,7 +324,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 dynamic_attr %type static_attr %type filter where_filter @@ -895,16 +895,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 8a2f474e..b63fc1f4 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -506,6 +506,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); @@ -518,6 +519,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 c014dadd..c74c2691 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -630,8 +630,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); @@ -976,8 +976,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)");