mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-18 17:18:42 +00:00
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.
This commit is contained in:
parent
d4bcef0e0b
commit
bc17fee1bf
@ -308,7 +308,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
|
||||
|
||||
%type <xp> cmds_int cmd_prep
|
||||
%type <x> term block cmd cmds constant constructor print_list var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail
|
||||
%type <fda> dynamic_attr
|
||||
%type <fda> dynamic_attr attr_bit
|
||||
%type <fsa> static_attr
|
||||
%type <f> filter where_filter
|
||||
%type <fl> 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) {
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user