0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

Nest: Use bitmask of pxlens to speed-up net_route()

Use bitmask to keep track of pxlens that might be in rtable to avoid
unnecessary lookups during net_route().
This commit is contained in:
Ondrej Zajicek (work) 2019-05-28 17:23:32 +02:00
parent 5c73cd94a5
commit 7d1c2ea5c0
2 changed files with 53 additions and 26 deletions

View File

@ -166,6 +166,8 @@ typedef struct rtable {
uint route_count; /* Number of routes in the table */
uint route_updates; /* Number of accepted route updates */
uint route_withdraws; /* Number of accepted route withdraws */
u32 pxlens[5]; /* Bitmask of pxlens that might be in rtable */
u32 pxlens_new[5]; /* The above bitmask, under recalculation */
struct hostcache *hostcache;
struct rtable_config *config; /* Configuration of this table */
struct config *deleted; /* Table doesn't exist in current configuration,
@ -301,10 +303,8 @@ void rt_lock_table(rtable *);
void rt_unlock_table(rtable *);
void rt_setup(pool *, rtable *, struct rtable_config *);
static inline net *net_find(rtable *tab, const net_addr *addr) { return (net *) fib_find(&tab->fib, addr); }
static inline net *net_find_valid(rtable *tab, const net_addr *addr)
{ net *n = net_find(tab, addr); return (n && rte_is_valid(n->routes)) ? n : NULL; }
static inline net *net_get(rtable *tab, const net_addr *addr) { return (net *) fib_get(&tab->fib, addr); }
void *net_route(rtable *tab, const net_addr *n);
net *net_route(rtable *tab, const net_addr *n);
int net_roa_check(rtable *tab, const net_addr *n, u32 asn);
rte *rte_find(net *net, struct rte_src *src);
rte *rte_get_temp(struct rta *);

View File

@ -58,35 +58,51 @@ static inline void rt_prune_table(rtable *tab);
/* Like fib_route(), but skips empty net entries */
static inline void *
net_route_ip4(rtable *t, net_addr_ip4 *n)
static inline net *
net_route_ip4(rtable *t, net_addr_ip4 *a)
{
net *r;
while (r = net_find_valid(t, (net_addr *) n), (!r) && (n->pxlen > 0))
while (1)
{
n->pxlen--;
ip4_clrbit(&n->prefix, n->pxlen);
}
if (!BIT32_TEST(t->pxlens, a->pxlen))
goto next;
return r;
net *n = net_find(t, (net_addr *) a);
if (n && rte_is_valid(n->routes))
return n;
next:
if (!a->pxlen)
return NULL;
a->pxlen--;
ip4_clrbit(&a->prefix, a->pxlen);
}
}
static inline void *
net_route_ip6(rtable *t, net_addr_ip6 *n)
static inline net *
net_route_ip6(rtable *t, net_addr_ip6 *a)
{
net *r;
while (r = net_find_valid(t, (net_addr *) n), (!r) && (n->pxlen > 0))
while (1)
{
n->pxlen--;
ip6_clrbit(&n->prefix, n->pxlen);
}
if (!BIT32_TEST(t->pxlens, a->pxlen))
goto next;
return r;
net *n = net_find(t, (net_addr *) a);
if (n && rte_is_valid(n->routes))
return n;
next:
if (!a->pxlen)
return NULL;
a->pxlen--;
ip6_clrbit(&a->prefix, a->pxlen);
}
}
static inline void *
static inline net *
net_route_ip6_sadr(rtable *t, net_addr_ip6_sadr *n)
{
struct fib_node *fn;
@ -96,6 +112,9 @@ net_route_ip6_sadr(rtable *t, net_addr_ip6_sadr *n)
net *best = NULL;
int best_pxlen = 0;
if (!BIT32_TEST(t->pxlens, n->dst_pxlen))
goto next;
/* We need to do dst first matching. Since sadr addresses are hashed on dst
prefix only, find the hash table chain and go through it to find the
match with the smallest matching src prefix. */
@ -115,17 +134,16 @@ net_route_ip6_sadr(rtable *t, net_addr_ip6_sadr *n)
if (best)
return best;
next:
if (!n->dst_pxlen)
break;
return NULL;
n->dst_pxlen--;
ip6_clrbit(&n->dst_prefix, n->dst_pxlen);
}
return NULL;
}
void *
net *
net_route(rtable *tab, const net_addr *n)
{
ASSERT(tab->addr_type == n->type);
@ -1415,6 +1433,9 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
if (!rta_is_cached(new->attrs)) /* Need to copy attributes */
new->attrs = rta_lookup(new->attrs);
new->flags |= REF_COW;
BIT32_SET(c->table->pxlens, net_pxlen(n));
BIT32_SET(c->table->pxlens_new, net_pxlen(n));
}
else
{
@ -1727,6 +1748,8 @@ rt_prune_table(rtable *tab)
FIB_ITERATE_INIT(fit, &tab->fib);
tab->prune_state = 2;
memset(tab->pxlens_new, 0, sizeof(tab->pxlens));
}
again:
@ -1757,6 +1780,8 @@ again:
fib_delete(&tab->fib, n);
goto again;
}
BIT32_SET(tab->pxlens_new, net_pxlen(n->n.addr));
}
FIB_ITERATE_END;
@ -1767,6 +1792,8 @@ again:
tab->gc_counter = 0;
tab->gc_time = current_time();
memcpy(tab->pxlens, tab->pxlens_new, sizeof(tab->pxlens));
/* state change 2->0, 3->1 */
tab->prune_state &= 1;