Commit abec2008 authored by Maria Jan Matejka's avatar Maria Jan Matejka Committed by Jan Maria Matejka
Browse files

Better dumping of trie. Works only for IPv4 now.

parent 0389931a
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -277,8 +277,21 @@ trie_node_format(struct f_trie_node *t, buffer *buf)
  if (t == NULL)
    return;

  if (ipa_nonzero(t->accept))
    buffer_print(buf, "%I/%d{%I}, ", t->addr, t->plen, t->accept);
  ip_addr amask = t->accept;
  while (ipa_nonzero(amask))
    {
      int top, bottom;
      ip_addr cmask = ipa_bitrange(amask, &top, &bottom);

      if ((t->plen == top) && (t->plen == bottom-1))
	buffer_print(buf, "%I/%d, ", t->addr, t->plen);
      else if ((t->plen == top) && (bottom-1 == MAX_PREFIX_LENGTH))
	buffer_print(buf, "%I/%d+, ", t->addr, t->plen);
      else
	buffer_print(buf, "%I/%d{%d,%d}, ", t->addr, t->plen, top, bottom-1);

      amask = ipa_xor(amask, cmask);
    }

  trie_node_format(t->c[0], buf);
  trie_node_format(t->c[1], buf);
+24 −0
Original line number Diff line number Diff line
@@ -68,3 +68,27 @@ u32_log2(u32 v)
  return r;
}

/**
 * u32_bitrange - find a contiguos series of 1's.
 * @v: number
 * @tp: pointer to top index (first 1: <31,0>)
 * @bp: pointer to bottom index (first 0: <30,-1>)
 * 
 * This functions finds the most significant contiguous series of 1's and returns it.
 * If the pointers are set, the indices are also written there.
 */
u32
u32_bitrange(u32 v, int *tp, int *bp)
{
						/* Example:		0x07ffe030 */
  int ti = u32_log2(v);				/* Get first 1's index: 26 */
  u32 t = (1 << (ti + 1)) - 1;			/* Get 1's mask:	0x07ffffff */
  u32 r = t ^ v;				/* Unmask the 1's:	0x00001fcf */
  int bi = (v & (v+1)) ? (int)u32_log2(r) : -1;	/* Get first 1's index:	12 */
  u32 b = (1 << (bi + 1)) - 1;			/* Get the mask:	0x00001fff */
  if (tp)
    *tp = ti;
  if (bp)
    *bp = bi;
  return t ^ b;					/* Return the bitrange: 0x07ffe000 */
}
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ u32 u32_mkmask(uint n);
int u32_masklen(u32 x);

u32 u32_log2(u32 v);
u32 u32_bitrange(u32 v, int *top, int *bottom);

static inline u32 u32_hash(u32 v) { return v * 2902958171u; }

+10 −0
Original line number Diff line number Diff line
@@ -326,6 +326,15 @@ static inline ip4_addr ip4_mkmask(uint n)
static inline int ip4_masklen(ip4_addr a)
{ return u32_masklen(_I(a)); }

static inline ip4_addr ip4_bitrange(ip4_addr a, int *tp, int *bp)
{
  int t, b;
  a = u32_bitrange(a, &t, &b);
  if (tp) *tp = 32-t;
  if (bp) *bp = 32-b;
  return a;
}

ip6_addr ip6_mkmask(uint n);
int ip6_masklen(ip6_addr *a);

@@ -373,6 +382,7 @@ ip4_addr ip4_class_mask(ip4_addr ad);
#else
#define ipa_mkmask(x) ip4_mkmask(x)
#define ipa_masklen(x) ip4_masklen(x)
#define ipa_bitrange(x,tp,bp) ip4_bitrange(x,tp,bp)
#define ipa_pxlen(x,y) ip4_pxlen(x,y)
#define ipa_getbit(x,n) ip4_getbit(x,n)
#define ipa_opposite_m1(x) ip4_opposite_m1(x)