From: Ondrej Zajicek Date: Fri, 18 Oct 2024 14:39:42 +0000 (+0200) Subject: Filter: Add enum types to filter grammar X-Git-Tag: v2.16~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=80ca0ed279f2c8f396976d90f2e98ba6b923081c;p=thirdparty%2Fbird.git Filter: Add enum types to filter grammar Enum types existed on semantic level, but not on syntactic level, so they could not be used in filter code. Generate filter grammar for enum types based on CF_ENUM() declarations. Thanks to lbz for the bugreport. --- diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 2f95f2e13..637a5d384 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -680,7 +680,7 @@ cf_lex_symbol(const char *data) int val = sym->keyword->value; if (val > 0) return val; cf_lval.i = -val; - return ENUM; + return ENUM_TOKEN; } case SYM_METHOD: return (sym->method->arg_num > 1) ? CF_SYM_METHOD_ARGS : CF_SYM_METHOD_BARE; diff --git a/conf/confbase.Y b/conf/confbase.Y index cdbdf1ce2..1011a57c7 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -105,7 +105,7 @@ CF_DECLS %token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT %token GEQ LEQ NEQ AND OR IMP %token PO PC -%token NUM ENUM +%token NUM ENUM_TOKEN %token IP4 %token IP6 %token VPN_RD diff --git a/conf/gen_keywords.m4 b/conf/gen_keywords.m4 index 4e8651f6d..e81589dc8 100644 --- a/conf/gen_keywords.m4 +++ b/conf/gen_keywords.m4 @@ -35,10 +35,11 @@ m4_define(CF_CLI, `CF_KEYWORDS(m4_translit($1, [[ ]], [[,]])) # Enums are translated to C initializers: use CF_ENUM(typename, prefix, values) # For different prefix: CF_ENUM_PX(typename, external prefix, C prefix, values) +# The typename is converted to a keyword by removing T_ENUM_ prefix m4_define(CF_enum, `m4_divert(1){ "CF_enum_prefix_ext[[]]$1", -((CF_enum_type<<16) | CF_enum_prefix_int[[]]$1) }, m4_divert(-1)') -m4_define(CF_ENUM, `m4_define([[CF_enum_type]],$1)m4_define([[CF_enum_prefix_ext]],$2)m4_define([[CF_enum_prefix_int]],$2)CF_iterate([[CF_enum]], [[m4_shift(m4_shift($@))]])DNL') -m4_define(CF_ENUM_PX, `m4_define([[CF_enum_type]],$1)m4_define([[CF_enum_prefix_ext]],$2)m4_define([[CF_enum_prefix_int]],$3)CF_iterate([[CF_enum]], [[m4_shift(m4_shift(m4_shift($@)))]])DNL') +m4_define(CF_ENUM, `CF_keywd(m4_substr($1, 7))m4_define([[CF_enum_type]],$1)m4_define([[CF_enum_prefix_ext]],$2)m4_define([[CF_enum_prefix_int]],$2)CF_iterate([[CF_enum]], [[m4_shift(m4_shift($@))]])DNL') +m4_define(CF_ENUM_PX, `CF_keywd(m4_substr($1, 7))m4_define([[CF_enum_type]],$1)m4_define([[CF_enum_prefix_ext]],$2)m4_define([[CF_enum_prefix_int]],$3)CF_iterate([[CF_enum]], [[m4_shift(m4_shift(m4_shift($@)))]])DNL') # After all configuration templates end, we generate the m4_m4wrap(` diff --git a/conf/gen_parser.m4 b/conf/gen_parser.m4 index 48c2ca508..e41eb7f76 100644 --- a/conf/gen_parser.m4 +++ b/conf/gen_parser.m4 @@ -52,8 +52,10 @@ m4_define(CF_CLI_OPT, `') m4_define(CF_CLI_HELP, `') # ENUM declarations are ignored -m4_define(CF_ENUM, `') -m4_define(CF_ENUM_PX, `') +m4_define(CF_token, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],1)%token $1]])') +m4_define(CF_enum, `CF_append([[CF_enum_type]],[[$1 { $$ = $2; }]],[[ | ]])CF_token($1)') +m4_define(CF_ENUM, `CF_enum(m4_substr($1, 7), $1)') +m4_define(CF_ENUM_PX, `CF_enum(m4_substr($1, 7), $1)') # After all configuration templates end, we finally generate the grammar file. m4_m4wrap(` @@ -65,9 +67,11 @@ m4_undivert(1)DNL m4_undivert(2)DNL %type KEYWORD +%type enum_type %% KEYWORD: CF_kw_rule; +enum_type: CF_enum_type; m4_undivert(3)DNL diff --git a/filter/config.Y b/filter/config.Y index d656a7268..3b4d669f0 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -357,7 +357,7 @@ CF_DECLS CF_KEYWORDS_EXCLUSIVE(IN) CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, ACCEPT, REJECT, ERROR, - INT, BOOL, IP, PREFIX, RD, PAIR, QUAD, EC, LC, + INT, BOOL, IP, PREFIX, RD, PAIR, QUAD, EC, LC, ENUM, SET, STRING, BYTESTRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST, IF, THEN, ELSE, CASE, FOR, DO, @@ -473,6 +473,7 @@ type: case T_INT: case T_PAIR: case T_QUAD: + case T_ENUM: case T_EC: case T_LC: case T_RD: @@ -488,6 +489,7 @@ type: cf_error( "You can't create sets of this type." ); } } + | ENUM enum_type { $$ = $2; }; ; function_argsn: @@ -640,7 +642,7 @@ set_atom0: NUM { $$.type = T_INT; $$.val.i = $1; } | fipa { $$ = $1; } | VPN_RD { $$.type = T_RD; $$.val.ec = $1; } - | ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); } + | ENUM_TOKEN { $$.type = pair_a($1); $$.val.i = pair_b($1); } | '(' term ')' { $$ = cf_eval($2, T_VOID); if (!f_valid_set_type($$.type)) @@ -808,7 +810,7 @@ constant: DBG( "ook\n" ); } | '[' fprefix_set ']' { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PREFIX_SET, .val.ti = $2, }); } - | ENUM { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = $1 >> 16, .val.i = $1 & 0xffff, }); } + | ENUM_TOKEN { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = $1 >> 16, .val.i = $1 & 0xffff, }); } ; constructor: diff --git a/filter/data.c b/filter/data.c index 282206eb6..100844481 100644 --- a/filter/data.c +++ b/filter/data.c @@ -44,6 +44,7 @@ static const char * const f_type_str[] = { [T_ENUM_NETTYPE] = "enum nettype", [T_ENUM_RA_PREFERENCE] = "enum ra_preference", [T_ENUM_AF] = "enum af", + [T_ENUM_MPLS_POLICY] = "enum mpls_policy", [T_IP] = "ip", [T_NET] = "prefix", diff --git a/filter/test.conf b/filter/test.conf index 0361a1c98..c27c04edb 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -471,12 +471,31 @@ bt_test_suite(t_ip_set, "Testing sets of ip address"); function t_enum() { + enum rts ev0 = RTS_STATIC; + enum rtd ev1 = RTD_UNICAST; + enum scope ev2 = SCOPE_UNIVERSE; + enum roa ev3 = ROA_VALID; + enum aspa ev4 = ASPA_VALID; + enum af ev5 = AF_IPV6; + enum nettype ev6 = NET_IP6; + enum bgp_origin ev7 = ORIGIN_IGP; + enum ra_preference ev8 = RA_PREF_LOW; + enum mpls_policy ev9 = MPLS_POLICY_STATIC; + + enum nettype set es = [NET_IP6, NET_VPN6]; + bt_assert(format(RTS_STATIC) = "(enum 30)1"); bt_assert(format(NET_IP4) = "(enum 36)1"); bt_assert(format(NET_VPN6) = "(enum 36)4"); + bt_assert(format(ev6) = "(enum 36)2"); + + bt_assert(ev0 = RTS_STATIC); + bt_assert(ev6 = NET_IP6); bt_assert(RTS_STATIC ~ [RTS_STATIC, RTS_DEVICE]); bt_assert(RTS_BGP !~ [RTS_STATIC, RTS_DEVICE]); + bt_assert(NET_IP6 ~ es); + bt_assert(NET_IP4 !~ es); } bt_test_suite(t_enum, "Testing enums"); diff --git a/nest/config.Y b/nest/config.Y index 6b89f5d85..118c112e4 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -132,6 +132,7 @@ CF_KEYWORDS(ASPA_PROVIDERS) /* For r_args_channel */ 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, ASPA) +CF_ENUM(T_ENUM_NETTYPE, NET_, IP4, IP6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, IP6_SADR, MPLS, ASPA) CF_ENUM(T_ENUM_RTS, RTS_, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT, RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE, BABEL, RPKI, L3VPN, AGGREGATED) @@ -211,8 +212,6 @@ net_type: | MPLS { $$ = NET_MPLS; } ; -CF_ENUM(T_ENUM_NETTYPE, NET_, IP4, IP6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, IP6_SADR, MPLS, ASPA) - /* Creation of routing tables */