mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 07:31:54 +00:00
tmp: tmp progress on trie API
This commit is contained in:
parent
7e68ba64a9
commit
3719d746bc
115
filter/trie.c
115
filter/trie.c
@ -817,12 +817,13 @@ trie_walk_init(struct f_trie_walk_state *s, const struct f_trie *t, const net_ad
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (!net)
|
if (!net)
|
||||||
return 1;
|
{ log("return 0"); return 0; }
|
||||||
|
|
||||||
/* We want to find node of level at least plen */
|
/* We want to find node of level at least plen */
|
||||||
int plen = ROUND_DOWN_POW2(net->pxlen, TRIE_STEP);
|
int plen = ROUND_DOWN_POW2(net->pxlen, TRIE_STEP);
|
||||||
const struct f_trie_node *n = &t->root;
|
const struct f_trie_node *n = &t->root;
|
||||||
const int v4 = t->ipv4;
|
const int v4 = t->ipv4;
|
||||||
|
int step;
|
||||||
|
|
||||||
while (n)
|
while (n)
|
||||||
{
|
{
|
||||||
@ -838,7 +839,7 @@ trie_walk_init(struct f_trie_walk_state *s, const struct f_trie *t, const net_ad
|
|||||||
if (nlen == plen)
|
if (nlen == plen)
|
||||||
{
|
{
|
||||||
/* Find proper local_pos, while accept_length is not used */
|
/* Find proper local_pos, while accept_length is not used */
|
||||||
int step = net->pxlen - plen;
|
step = net->pxlen - plen;
|
||||||
s->start_pos = s->local_pos = (1u << step) + GET_NET_BITS(net, v4, plen, step);
|
s->start_pos = s->local_pos = (1u << step) + GET_NET_BITS(net, v4, plen, step);
|
||||||
s->accept_length = plen;
|
s->accept_length = plen;
|
||||||
}
|
}
|
||||||
@ -859,6 +860,7 @@ trie_walk_init(struct f_trie_walk_state *s, const struct f_trie *t, const net_ad
|
|||||||
s->start_pos = 1;
|
s->start_pos = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log("return 1");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -873,15 +875,114 @@ trie_walk_init(struct f_trie_walk_state *s, const struct f_trie *t, const net_ad
|
|||||||
/* We do not override the trie root in case of inclusive search */
|
/* We do not override the trie root in case of inclusive search */
|
||||||
if (!include_successors)
|
if (!include_successors)
|
||||||
s->stack[0] = NULL;
|
s->stack[0] = NULL;
|
||||||
|
/* We are out of path, find nearest successor */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int nlen;
|
||||||
|
char buf[64];
|
||||||
|
char buf2[64];
|
||||||
|
net_format(net, buf, 64);
|
||||||
|
net_addr curr;
|
||||||
|
if (n == NULL)
|
||||||
|
log("node is null");
|
||||||
|
//bug("node is null");
|
||||||
|
else {
|
||||||
|
nlen = v4 ? n->v4.plen : n->v6.plen;
|
||||||
|
if (v4)
|
||||||
|
net_fill_ip4(&curr, ip4_and(n->v4.addr, ip4_mkmask(n->v4.plen)), n->v4.plen);
|
||||||
|
//net_fill_ip4(&curr, n->v4.addr, n->v4.plen);
|
||||||
|
else
|
||||||
|
net_fill_ip6(&curr, ip6_and(n->v6.addr, ip6_mkmask(n->v6.plen)), n->v6.plen);
|
||||||
|
//net_fill_ip6(&curr, n->v6.addr, n->v6.plen);
|
||||||
|
net_format(&curr, buf2, 64);
|
||||||
|
|
||||||
/* Be careful about underflow */
|
log(" !SAME_PREFIX: %s vs. %s\n", buf, buf2);
|
||||||
else if (s->stack_pos > 0)
|
}
|
||||||
|
|
||||||
|
if (s->stack_pos > 0)
|
||||||
|
n = s->stack[s->stack_pos - 1];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log("root fallback");
|
||||||
|
n = &t->root;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlen = v4 ? n->v4.plen : n->v6.plen;
|
||||||
|
|
||||||
|
log("phase 2 after back step");
|
||||||
|
net_format(net, buf, 64);
|
||||||
|
if (v4)
|
||||||
|
net_fill_ip4(&curr, ip4_and(n->v4.addr, ip4_mkmask(n->v4.plen)), n->v4.plen);
|
||||||
|
//net_fill_ip4(&curr, n->v4.addr, n->v4.plen);
|
||||||
|
else
|
||||||
|
net_fill_ip6(&curr, ip6_and(n->v6.addr, ip6_mkmask(n->v6.plen)), n->v6.plen);
|
||||||
|
//net_fill_ip6(&curr, n->v6.addr, n->v6.plen);
|
||||||
|
net_format(&curr, buf2, 64);
|
||||||
|
log(" (%d) SAME_PREFIX: %s vs. %s\n", SAME_PREFIX(n, net, v4, MIN(net->pxlen, nlen)), buf, buf2);
|
||||||
|
|
||||||
|
step = net->pxlen - plen;
|
||||||
|
/* Stack position point one element ahead */
|
||||||
|
if (s->stack_pos == 1)
|
||||||
|
{
|
||||||
|
//bug("there");
|
||||||
|
log("there");
|
||||||
|
s->stack_pos--;
|
||||||
|
s->start_pos = s->local_pos = 1;
|
||||||
|
}
|
||||||
|
else if (s->stack_pos > 1)
|
||||||
|
{
|
||||||
|
//bug("over");
|
||||||
|
log("over");
|
||||||
s->stack_pos--;
|
s->stack_pos--;
|
||||||
|
|
||||||
/* Search whole trie except skipped parts */
|
nlen = (v4) ? n->v4.plen : n->v6.plen;
|
||||||
if (include_successors)
|
int next = (GET_NET_BITS(net, v4, nlen, step) + 1) % TRIE_STEP;
|
||||||
s->start_pos = 1;
|
while (s->stack_pos != 0 && next == 0)
|
||||||
|
{
|
||||||
|
n = s->stack[s->start_pos];
|
||||||
|
step--;
|
||||||
|
s->stack_pos--;
|
||||||
|
next = (GET_NET_BITS(net, v4, nlen, step) + 1) % TRIE_STEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix the stack_pos, one decrement one than needed */
|
||||||
|
s->stack_pos++;
|
||||||
|
|
||||||
|
if ((n = GET_CHILD(n, v4, next)) != NULL)
|
||||||
|
{
|
||||||
|
log("settting the positions");
|
||||||
|
s->stack[s->stack_pos] = n;
|
||||||
|
//s->start_pos = (1u << step) + GET_NET_BITS(net, v4, plen, step);
|
||||||
|
s->start_pos = 2 * (1u << step) + GET_NET_BITS(net, v4, plen, step);
|
||||||
|
s->local_pos = 2 * (1u << step) + GET_NET_BITS(net, v4, plen, step);
|
||||||
|
}
|
||||||
|
//s->start_pos = s->local_pos = (1u << step) + GET_NET_BITS(net, v4, plen, step);
|
||||||
|
//s->accept_length = plen;
|
||||||
|
/* s->start_pos and s->local_pos is already initialized */
|
||||||
|
}
|
||||||
|
/* Be careful around underflow */
|
||||||
|
else /* stack_pos == 0 */
|
||||||
|
{
|
||||||
|
bug("here");
|
||||||
|
|
||||||
|
//return 0;
|
||||||
|
s->stack[0] = &t->root;
|
||||||
|
s->start_pos = s->local_pos = (1u << step);
|
||||||
|
s->accept_length = plen;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct net_addr net_copy;
|
||||||
|
memcpy(&net_copy, net, sizeof(struct net_addr));
|
||||||
|
/*
|
||||||
|
if (v4)
|
||||||
|
net_fill_ip4(net, ip4_and(), len);
|
||||||
|
else
|
||||||
|
net_fill_ip6(net, ip6_and(), len);
|
||||||
|
*/
|
||||||
|
//trie_walk_next(s, &net_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
log("return 2");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -890,7 +890,8 @@ t_trie_walk_inclusive(void)
|
|||||||
{
|
{
|
||||||
int level = round / TESTS_NUM;
|
int level = round / TESTS_NUM;
|
||||||
int v6 = level % 2;
|
int v6 = level % 2;
|
||||||
int num = PREFIXES_NUM * (int[]){1, 10, 100, 1000}[level / 2];
|
//int num = PREFIXES_NUM * (int[]){0, 1, 10, 100, 1000}[level / 2];
|
||||||
|
int num = PREFIXES_NUM * (int[]){32, 512}[level / 2];
|
||||||
int pos = 0, end = 0;
|
int pos = 0, end = 0;
|
||||||
list *prefixes = make_random_prefix_list(num, v6, 1);
|
list *prefixes = make_random_prefix_list(num, v6, 1);
|
||||||
struct f_trie *trie = make_trie_from_prefix_list(prefixes);
|
struct f_trie *trie = make_trie_from_prefix_list(prefixes);
|
||||||
@ -903,7 +904,7 @@ t_trie_walk_inclusive(void)
|
|||||||
|
|
||||||
qsort(pxset, num, sizeof(struct f_prefix), compare_prefixes);
|
qsort(pxset, num, sizeof(struct f_prefix), compare_prefixes);
|
||||||
|
|
||||||
/* // print sorted prefixes
|
// print sorted prefixes
|
||||||
bt_debug("sorted prefixes\n");
|
bt_debug("sorted prefixes\n");
|
||||||
for (struct f_prefix *px = pxset; px < pxset + num; px++)
|
for (struct f_prefix *px = pxset; px < pxset + num; px++)
|
||||||
{
|
{
|
||||||
@ -937,12 +938,20 @@ t_trie_walk_inclusive(void)
|
|||||||
bt_debug("Full walk inclusive done\n");
|
bt_debug("Full walk inclusive done\n");
|
||||||
|
|
||||||
|
|
||||||
/* Prepare net for subnet walk - start with random prefix */
|
/* Prepare net for subnet walk - start with random prefix from trie */
|
||||||
|
if (num)
|
||||||
pos = bt_random() % num;
|
pos = bt_random() % num;
|
||||||
|
else
|
||||||
|
pos = 0;
|
||||||
end = pos + (int[]){2, 2, 3, 4}[level / 2];
|
end = pos + (int[]){2, 2, 3, 4}[level / 2];
|
||||||
end = MIN(end, num);
|
end = MIN(end, num);
|
||||||
|
|
||||||
struct f_prefix from = pxset[pos];
|
struct f_prefix from;
|
||||||
|
|
||||||
|
if (num)
|
||||||
|
from = pxset[pos];
|
||||||
|
else
|
||||||
|
get_random_prefix(&from, v6, 1);
|
||||||
|
|
||||||
/* Find a common superprefix to several subsequent prefixes */
|
/* Find a common superprefix to several subsequent prefixes */
|
||||||
for (; pos < end; pos++)
|
for (; pos < end; pos++)
|
||||||
@ -977,11 +986,6 @@ t_trie_walk_inclusive(void)
|
|||||||
if (compare_prefixes(&pxset[pos], &from) >= 0)
|
if (compare_prefixes(&pxset[pos], &from) >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Account for subnets before searched net from */
|
|
||||||
//for (; pos < num; pos++)
|
|
||||||
//if (net_compare(&pxset[pos].net, &from.net) >= 0)
|
|
||||||
//break;
|
|
||||||
|
|
||||||
int p0 = pos;
|
int p0 = pos;
|
||||||
char buf0[64];
|
char buf0[64];
|
||||||
bt_format_net(buf0, 64, &from.net);
|
bt_format_net(buf0, 64, &from.net);
|
||||||
@ -991,7 +995,8 @@ t_trie_walk_inclusive(void)
|
|||||||
TRIE_WALK2(trie, net, &from.net, 1)
|
TRIE_WALK2(trie, net, &from.net, 1)
|
||||||
{
|
{
|
||||||
log_networks(&net, &pxset[pos].net);
|
log_networks(&net, &pxset[pos].net);
|
||||||
bt_assert(net_compare(&net, &pxset[pos].net) >= 0);
|
//bt_assert(net_compare(&net, &pxset[pos].net) >= 0);
|
||||||
|
bt_assert(net_compare(&net, &from.net) >= 0);
|
||||||
|
|
||||||
/* Skip possible duplicates */
|
/* Skip possible duplicates */
|
||||||
while (net_equal(&pxset[pos].net, &pxset[pos + 1].net))
|
while (net_equal(&pxset[pos].net, &pxset[pos + 1].net))
|
||||||
@ -1004,11 +1009,76 @@ t_trie_walk_inclusive(void)
|
|||||||
bt_assert(pos == num);
|
bt_assert(pos == num);
|
||||||
bt_debug("Subnet walk done inclusive for %s (found %d nets)\n", buf0, pos - p0);
|
bt_debug("Subnet walk done inclusive for %s (found %d nets)\n", buf0, pos - p0);
|
||||||
|
|
||||||
|
/* Prepare net for subnet walk - start with random prefix (likely not from trie) */
|
||||||
|
get_random_prefix(&from, v6, 1);
|
||||||
|
|
||||||
|
for (pos = 0; pos < num; pos++)
|
||||||
|
{
|
||||||
|
bt_format_net(buf0, 64, &pxset[pos].net);
|
||||||
|
bt_debug(" -> %s ", buf0);
|
||||||
|
if (net_compare(&pxset[pos].net, &from.net) >= 0)
|
||||||
|
{
|
||||||
|
bt_debug("true, breaking\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bt_debug("false\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
p0 = pos;
|
||||||
|
bt_format_net(buf0, 64, &from.net);
|
||||||
|
bt_debug("Subnet walk inclusive for random %s (round %d, %d nets)\n", buf0, round, num);
|
||||||
|
|
||||||
|
/* Subnet walk */
|
||||||
|
TRIE_WALK2(trie, net, &from.net, 1)
|
||||||
|
{
|
||||||
|
/* Make sure that net is from inserted prefixes */
|
||||||
|
bt_format_net(buf0, 64, &net);
|
||||||
|
bt_debug("got: %s", buf0);
|
||||||
|
bt_format_net(buf0, 64, &pxset[pos].net);
|
||||||
|
bt_debug(" expected %s", buf0);
|
||||||
|
if (pos + 1 < num)
|
||||||
|
{
|
||||||
|
bt_format_net(buf0, 64, &pxset[pos + 1].net);
|
||||||
|
bt_debug(" (next: %s)\n", buf0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bt_debug("\n");
|
||||||
|
|
||||||
|
bt_assert(net_equal(&net, &pxset[pos].net));
|
||||||
|
bt_assert(net_compare(&net, &from.net) >= 0);
|
||||||
|
|
||||||
|
while (net_equal(&pxset[pos].net, &pxset[pos + 1].net))
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
TRIE_WALK2_END;
|
||||||
|
|
||||||
|
bt_debug("Subnet walk inclusive for random %s (found %d nets from %d)\n", buf0, pos - p0, num - p0);
|
||||||
|
bt_assert(pos == num);
|
||||||
|
|
||||||
tmp_flush();
|
tmp_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_bird_cleanup();
|
bt_bird_cleanup();
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* empty trie
|
||||||
|
* inclusive after last element
|
||||||
|
* inclusive before first element
|
||||||
|
* not found root (empty trie)
|
||||||
|
* not found root (after last)
|
||||||
|
* not found root (before first)
|
||||||
|
* not found root (single element)
|
||||||
|
* not found root inbetween
|
||||||
|
* not found first level
|
||||||
|
* not found first level (after)
|
||||||
|
* not found first level (before)
|
||||||
|
* general case (found / not found on higher level)
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
3
lib/ip.h
3
lib/ip.h
@ -145,9 +145,6 @@ static inline ip4_addr ip4_xor(ip4_addr a, ip4_addr b)
|
|||||||
static inline ip4_addr ip4_not(ip4_addr a)
|
static inline ip4_addr ip4_not(ip4_addr a)
|
||||||
{ return _MI4(~_I(a)); }
|
{ return _MI4(~_I(a)); }
|
||||||
|
|
||||||
static inline int ip4_less(ip4_addr a, ip4_addr b)
|
|
||||||
{ return _I(a) < _I(b); }
|
|
||||||
|
|
||||||
|
|
||||||
static inline int ip6_equal(ip6_addr a, ip6_addr b)
|
static inline int ip6_equal(ip6_addr a, ip6_addr b)
|
||||||
{ return _I0(a) == _I0(b) && _I1(a) == _I1(b) && _I2(a) == _I2(b) && _I3(a) == _I3(b); }
|
{ return _I0(a) == _I0(b) && _I1(a) == _I1(b) && _I2(a) == _I2(b) && _I3(a) == _I3(b); }
|
||||||
|
Loading…
Reference in New Issue
Block a user