]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
WIP Nest: Making the clist/eclist/lclist even more generic mq-tmpb
authorJan Maria Matejka <mq@ucw.cz>
Thu, 7 Jun 2018 13:02:05 +0000 (15:02 +0200)
committerJan Maria Matejka <mq@ucw.cz>
Thu, 7 Jun 2018 13:02:05 +0000 (15:02 +0200)
filter/filter.c
nest/a-set.c
nest/a-set_test.c
nest/attrs.h

index 4ca86de73d01caff8cd6108d0a153a3cae0a1bd2..18ff15554acae7a05b73569353c1992a0e5c7266 100644 (file)
@@ -301,14 +301,10 @@ eclist_match_set(struct adata *list, struct f_tree *set)
   if (!eclist_set_type(set))
     return CMP_ERROR;
 
-  struct f_val v;
-  u32 *l = int_set_get_data(list);
-  int len = int_set_get_size(list);
-  int i;
-
+  struct f_val v = { .type = T_EC };
   v.type = T_EC;
-  for (i = 0; i < len; i += 2) {
-    v.val.ec = ec_get(l, i);
+  for (void *p = list->data, *end = p + list->length; p < end; p += sizeof(u64)) {
+    memcpy(&v.val.ec, p, sizeof(u64));
     if (find_tree(set, v))
       return 1;
   }
@@ -325,14 +321,10 @@ lclist_match_set(struct adata *list, struct f_tree *set)
   if (!lclist_set_type(set))
     return CMP_ERROR;
 
-  struct f_val v;
-  u32 *l = int_set_get_data(list);
-  int len = int_set_get_size(list);
-  int i;
-
+  struct f_val v = { .type = T_LC };
   v.type = T_LC;
-  for (i = 0; i < len; i += 3) {
-    v.val.lc = lc_get(l, i);
+  for (void *p = list->data, *end = p + list->length; p < end; p += sizeof(lcomm)) {
+    memcpy(&v.val.ec, p, sizeof(lcomm));
     if (find_tree(set, v))
       return 1;
   }
@@ -353,8 +345,8 @@ clist_filter(struct linpool *pool, struct adata *list, struct f_val set, int pos
   else
     v.type = T_PAIR;
 
-  int len = int_set_get_size(list);
-  u32 *l = int_set_get_data(list);
+  int len = list->length / 4;
+  u32 *l = (u32 *) list->data;
   u32 tmp[len];
   u32 *k = tmp;
   u32 *end = l + len;
@@ -384,15 +376,15 @@ eclist_filter(struct linpool *pool, struct adata *list, struct f_val set, int po
   int tree = (set.type == T_SET);      /* 1 -> set is T_SET, 0 -> set is T_CLIST */
   struct f_val v;
 
-  int len = int_set_get_size(list);
-  u32 *l = int_set_get_data(list);
+  int len = list->length / 4;
+  u32 *l = (u32 *) list->data;
   u32 tmp[len];
   u32 *k = tmp;
   int i;
 
   v.type = T_EC;
   for (i = 0; i < len; i += 2) {
-    v.val.ec = ec_get(l, i);
+    memcpy(&(v.val.ec), &(l[i]), sizeof(u64));
     /* pos && member(val, set) || !pos && !member(val, set),  member() depends on tree */
     if ((tree ? !!find_tree(set.val.t, v) : ec_set_contains(set.val.ad, v.val.ec)) == pos) {
       *k++ = l[i];
@@ -418,18 +410,21 @@ lclist_filter(struct linpool *pool, struct adata *list, struct f_val set, int po
   int tree = (set.type == T_SET);      /* 1 -> set is T_SET, 0 -> set is T_CLIST */
   struct f_val v;
 
-  int len = int_set_get_size(list);
-  u32 *l = int_set_get_data(list);
+  int len = list->length / 4;
+  u32 *l = (u32 *) list->data;
   u32 tmp[len];
   u32 *k = tmp;
   int i;
 
   v.type = T_LC;
   for (i = 0; i < len; i += 3) {
-    v.val.lc = lc_get(l, i);
+    memcpy(&(v.val.lc), &(l[i]), sizeof(lcomm));
     /* pos && member(val, set) || !pos && !member(val, set),  member() depends on tree */
-    if ((tree ? !!find_tree(set.val.t, v) : lc_set_contains(set.val.ad, v.val.lc)) == pos)
-      k = lc_copy(k, l+i);
+    if ((tree ? !!find_tree(set.val.t, v) : lc_set_contains(set.val.ad, v.val.lc)) != pos)
+      continue;
+
+    memcpy(k, &(l[i]), sizeof(lcomm));
+    k += sizeof(lcomm)/sizeof(u32);
   }
 
   uint nl = (k - tmp) * sizeof(u32);
@@ -871,9 +866,9 @@ interpret(struct f_inst *what)
        switch(v1.type) {
          case T_NET:    res.val.i = net_pxlen(v1.val.net); break;
          case T_PATH:   res.val.i = as_path_getlen(v1.val.ad); break;
-         case T_CLIST:  res.val.i = int_set_get_size(v1.val.ad); break;
-         case T_ECLIST: res.val.i = ec_set_get_size(v1.val.ad); break;
-         case T_LCLIST: res.val.i = lc_set_get_size(v1.val.ad); break;
+         case T_CLIST:  res.val.i = v1.val.ad->length / 4; break;
+         case T_ECLIST: res.val.i = v1.val.ad->length / 8; break;
+         case T_LCLIST: res.val.i = v1.val.ad->length / 12; break;
          default: runtime( "Prefix, path, clist, eclist or lclist expected" );
        }
        break;
index 69d337354526765a9c89ecd536587a6c3486ad77..c102a8e5f4617b69989df094f6248209ad5b64cd 100644 (file)
@@ -117,10 +117,10 @@ ec_format(byte *buf, u64 ec)
 int
 ec_set_format(struct adata *set, int from, byte *buf, uint size)
 {
-  u32 *z = int_set_get_data(set);
+  u32 *z = (u32 *) set->data;
   byte *end = buf + size - 64;
   int from2 = MAX(from, 0);
-  int to = int_set_get_size(set);
+  int to = set->length / 4;
   int i;
 
   for (i = from2; i < to; i += 2)
@@ -137,7 +137,9 @@ ec_set_format(struct adata *set, int from, byte *buf, uint size)
       if (i > from2)
        *buf++ = ' ';
 
-      buf += ec_format(buf, ec_get(z, i));
+      u64 ec;
+      memcpy(&ec, &(z[i]), sizeof(u64));
+      buf += ec_format(buf, ec);
     }
   *buf = 0;
   return 0;
@@ -181,16 +183,16 @@ lc_set_format(struct adata *set, int from, byte *buf, uint bufsize)
 }
 
 int
-set_position(struct adata *list, u32 *val, int skip)
+set_position(struct adata *list, void *val, int size)
 {
   if (!list)
     return -1;
 
-  u32 *l = int_set_get_data(list);
-  int len = list->length / (skip * 4);
+  int len = list->length / size;
+  void *l = list->data;
 
   for (int i = 0; i < len; i++)
-    if (!memcmp(&(l[i*skip]), val, skip * 4))
+    if (!memcmp(l + i * size, val, size))
       return i;
 
   return -1;
@@ -218,7 +220,7 @@ int_set_prepend(struct linpool *pool, struct adata *list, u32 val)
 }
 
 struct adata *
-set_add(struct linpool *pool, struct adata *list, u32 *val, int size)
+set_add(struct linpool *pool, struct adata *list, void *val, int size)
 {
   struct adata *res;
   int len;
@@ -227,30 +229,30 @@ set_add(struct linpool *pool, struct adata *list, u32 *val, int size)
     return list;
 
   len = list ? list->length : 0;
-  res = lp_alloc(pool, sizeof(struct adata) + len + size * 4);
-  res->length = len + size * 4;
+  res = lp_alloc(pool, sizeof(struct adata) + len + size);
+  res->length = len + size;
 
   if (list)
     memcpy(res->data, list->data, len);
 
-  memcpy(res->data + len, val, size * 4);
+  memcpy(res->data + len, val, size);
 
   return res;
 }
 
 struct adata *
-set_del(struct linpool *pool, struct adata *list, u32 *val, int size)
+set_del(struct linpool *pool, struct adata *list, void *val, int size)
 {
   int pos = set_position(list, val, size);
   if (pos == -1)
     return list;
 
-  int len = list->length - 4*size;
+  int len = list->length - size;
   struct adata *res = lp_alloc(pool, sizeof(struct adata) + len);
   res->length = len;
 
-  u32 *dest = int_set_get_data(res);
-  u32 *src = int_set_get_data(list);
+  void *dest = res->data;
+  void *src = list->data;
   memcpy(dest, src, size * pos);
   memcpy(dest + size * pos, src + size * (pos + 1), size * (len - pos));
 
@@ -267,15 +269,15 @@ set_union(struct linpool *pool, struct adata *l1, struct adata *l2, int size)
 
   /* Filter out duplicit data from l2 */
   struct adata *res;
-  int len = l2->length / (size * 4);
-  u32 *l = int_set_get_data(l2);
-  u32 tmp[len*size];
-  u32 *k = tmp;
+  int len = l2->length / size;
+  void *l = l2->data;
+  u32 tmp[len*size/sizeof(u32)];
+  void *k = tmp;
 
   for (int i = 0; i < len; i++)
     if (!set_contains(l1, l + i*size, size))
     {
-      memcpy(k, l + i*size, size * 4);
+      memcpy(k, l + i*size, size);
       k += size;
     }
 
@@ -283,7 +285,7 @@ set_union(struct linpool *pool, struct adata *l1, struct adata *l2, int size)
   if (k == tmp)
     return l1;
 
-  len = (k - tmp) * 4;
+  len = (k - (void*)tmp);
   res = lp_alloc(pool, sizeof(struct adata) + l1->length + len);
   res->length = l1->length + len;
   memcpy(res->data, l1->data, l1->length);
@@ -296,9 +298,9 @@ struct adata *
 ec_set_del_nontrans(struct linpool *pool, struct adata *set)
 {
   adata *res = lp_alloc_adata(pool, set->length);
-  u32 *src = int_set_get_data(set);
-  u32 *dst = int_set_get_data(res);
-  int len = int_set_get_size(set);
+  u32 *src = (u32 *) set->data;
+  u32 *dst = (u32 *) res->data;
+  int len = set->length / 4;
   int i;
 
   /* Remove non-transitive communities (EC_TBIT set) */
@@ -336,8 +338,8 @@ int_set_sort(struct linpool *pool, struct adata *src)
 static int
 ec_set_cmp(const void *X, const void *Y)
 {
-  u64 x = ec_get(X, 0);
-  u64 y = ec_get(Y, 0);
+  u64 x = *((u64 *) X);
+  u64 y = *((u64 *) Y);
   return (x < y) ? -1 : (x > y) ? 1 : 0;
 }
 
@@ -376,6 +378,6 @@ lc_set_sort(struct linpool *pool, struct adata *src)
 {
   struct adata *dst = lp_alloc_adata(pool, src->length);
   memcpy(dst->data, src->data, src->length);
-  qsort(dst->data, dst->length / LCOMM_LENGTH, LCOMM_LENGTH, lc_set_cmp);
+  qsort(dst->data, dst->length / sizeof(lcomm), sizeof(lcomm), lc_set_cmp);
   return dst;
 }
index a5081f9f4fec4e6f74c71d06bc1544806d28eaef..5deeb4f3a4603df01e6acda9298c39d53e89d521 100644 (file)
@@ -69,21 +69,21 @@ generate_set_sequence(enum set_type type)
 static int
 t_set_int_contains(void)
 {
-  int i;
+  u32 i;
 
   resource_init();
   generate_set_sequence(SET_TYPE_INT);
 
-  bt_assert(int_set_get_size(set_sequence) == SET_SIZE);
+  bt_assert(set_sequence->length / 4 == SET_SIZE);
 
   for (i = 0; i < SET_SIZE; i++)
     bt_assert(int_set_contains(set_sequence, i));
   bt_assert(int_set_contains(set_sequence, -1) == 0);
   bt_assert(int_set_contains(set_sequence, SET_SIZE) == 0);
 
-  int *data = int_set_get_data(set_sequence);
+  u32 *data = (u32 *) set_sequence->data;
   for (i = 0; i < SET_SIZE; i++)
-    bt_assert_msg(data[i] == i, "(data[i] = %d) == i = %d)", data[i], i);
+    bt_assert_msg(data[i] == i, "(data[i] = %u) == i = %u)", data[i], i);
 
   rfree(lp);
   return 1;
@@ -97,11 +97,11 @@ t_set_int_union(void)
 
   struct adata *set_union;
   set_union = int_set_union(lp, set_sequence, set_sequence_same);
-  bt_assert(int_set_get_size(set_union) == SET_SIZE);
+  bt_assert(set_union->length / 4 == SET_SIZE);
   bt_assert(int_set_format(set_union, 0, 2, buf, BUFFER_SIZE) == 0);
 
   set_union = int_set_union(lp, set_sequence, set_sequence_higher);
-  bt_assert_msg(int_set_get_size(set_union) == SET_SIZE*2, "int_set_get_size(set_union) %d, SET_SIZE*2 %d", int_set_get_size(set_union), SET_SIZE*2);
+  bt_assert_msg(set_union->length / 4 == SET_SIZE*2, "set_union->length/4 %d, SET_SIZE*2 %d", set_union->length / 4, SET_SIZE*2);
   bt_assert(int_set_format(set_union, 0, 2, buf, BUFFER_SIZE) == 0);
 
   rfree(lp);
@@ -141,13 +141,13 @@ t_set_int_delete(void)
   for (i = 0; i < SET_SIZE; i++)
   {
     deleting_sequence = int_set_del(lp, deleting_sequence, i);
-    bt_assert_msg(int_set_get_size(deleting_sequence) == (int) (SET_SIZE-1-i),
-                 "int_set_get_size(deleting_sequence) %d == SET_SIZE-1-i %d",
-                 int_set_get_size(deleting_sequence),
+    bt_assert_msg(deleting_sequence->length / 4 == (uint) (SET_SIZE-1-i),
+                 "deleting_sequence->length/4 %d == SET_SIZE-1-i %d",
+                 deleting_sequence->length / 4,
                  SET_SIZE-1-i);
   }
 
-  bt_assert(int_set_get_size(set_sequence) == SET_SIZE);
+  bt_assert(set_sequence->length/4 == SET_SIZE);
 
   return 1;
 }
@@ -164,7 +164,7 @@ t_set_ec_contains(void)
   resource_init();
   generate_set_sequence(SET_TYPE_EC);
 
-  bt_assert(ec_set_get_size(set_sequence) == SET_SIZE);
+  bt_assert(set_sequence->length/8 == SET_SIZE);
 
   for (i = 0; i < SET_SIZE; i++)
     bt_assert(ec_set_contains(set_sequence, i));
@@ -187,11 +187,11 @@ t_set_ec_union(void)
 
   struct adata *set_union;
   set_union = ec_set_union(lp, set_sequence, set_sequence_same);
-  bt_assert(ec_set_get_size(set_union) == SET_SIZE);
+  bt_assert(set_union->length/8 == SET_SIZE);
   bt_assert(ec_set_format(set_union, 0, buf, BUFFER_SIZE) == 0);
 
   set_union = ec_set_union(lp, set_sequence, set_sequence_higher);
-  bt_assert_msg(ec_set_get_size(set_union) == SET_SIZE*2, "ec_set_get_size(set_union) %d, SET_SIZE*2 %d", ec_set_get_size(set_union), SET_SIZE*2);
+  bt_assert_msg(set_union->length/8 == SET_SIZE*2, "set_union->length/8 %d, SET_SIZE*2 %d", set_union->length/8, SET_SIZE*2);
   bt_assert(ec_set_format(set_union, 0, buf, BUFFER_SIZE) == 0);
 
   rfree(lp);
@@ -231,12 +231,12 @@ t_set_ec_delete(void)
   for (i = 0; i < SET_SIZE; i++)
   {
     deleting_sequence = ec_set_del(lp, deleting_sequence, i);
-    bt_assert_msg(ec_set_get_size(deleting_sequence) == (int) (SET_SIZE-1-i),
+    bt_assert_msg(deleting_sequence->length/8 == (uint) (SET_SIZE-1-i),
                  "ec_set_get_size(deleting_sequence) %d  == SET_SIZE-1-i %d",
-                 ec_set_get_size(deleting_sequence), SET_SIZE-1-i);
+                 deleting_sequence->length/8, SET_SIZE-1-i);
   }
 
-  bt_assert(ec_set_get_size(set_sequence) == SET_SIZE);
+  bt_assert(set_sequence->length/8 == SET_SIZE);
 
   return 1;
 }
index 7058924d82c0e2369509b01756740f53158f2686..515bebc948594cde796cdd03b646566646c2a448 100644 (file)
@@ -119,23 +119,6 @@ aggregator_to_old(struct linpool *pool, struct adata *a)
 
 #define ECOMM_LENGTH 8
 
-static inline int int_set_get_size(struct adata *list)
-{ return list->length / 4; }
-
-static inline int ec_set_get_size(struct adata *list)
-{ return list->length / 8; }
-
-static inline int lc_set_get_size(struct adata *list)
-{ return list->length / 12; }
-
-static inline u32 *int_set_get_data(struct adata *list)
-{ return (u32 *) list->data; }
-
-static inline u32 ec_hi(u64 ec) { return ec >> 32; }
-static inline u32 ec_lo(u64 ec) { return ec; }
-static inline u64 ec_get(const u32 *l, int i)
-{ return (((u64) l[i]) << 32) | l[i+1]; }
-
 /* RFC 4360 3.1.  Two-Octet AS Specific Extended Community */
 static inline u64 ec_as2(u64 kind, u64 key, u64 val)
 { return ((kind | 0x0000) << 48) | (key << 32) | val; }
@@ -158,19 +141,8 @@ typedef struct lcomm {
   u32 ldp2;
 } lcomm;
 
-#define LCOMM_LENGTH 12
-
-static inline lcomm lc_get(const u32 *l, int i)
-{ return (lcomm) { l[i], l[i+1], l[i+2] }; }
-
-static inline void lc_put(u32 *l, lcomm v)
-{ l[0] = v.asn; l[1] = v.ldp1; l[2] = v.ldp2; }
-
-static inline int lc_match(const u32 *l, int i, lcomm v)
-{ return (l[i] == v.asn && l[i+1] == v.ldp1 && l[i+2] == v.ldp2); }
-
-static inline u32 *lc_copy(u32 *dst, const u32 *src)
-{ memcpy(dst, src, LCOMM_LENGTH); return dst + 3; }
+static inline int int_set_get_size(struct adata *set)
+{ return set->length / 4; }
 
 int int_set_format(struct adata *set, int way, int from, byte *buf, uint size);
 int ec_format(byte *buf, u64 ec);
@@ -178,59 +150,42 @@ int ec_set_format(struct adata *set, int from, byte *buf, uint size);
 int lc_format(byte *buf, lcomm lc);
 int lc_set_format(struct adata *set, int from, byte *buf, uint size);
 
-int set_position(struct adata *list, u32 *val, int skip);
-static inline int set_contains(struct adata *list, u32 *val, int skip)
-{ return set_position(list, val, skip) != -1; }
+int set_position(struct adata *list, void *val, int size);
+static inline int set_contains(struct adata *list, void *val, int size)
+{ return set_position(list, val, size) != -1; }
 static inline int int_set_contains(struct adata *list, u32 val)
-{ return set_contains(list, &val, 1); }
+{ return set_contains(list, &val, sizeof(val)); }
 static inline int ec_set_contains(struct adata *list, u64 val)
-{
-  u32 ec[2] = { ec_hi(val), ec_lo(val) };
-  return set_contains(list, ec, 2);
-}
+{ return set_contains(list, &val, sizeof(val)); }
 static inline int lc_set_contains(struct adata *list, lcomm val)
-{
-  u32 lc[3] = { val.asn, val.ldp1, val.ldp2 };
-  return set_contains(list, lc, 3);
-}
+{ return set_contains(list, &val, sizeof(val)); }
 
 struct adata *int_set_prepend(struct linpool *pool, struct adata *list, u32 val);
 
-struct adata *set_add(struct linpool *pool, struct adata *list, u32 *val, int size);
+struct adata *set_add(struct linpool *pool, struct adata *list, void *val, int size);
 static inline struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val)
-{ return set_add(pool, list, &val, 1); };
+{ return set_add(pool, list, &val, sizeof(val)); };
 static inline struct adata *ec_set_add(struct linpool *pool, struct adata *list, u64 val)
-{
-  u32 ec[2] = { ec_hi(val), ec_lo(val) };
-  return set_add(pool, list, ec, 2);
-}
+{ return set_add(pool, list, &val, sizeof(val)); };
 static inline struct adata *lc_set_add(struct linpool *pool, struct adata *list, lcomm val)
-{
-  u32 lc[3] = { val.asn, val.ldp1, val.ldp2 };
-  return set_add(pool, list, lc, 3);
-}
+{ return set_add(pool, list, &val, sizeof(val)); };
 
-struct adata *set_del(struct linpool *pool, struct adata *list, u32 *val, int size);
+struct adata *set_del(struct linpool *pool, struct adata *list, void *val, int size);
 static inline struct adata *int_set_del(struct linpool *pool, struct adata *list, u32 val)
-{ return set_del(pool, list, &val, 1); }
+{ return set_del(pool, list, &val, sizeof(val)); }
 static inline struct adata *ec_set_del(struct linpool *pool, struct adata *list, u64 val)
-{
-  u32 ec[2] = { ec_hi(val), ec_lo(val) };
-  return set_del(pool, list, ec, 2);
-}
+{ return set_del(pool, list, &val, sizeof(val)); }
 static inline struct adata *lc_set_del(struct linpool *pool, struct adata *list, lcomm val)
-{
-  u32 lc[3] = { val.asn, val.ldp1, val.ldp2 };
-  return set_del(pool, list, lc, 3);
-}
+{ return set_del(pool, list, &val, sizeof(val)); }
 
 struct adata *set_union(struct linpool *pool, struct adata *l1, struct adata *l2, int size);
 static inline struct adata *int_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
-{ return set_union(pool, l1, l2, 1); }
+{ return set_union(pool, l1, l2, sizeof(u32)); }
 static inline struct adata *ec_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
-{ return set_union(pool, l1, l2, 2); }
+{ return set_union(pool, l1, l2, sizeof(u64)); }
 static inline struct adata *lc_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
-{ return set_union(pool, l1, l2, 3); }
+{ return set_union(pool, l1, l2, sizeof(lcomm)); }
+
 
 struct adata *ec_set_del_nontrans(struct linpool *pool, struct adata *set);
 struct adata *int_set_sort(struct linpool *pool, struct adata *src);