]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter: Bitfield eattrs reading / writing moved to filter code
authorMaria Matejka <mq@ucw.cz>
Fri, 25 Mar 2022 18:51:35 +0000 (19:51 +0100)
committerMaria Matejka <mq@ucw.cz>
Wed, 4 May 2022 13:37:41 +0000 (15:37 +0200)
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
filter/f-inst.c
filter/f-inst.h
filter/test.conf
nest/route.h
nest/rt-attr.c
sysdep/linux/netlink.Y
sysdep/linux/netlink.c

index dabe47816f9875adde7532ff9bd6d4d23a20607d..67bd04b429ab2e7252ecc43cdc592223e8143b9c 100644 (file)
@@ -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) {
index 0050c23791f680f45176deb66ddb29004d28d0b9..8bfec479e3ce83e5d2c27d6f5ba42acd9c8722a3 100644 (file)
       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;
        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");
       }
index df45f88e6ddaf1588d819269e749130615451c5c..9265ecec5596330e50663f2b5b769437d2dc92d2 100644 (file)
@@ -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);
index 1058d34edc3dbae375296d2a6ceba11ad24348cd..ee2f5be4d5c6fe7a428d773e6039aa8a37dbb0b9 100644 (file)
@@ -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";
 }
 
index 80c53ba6aaf09aa8e0073f5fbaf866e39bc43879..a4af0edc463071969ec554356e5d4716c7b58efc 100644 (file)
@@ -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 */
index 22b45db93c0f0d5fb8e9eae09dc5254aafc0dbb0..abda5d82f04190fe68c8c5ba4fdc94fbec0c6fc8 100644 (file)
@@ -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;
index 487ad1d8e10f7dc12a6360de218e6f7e6e515310..7390be7342e1c2d33364bf942386e6d15d9fc048 100644 (file)
@@ -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
index e103c8ef1665c800c575f11011a468763e1de585..6c8228fdef89c7aa01d49f24749499345da88638 100644 (file)
@@ -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++;
          }