mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
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.
This commit is contained in:
parent
072821e55e
commit
80ca0ed279
@ -680,7 +680,7 @@ cf_lex_symbol(const char *data)
|
|||||||
int val = sym->keyword->value;
|
int val = sym->keyword->value;
|
||||||
if (val > 0) return val;
|
if (val > 0) return val;
|
||||||
cf_lval.i = -val;
|
cf_lval.i = -val;
|
||||||
return ENUM;
|
return ENUM_TOKEN;
|
||||||
}
|
}
|
||||||
case SYM_METHOD:
|
case SYM_METHOD:
|
||||||
return (sym->method->arg_num > 1) ? CF_SYM_METHOD_ARGS : CF_SYM_METHOD_BARE;
|
return (sym->method->arg_num > 1) ? CF_SYM_METHOD_ARGS : CF_SYM_METHOD_BARE;
|
||||||
|
@ -105,7 +105,7 @@ CF_DECLS
|
|||||||
%token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT
|
%token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT
|
||||||
%token GEQ LEQ NEQ AND OR IMP
|
%token GEQ LEQ NEQ AND OR IMP
|
||||||
%token PO PC
|
%token PO PC
|
||||||
%token <i> NUM ENUM
|
%token <i> NUM ENUM_TOKEN
|
||||||
%token <ip4> IP4
|
%token <ip4> IP4
|
||||||
%token <ip6> IP6
|
%token <ip6> IP6
|
||||||
%token <i64> VPN_RD
|
%token <i64> VPN_RD
|
||||||
|
@ -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)
|
# Enums are translated to C initializers: use CF_ENUM(typename, prefix, values)
|
||||||
# For different prefix: CF_ENUM_PX(typename, external prefix, C 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_define(CF_enum, `m4_divert(1){ "CF_enum_prefix_ext[[]]$1", -((CF_enum_type<<16) | CF_enum_prefix_int[[]]$1) },
|
||||||
m4_divert(-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, `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, `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_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
|
# After all configuration templates end, we generate the
|
||||||
m4_m4wrap(`
|
m4_m4wrap(`
|
||||||
|
@ -52,8 +52,10 @@ m4_define(CF_CLI_OPT, `')
|
|||||||
m4_define(CF_CLI_HELP, `')
|
m4_define(CF_CLI_HELP, `')
|
||||||
|
|
||||||
# ENUM declarations are ignored
|
# ENUM declarations are ignored
|
||||||
m4_define(CF_ENUM, `')
|
m4_define(CF_token, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],1)%token<s> $1]])')
|
||||||
m4_define(CF_ENUM_PX, `')
|
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.
|
# After all configuration templates end, we finally generate the grammar file.
|
||||||
m4_m4wrap(`
|
m4_m4wrap(`
|
||||||
@ -65,9 +67,11 @@ m4_undivert(1)DNL
|
|||||||
m4_undivert(2)DNL
|
m4_undivert(2)DNL
|
||||||
|
|
||||||
%type <s> KEYWORD
|
%type <s> KEYWORD
|
||||||
|
%type <i> enum_type
|
||||||
|
|
||||||
%%
|
%%
|
||||||
KEYWORD: CF_kw_rule;
|
KEYWORD: CF_kw_rule;
|
||||||
|
enum_type: CF_enum_type;
|
||||||
|
|
||||||
m4_undivert(3)DNL
|
m4_undivert(3)DNL
|
||||||
|
|
||||||
|
@ -357,7 +357,7 @@ CF_DECLS
|
|||||||
CF_KEYWORDS_EXCLUSIVE(IN)
|
CF_KEYWORDS_EXCLUSIVE(IN)
|
||||||
CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
|
CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
|
||||||
ACCEPT, REJECT, ERROR,
|
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,
|
SET, STRING, BYTESTRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
|
||||||
IF, THEN, ELSE, CASE,
|
IF, THEN, ELSE, CASE,
|
||||||
FOR, DO,
|
FOR, DO,
|
||||||
@ -473,6 +473,7 @@ type:
|
|||||||
case T_INT:
|
case T_INT:
|
||||||
case T_PAIR:
|
case T_PAIR:
|
||||||
case T_QUAD:
|
case T_QUAD:
|
||||||
|
case T_ENUM:
|
||||||
case T_EC:
|
case T_EC:
|
||||||
case T_LC:
|
case T_LC:
|
||||||
case T_RD:
|
case T_RD:
|
||||||
@ -488,6 +489,7 @@ type:
|
|||||||
cf_error( "You can't create sets of this type." );
|
cf_error( "You can't create sets of this type." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
| ENUM enum_type { $$ = $2; };
|
||||||
;
|
;
|
||||||
|
|
||||||
function_argsn:
|
function_argsn:
|
||||||
@ -640,7 +642,7 @@ set_atom0:
|
|||||||
NUM { $$.type = T_INT; $$.val.i = $1; }
|
NUM { $$.type = T_INT; $$.val.i = $1; }
|
||||||
| fipa { $$ = $1; }
|
| fipa { $$ = $1; }
|
||||||
| VPN_RD { $$.type = T_RD; $$.val.ec = $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 ')' {
|
| '(' term ')' {
|
||||||
$$ = cf_eval($2, T_VOID);
|
$$ = cf_eval($2, T_VOID);
|
||||||
if (!f_valid_set_type($$.type))
|
if (!f_valid_set_type($$.type))
|
||||||
@ -808,7 +810,7 @@ constant:
|
|||||||
DBG( "ook\n" );
|
DBG( "ook\n" );
|
||||||
}
|
}
|
||||||
| '[' fprefix_set ']' { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PREFIX_SET, .val.ti = $2, }); }
|
| '[' 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:
|
constructor:
|
||||||
|
@ -44,6 +44,7 @@ static const char * const f_type_str[] = {
|
|||||||
[T_ENUM_NETTYPE] = "enum nettype",
|
[T_ENUM_NETTYPE] = "enum nettype",
|
||||||
[T_ENUM_RA_PREFERENCE] = "enum ra_preference",
|
[T_ENUM_RA_PREFERENCE] = "enum ra_preference",
|
||||||
[T_ENUM_AF] = "enum af",
|
[T_ENUM_AF] = "enum af",
|
||||||
|
[T_ENUM_MPLS_POLICY] = "enum mpls_policy",
|
||||||
|
|
||||||
[T_IP] = "ip",
|
[T_IP] = "ip",
|
||||||
[T_NET] = "prefix",
|
[T_NET] = "prefix",
|
||||||
|
@ -471,12 +471,31 @@ bt_test_suite(t_ip_set, "Testing sets of ip address");
|
|||||||
|
|
||||||
function t_enum()
|
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(RTS_STATIC) = "(enum 30)1");
|
||||||
bt_assert(format(NET_IP4) = "(enum 36)1");
|
bt_assert(format(NET_IP4) = "(enum 36)1");
|
||||||
bt_assert(format(NET_VPN6) = "(enum 36)4");
|
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_STATIC ~ [RTS_STATIC, RTS_DEVICE]);
|
||||||
bt_assert(RTS_BGP !~ [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");
|
bt_test_suite(t_enum, "Testing enums");
|
||||||
|
@ -132,6 +132,7 @@ CF_KEYWORDS(ASPA_PROVIDERS)
|
|||||||
/* For r_args_channel */
|
/* 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_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,
|
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,
|
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE, BABEL, RPKI, L3VPN,
|
||||||
AGGREGATED)
|
AGGREGATED)
|
||||||
@ -211,8 +212,6 @@ net_type:
|
|||||||
| MPLS { $$ = NET_MPLS; }
|
| 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 */
|
/* Creation of routing tables */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user