From d4bcef0e0bfee911d403c0cf830de3e3007eeb38 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Fri, 25 Mar 2022 19:15:11 +0100 Subject: [PATCH 1/5] Filter operations: bitwise AND and OR --- conf/cf-lex.l | 2 +- conf/confbase.Y | 1 + filter/config.Y | 2 ++ filter/f-inst.c | 10 ++++++++++ filter/test.conf | 8 ++++++++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/conf/cf-lex.l b/conf/cf-lex.l index c9d2f5a5..b9457a83 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -347,7 +347,7 @@ else: { return DDOT; } -[={}:;,.()+*/%<>~\[\]?!\|-] { +[={}:;,.()+*/%<>~\[\]?!\|&-] { return yytext[0]; } diff --git a/conf/confbase.Y b/conf/confbase.Y index 6985783b..753df325 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -120,6 +120,7 @@ CF_DECLS %nonassoc PREFIX_DUMMY %left AND OR %nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA PO PC +%left '|' '&' %left '+' '-' %left '*' '/' '%' %left '!' diff --git a/filter/config.Y b/filter/config.Y index 46ba7769..dabe4781 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -780,6 +780,8 @@ term: | term '-' term { $$ = f_new_inst(FI_SUBTRACT, $1, $3); } | term '*' term { $$ = f_new_inst(FI_MULTIPLY, $1, $3); } | term '/' term { $$ = f_new_inst(FI_DIVIDE, $1, $3); } + | term '&' term { $$ = f_new_inst(FI_BITAND, $1, $3); } + | term '|' term { $$ = f_new_inst(FI_BITOR, $1, $3); } | term AND term { $$ = f_new_inst(FI_AND, $1, $3); } | term OR term { $$ = f_new_inst(FI_OR, $1, $3); } | term '=' term { $$ = f_new_inst(FI_EQ, $1, $3); } diff --git a/filter/f-inst.c b/filter/f-inst.c index 8e20dc74..0050c237 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -240,6 +240,16 @@ if (v2.val.i == 0) runtime( "Mother told me not to divide by 0" ); RESULT(T_INT, i, v1.val.i / v2.val.i); } + INST(FI_BITOR, 2, 1) { + ARG(1,T_INT); + ARG(2,T_INT); + RESULT(T_INT, i, v1.val.i | v2.val.i); + } + INST(FI_BITAND, 2, 1) { + ARG(1,T_INT); + ARG(2,T_INT); + RESULT(T_INT, i, v1.val.i & v2.val.i); + } INST(FI_AND, 1, 1) { ARG(1,T_BOOL); ARG_TYPE_STATIC(2,T_BOOL); diff --git a/filter/test.conf b/filter/test.conf index 2a5a2d98..1058d34e 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -111,6 +111,14 @@ int i; bt_assert(!(i = 4)); bt_assert(1 <= 1); bt_assert(!(1234 < 1234)); + + bt_assert(10 - 5 = 5); + bt_assert(4294967295 + 1 = 0); + bt_assert(6*9=54); + bt_assert(984/41 = 24); + bt_assert(123/45 = 2); + bt_assert(0xfee1a | 0xbeef = 0xffeff); + bt_assert(0xfee1a & 0xbeef = 0xae0a); } bt_test_suite(t_int, "Testing integers"); From bc17fee1bfdbd330f5a4377bf40f6de0681afa5c Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Fri, 25 Mar 2022 19:51:35 +0100 Subject: [PATCH 2/5] Filter: Bitfield eattrs reading / writing moved to filter code Before this change, fetch-update-write and bitmasking was hardcoded in attribute access code cased by the attribute type. Several filter instructions are used to do it instead. As this is certainly going to be a little bit slower than before, the switch block in attribute access code should be completely removed in near future, helping with both performance and code cleanliness. The user interface should have stayed intact. --- filter/config.Y | 14 +++++++++++++- filter/f-inst.c | 16 ---------------- filter/f-inst.h | 4 ++-- filter/test.conf | 4 ++++ nest/route.h | 1 - nest/rt-attr.c | 3 --- sysdep/linux/netlink.Y | 24 ++++++++++++------------ sysdep/linux/netlink.c | 2 +- 8 files changed, 32 insertions(+), 36 deletions(-) diff --git a/filter/config.Y b/filter/config.Y index dabe4781..67bd04b4 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -308,7 +308,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, %type cmds_int cmd_prep %type term block cmd cmds constant constructor print_list var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail -%type dynamic_attr +%type dynamic_attr attr_bit %type static_attr %type filter where_filter %type filter_body function_body @@ -802,6 +802,10 @@ term: | static_attr { $$ = f_new_inst(FI_RTA_GET, $1); } | dynamic_attr { $$ = f_new_inst(FI_EA_GET, $1); } + | attr_bit { + struct f_inst *c = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = (1U << $1.bit)}); + $$ = f_new_inst(FI_EQ, c, f_new_inst(FI_BITAND, f_new_inst(FI_EA_GET, $1), c)); + } | term '.' IS_V4 { $$ = f_new_inst(FI_IS_V4, $1); } | term '.' TYPE { $$ = f_new_inst(FI_TYPE, $1); } @@ -899,6 +903,14 @@ cmd: | UNSET '(' dynamic_attr ')' ';' { $$ = f_new_inst(FI_EA_UNSET, $3); } + | attr_bit '=' term ';' { + $$ = f_new_inst(FI_CONDITION, $3, + f_generate_complex(FI_BITOR, $1, + f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = (1U << $1.bit)})), + f_generate_complex(FI_BITAND, $1, + f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = ~(1U << $1.bit)})) + ); + } | break_command print_list ';' { struct f_inst *breaker = f_new_inst(FI_DIE, $1); if ($2) { diff --git a/filter/f-inst.c b/filter/f-inst.c index 0050c237..8bfec479 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -712,9 +712,6 @@ case EAF_TYPE_AS_PATH: RESULT_(T_PATH, ad, e->u.ptr); break; - case EAF_TYPE_BITFIELD: - RESULT_(T_BOOL, i, !!(e->u.data & (1u << da.bit))); - break; case EAF_TYPE_INT_SET: RESULT_(T_CLIST, ad, e->u.ptr); break; @@ -774,19 +771,6 @@ l->attrs[0].u.ptr = v1.val.ad; break; - case EAF_TYPE_BITFIELD: - { - /* First, we have to find the old value */ - eattr *e = ea_find(*fs->eattrs, da.ea_code); - u32 data = e ? e->u.data : 0; - - if (v1.val.i) - l->attrs[0].u.data = data | (1u << da.bit); - else - l->attrs[0].u.data = data & ~(1u << da.bit); - } - break; - default: bug("Unknown dynamic attribute type"); } diff --git a/filter/f-inst.h b/filter/f-inst.h index df45f88e..9265ecec 100644 --- a/filter/f-inst.h +++ b/filter/f-inst.h @@ -89,8 +89,8 @@ void f_add_lines(const struct f_line_item *what, struct filter_iterator *fit); struct filter *f_new_where(struct f_inst *); static inline struct f_dynamic_attr f_new_dynamic_attr(u8 type, enum f_type f_type, uint code) /* Type as core knows it, type as filters know it, and code of dynamic attribute */ { return (struct f_dynamic_attr) { .type = type, .f_type = f_type, .ea_code = code }; } /* f_type currently unused; will be handy for static type checking */ -static inline struct f_dynamic_attr f_new_dynamic_attr_bit(u8 bit, enum f_type f_type, uint code) /* Type as core knows it, type as filters know it, and code of dynamic attribute */ -{ return (struct f_dynamic_attr) { .type = EAF_TYPE_BITFIELD, .bit = bit, .f_type = f_type, .ea_code = code }; } /* f_type currently unused; will be handy for static type checking */ +static inline struct f_dynamic_attr f_new_dynamic_attr_bit(u8 bit, uint code) /* Type as core knows it, type as filters know it, and code of dynamic attribute */ +{ return (struct f_dynamic_attr) { .type = EAF_TYPE_INT, .bit = bit, .f_type = T_INT, .ea_code = code }; } /* f_type currently unused; will be handy for static type checking */ static inline struct f_static_attr f_new_static_attr(int f_type, int code, int readonly) { return (struct f_static_attr) { .f_type = f_type, .sa_code = code, .readonly = readonly }; } struct f_inst *f_generate_complex(enum f_instruction_code fi_code, struct f_dynamic_attr da, struct f_inst *argument); diff --git a/filter/test.conf b/filter/test.conf index 1058d34e..ee2f5be4 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -1342,6 +1342,10 @@ int j; rip_metric = 14; unset(rip_metric); +# krt_lock_mtu = false; +# krt_lock_window = true; +# krt_lock_rtt = krt_lock_rttvar && krt_lock_sstresh || krt_lock_cwnd; + accept "ok I take that"; } diff --git a/nest/route.h b/nest/route.h index 80c53ba6..a4af0edc 100644 --- a/nest/route.h +++ b/nest/route.h @@ -536,7 +536,6 @@ const char *ea_custom_name(uint ea); #define EAF_TYPE_IP_ADDRESS 0x04 /* IP address */ #define EAF_TYPE_ROUTER_ID 0x05 /* Router ID (IPv4 address) */ #define EAF_TYPE_AS_PATH 0x06 /* BGP AS path (encoding per RFC 1771:4.3) */ -#define EAF_TYPE_BITFIELD 0x09 /* 32-bit embedded bitfield */ #define EAF_TYPE_INT_SET 0x0a /* Set of u32's (e.g., a community list) */ #define EAF_TYPE_EC_SET 0x0e /* Set of pairs of u32's - ext. community list */ #define EAF_TYPE_LC_SET 0x12 /* Set of triplets of u32's - large community list */ diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 22b45db9..abda5d82 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -965,9 +965,6 @@ ea_show(struct cli *c, const eattr *e) case EAF_TYPE_AS_PATH: as_path_format(ad, pos, end - pos); break; - case EAF_TYPE_BITFIELD: - bsprintf(pos, "%08x", e->u.data); - break; case EAF_TYPE_INT_SET: ea_show_int_set(c, ad, 1, pos, buf, end); return; diff --git a/sysdep/linux/netlink.Y b/sysdep/linux/netlink.Y index 487ad1d8..7390be73 100644 --- a/sysdep/linux/netlink.Y +++ b/sysdep/linux/netlink.Y @@ -48,19 +48,19 @@ dynamic_attr: KRT_QUICKACK { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT /* Bits of EA_KRT_LOCK, based on RTAX_* constants */ -dynamic_attr: KRT_LOCK_MTU { $$ = f_new_dynamic_attr_bit(2, T_BOOL, EA_KRT_LOCK); } ; -dynamic_attr: KRT_LOCK_WINDOW { $$ = f_new_dynamic_attr_bit(3, T_BOOL, EA_KRT_LOCK); } ; -dynamic_attr: KRT_LOCK_RTT { $$ = f_new_dynamic_attr_bit(4, T_BOOL, EA_KRT_LOCK); } ; -dynamic_attr: KRT_LOCK_RTTVAR { $$ = f_new_dynamic_attr_bit(5, T_BOOL, EA_KRT_LOCK); } ; -dynamic_attr: KRT_LOCK_SSTRESH { $$ = f_new_dynamic_attr_bit(6, T_BOOL, EA_KRT_LOCK); } ; -dynamic_attr: KRT_LOCK_CWND { $$ = f_new_dynamic_attr_bit(7, T_BOOL, EA_KRT_LOCK); } ; -dynamic_attr: KRT_LOCK_ADVMSS { $$ = f_new_dynamic_attr_bit(8, T_BOOL, EA_KRT_LOCK); } ; -dynamic_attr: KRT_LOCK_REORDERING { $$ = f_new_dynamic_attr_bit(9, T_BOOL, EA_KRT_LOCK); } ; -dynamic_attr: KRT_LOCK_HOPLIMIT { $$ = f_new_dynamic_attr_bit(10, T_BOOL, EA_KRT_LOCK); } ; -dynamic_attr: KRT_LOCK_RTO_MIN { $$ = f_new_dynamic_attr_bit(13, T_BOOL, EA_KRT_LOCK); } ; +attr_bit: KRT_LOCK_MTU { $$ = f_new_dynamic_attr_bit(2, EA_KRT_LOCK); } ; +attr_bit: KRT_LOCK_WINDOW { $$ = f_new_dynamic_attr_bit(3, EA_KRT_LOCK); } ; +attr_bit: KRT_LOCK_RTT { $$ = f_new_dynamic_attr_bit(4, EA_KRT_LOCK); } ; +attr_bit: KRT_LOCK_RTTVAR { $$ = f_new_dynamic_attr_bit(5, EA_KRT_LOCK); } ; +attr_bit: KRT_LOCK_SSTRESH { $$ = f_new_dynamic_attr_bit(6, EA_KRT_LOCK); } ; +attr_bit: KRT_LOCK_CWND { $$ = f_new_dynamic_attr_bit(7, EA_KRT_LOCK); } ; +attr_bit: KRT_LOCK_ADVMSS { $$ = f_new_dynamic_attr_bit(8, EA_KRT_LOCK); } ; +attr_bit: KRT_LOCK_REORDERING { $$ = f_new_dynamic_attr_bit(9, EA_KRT_LOCK); } ; +attr_bit: KRT_LOCK_HOPLIMIT { $$ = f_new_dynamic_attr_bit(10, EA_KRT_LOCK); } ; +attr_bit: KRT_LOCK_RTO_MIN { $$ = f_new_dynamic_attr_bit(13, EA_KRT_LOCK); } ; -dynamic_attr: KRT_FEATURE_ECN { $$ = f_new_dynamic_attr_bit(0, T_BOOL, EA_KRT_FEATURES); } ; -dynamic_attr: KRT_FEATURE_ALLFRAG { $$ = f_new_dynamic_attr(3, T_BOOL, EA_KRT_FEATURES); } ; +attr_bit: KRT_FEATURE_ECN { $$ = f_new_dynamic_attr_bit(0, EA_KRT_FEATURES); } ; +attr_bit: KRT_FEATURE_ALLFRAG { $$ = f_new_dynamic_attr_bit(3, EA_KRT_FEATURES); } ; CF_CODE diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index e103c8ef..6c8228fd 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -1928,7 +1928,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h) { ea->attrs[n].id = EA_CODE(PROTOCOL_KERNEL, KRT_METRICS_OFFSET + t); ea->attrs[n].flags = 0; - ea->attrs[n].type = EAF_TYPE_INT; /* FIXME: Some are EAF_TYPE_BITFIELD */ + ea->attrs[n].type = EAF_TYPE_INT; ea->attrs[n].u.data = metrics[t]; n++; } From e261b325113a63410bc30287c135bf162480c3b2 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Thu, 14 Apr 2022 12:06:17 +0200 Subject: [PATCH 3/5] Dropping EAF_VAR_LENGTH as the attribute data is either embedded or adata --- nest/route.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nest/route.h b/nest/route.h index a4af0edc..7557bf93 100644 --- a/nest/route.h +++ b/nest/route.h @@ -538,10 +538,10 @@ const char *ea_custom_name(uint ea); #define EAF_TYPE_AS_PATH 0x06 /* BGP AS path (encoding per RFC 1771:4.3) */ #define EAF_TYPE_INT_SET 0x0a /* Set of u32's (e.g., a community list) */ #define EAF_TYPE_EC_SET 0x0e /* Set of pairs of u32's - ext. community list */ -#define EAF_TYPE_LC_SET 0x12 /* Set of triplets of u32's - large community list */ -#define EAF_TYPE_IFACE 0x16 /* Interface pointer stored in adata */ +#define EAF_TYPE_LC_SET 0x08 /* Set of triplets of u32's - large community list */ +#define EAF_TYPE_IFACE 0x0c /* Interface pointer stored in adata */ #define EAF_EMBEDDED 0x01 /* Data stored in eattr.u.data (part of type spec) */ -#define EAF_VAR_LENGTH 0x02 /* Attribute length is variable (part of type spec) */ + /* Otherwise, attribute data is adata */ typedef struct adata { uint length; /* Length of data */ From 22f95d9889f07d868ffaec40ab43fd8dd9b0bb31 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Sat, 26 Mar 2022 12:37:41 +0100 Subject: [PATCH 4/5] Special attribute types for enums --- filter/config.Y | 2 +- filter/f-inst.c | 2 +- nest/route.h | 3 +++ nest/rt-attr.c | 7 +++++-- proto/bgp/attrs.c | 2 +- proto/bgp/config.Y | 2 +- proto/radv/config.Y | 2 +- 7 files changed, 13 insertions(+), 7 deletions(-) diff --git a/filter/config.Y b/filter/config.Y index 67bd04b4..fb331c16 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -165,7 +165,7 @@ f_generate_empty(struct f_dynamic_attr dyn) { struct f_val empty; - switch (dyn.type & EAF_TYPE_MASK) { + switch (dyn.type) { case EAF_TYPE_AS_PATH: empty = f_const_empty_path; break; diff --git a/filter/f-inst.c b/filter/f-inst.c index 8bfec479..11ca1e28 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -696,7 +696,7 @@ break; } - switch (e->type & EAF_TYPE_MASK) { + switch (e->type) { case EAF_TYPE_INT: RESULT_(da.f_type, i, e->u.data); break; diff --git a/nest/route.h b/nest/route.h index 7557bf93..d2f60f41 100644 --- a/nest/route.h +++ b/nest/route.h @@ -540,6 +540,9 @@ const char *ea_custom_name(uint ea); #define EAF_TYPE_EC_SET 0x0e /* Set of pairs of u32's - ext. community list */ #define EAF_TYPE_LC_SET 0x08 /* Set of triplets of u32's - large community list */ #define EAF_TYPE_IFACE 0x0c /* Interface pointer stored in adata */ +#define EAF_TYPE_BGP_ORIGIN 0x11 /* BGP Origin enum */ +#define EAF_TYPE_RA_PREFERENCE 0x13 /* RA Preference enum */ + #define EAF_EMBEDDED 0x01 /* Data stored in eattr.u.data (part of type spec) */ /* Otherwise, attribute data is adata */ diff --git a/nest/rt-attr.c b/nest/rt-attr.c index abda5d82..25548dca 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -948,7 +948,7 @@ ea_show(struct cli *c, const eattr *e) if (e->undef) bsprintf(pos, "undefined"); else - switch (e->type & EAF_TYPE_MASK) + switch (e->type) { case EAF_TYPE_INT: bsprintf(pos, "%u", e->u.data); @@ -1008,7 +1008,10 @@ ea_dump(ea_list *e) { eattr *a = &e->attrs[i]; debug(" %02x:%02x.%02x", EA_PROTO(a->id), EA_ID(a->id), a->flags); - debug("=%c", "?iO?I?P???S?????" [a->type & EAF_TYPE_MASK]); + debug("=%c", + "?iO?IRP???S??pE?" + "??L???N?????????" + "?o???r??????????" [a->type]); if (a->originated) debug("o"); if (a->type & EAF_EMBEDDED) diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index a7c49be5..b514f1b9 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -987,7 +987,7 @@ bgp_decode_unknown(struct bgp_parse_state *s, uint code, uint flags, byte *data, static const struct bgp_attr_desc bgp_attr_table[] = { [BA_ORIGIN] = { .name = "origin", - .type = EAF_TYPE_INT, + .type = EAF_TYPE_BGP_ORIGIN, .flags = BAF_TRANSITIVE, .export = bgp_export_origin, .encode = bgp_encode_u8, diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index 241aa7c2..04920941 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -318,7 +318,7 @@ bgp_proto_channel: bgp_channel_start bgp_channel_opt_list bgp_channel_end; dynamic_attr: BGP_ORIGIN - { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_ENUM_BGP_ORIGIN, EA_CODE(PROTOCOL_BGP, BA_ORIGIN)); } ; + { $$ = f_new_dynamic_attr(EAF_TYPE_BGP_ORIGIN, T_ENUM_BGP_ORIGIN, EA_CODE(PROTOCOL_BGP, BA_ORIGIN)); } ; dynamic_attr: BGP_PATH { $$ = f_new_dynamic_attr(EAF_TYPE_AS_PATH, T_PATH, EA_CODE(PROTOCOL_BGP, BA_AS_PATH)); } ; dynamic_attr: BGP_NEXT_HOP diff --git a/proto/radv/config.Y b/proto/radv/config.Y index 8d4a3ab9..f16b897d 100644 --- a/proto/radv/config.Y +++ b/proto/radv/config.Y @@ -336,7 +336,7 @@ radv_sensitive: | SENSITIVE bool { $$ = $2; } ; -dynamic_attr: RA_PREFERENCE { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_ENUM_RA_PREFERENCE, EA_RA_PREFERENCE); } ; +dynamic_attr: RA_PREFERENCE { $$ = f_new_dynamic_attr(EAF_TYPE_RA_PREFERENCE, T_ENUM_RA_PREFERENCE, EA_RA_PREFERENCE); } ; dynamic_attr: RA_LIFETIME { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RA_LIFETIME); } ; CF_CODE From 80272d4b64a38ee6f04a1c4e8566cac3a2293176 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Sat, 26 Mar 2022 12:40:46 +0100 Subject: [PATCH 5/5] Opaque types are named opaque also in filters --- filter/data.h | 4 +++- filter/f-inst.c | 2 +- proto/bgp/config.Y | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/filter/data.h b/filter/data.h index 6d588204..924bbf3e 100644 --- a/filter/data.h +++ b/filter/data.h @@ -20,6 +20,9 @@ enum f_type { /* Nothing. Simply nothing. */ T_VOID = 0, +/* Something but inaccessible. */ + T_OPAQUE = 0xee, + /* User visible types, which fit in int */ T_INT = 0x10, T_BOOL = 0x11, @@ -41,7 +44,6 @@ enum f_type { T_ENUM_AF = 0x38, /* new enums go here */ - T_ENUM_EMPTY = 0x3f, /* Special hack for atomic_aggr */ #define T_ENUM T_ENUM_LO ... T_ENUM_HI diff --git a/filter/f-inst.c b/filter/f-inst.c index 11ca1e28..75a53499 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -704,7 +704,7 @@ RESULT_(T_QUAD, i, e->u.data); break; case EAF_TYPE_OPAQUE: - RESULT_(T_ENUM_EMPTY, i, 0); + RESULT_(T_OPAQUE, ad, e->u.ptr); break; case EAF_TYPE_IP_ADDRESS: RESULT_(T_IP, ip, *((ip_addr *) e->u.ptr->data)); diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index 04920941..86124bfb 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -328,9 +328,9 @@ dynamic_attr: BGP_MED dynamic_attr: BGP_LOCAL_PREF { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF)); } ; dynamic_attr: BGP_ATOMIC_AGGR - { $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_ENUM_EMPTY, EA_CODE(PROTOCOL_BGP, BA_ATOMIC_AGGR)); } ; + { $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_OPAQUE, EA_CODE(PROTOCOL_BGP, BA_ATOMIC_AGGR)); } ; dynamic_attr: BGP_AGGREGATOR - { $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_ENUM_EMPTY, EA_CODE(PROTOCOL_BGP, BA_AGGREGATOR)); } ; + { $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_OPAQUE, EA_CODE(PROTOCOL_BGP, BA_AGGREGATOR)); } ; dynamic_attr: BGP_COMMUNITY { $$ = f_new_dynamic_attr(EAF_TYPE_INT_SET, T_CLIST, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY)); } ; dynamic_attr: BGP_ORIGINATOR_ID @@ -340,7 +340,7 @@ dynamic_attr: BGP_CLUSTER_LIST dynamic_attr: BGP_EXT_COMMUNITY { $$ = f_new_dynamic_attr(EAF_TYPE_EC_SET, T_ECLIST, EA_CODE(PROTOCOL_BGP, BA_EXT_COMMUNITY)); } ; dynamic_attr: BGP_AIGP - { $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_ENUM_EMPTY, EA_CODE(PROTOCOL_BGP, BA_AIGP)); } ; + { $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_OPAQUE, EA_CODE(PROTOCOL_BGP, BA_AIGP)); } ; dynamic_attr: BGP_LARGE_COMMUNITY { $$ = f_new_dynamic_attr(EAF_TYPE_LC_SET, T_LCLIST, EA_CODE(PROTOCOL_BGP, BA_LARGE_COMMUNITY)); } ;