Commit 9ca88473 authored by Jan Maria Matejka's avatar Jan Maria Matejka
Browse files

WIP Nest: Making the clist/eclist/lclist even more generic

parent 73652196
Loading
Loading
Loading
Loading
+22 −27
Original line number Diff line number Diff line
@@ -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;
+29 −27
Original line number Diff line number Diff line
@@ -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;
}
+16 −16
Original line number Diff line number Diff line
@@ -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;
}
+20 −65
Original line number Diff line number Diff line
@@ -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);