Hostcache should use trie to filter relevant route changes.
This commit is contained in:
parent
7f0d245a5e
commit
c477f48916
3 changed files with 20 additions and 20 deletions
|
@ -114,8 +114,8 @@ attach_node(struct f_trie_node *parent, struct f_trie_node *child)
|
||||||
* @h: prefix upper bound
|
* @h: prefix upper bound
|
||||||
*
|
*
|
||||||
* Adds prefix (prefix pattern) @px/@plen to trie @t. @l and @h are lower
|
* Adds prefix (prefix pattern) @px/@plen to trie @t. @l and @h are lower
|
||||||
* and upper bounds on accepted prefix lengths, both inclusive. 0 <=
|
* and upper bounds on accepted prefix lengths, both inclusive.
|
||||||
* l, h <= 32 (128 for IPv6).
|
* 0 <= l, h <= 32 (128 for IPv6).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -155,8 +155,9 @@ struct hostcache {
|
||||||
unsigned hash_order, hash_shift;
|
unsigned hash_order, hash_shift;
|
||||||
unsigned hash_max, hash_min;
|
unsigned hash_max, hash_min;
|
||||||
unsigned hash_items;
|
unsigned hash_items;
|
||||||
|
linpool *lp; /* Linpool for trie */
|
||||||
list hostentries;
|
struct f_trie *trie; /* Trie of prefixes that might affect hostentries */
|
||||||
|
list hostentries; /* List of all hostentries */
|
||||||
byte update_hostcache;
|
byte update_hostcache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -170,7 +171,6 @@ struct hostentry {
|
||||||
struct iface *iface; /* Chosen outgoing interface */
|
struct iface *iface; /* Chosen outgoing interface */
|
||||||
ip_addr gw; /* Chosen next hop */
|
ip_addr gw; /* Chosen next hop */
|
||||||
byte dest; /* Chosen route destination type (RTD_...) */
|
byte dest; /* Chosen route destination type (RTD_...) */
|
||||||
byte pxlen; /* Pxlen from net that matches route */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct rte {
|
typedef struct rte {
|
||||||
|
|
|
@ -1399,6 +1399,9 @@ rt_init_hostcache(rtable *tab)
|
||||||
hc_alloc_table(hc, HC_DEF_ORDER);
|
hc_alloc_table(hc, HC_DEF_ORDER);
|
||||||
hc->slab = sl_new(rt_table_pool, sizeof(struct hostentry));
|
hc->slab = sl_new(rt_table_pool, sizeof(struct hostentry));
|
||||||
|
|
||||||
|
hc->lp = lp_new(rt_table_pool, 1008);
|
||||||
|
hc->trie = f_new_trie(hc->lp);
|
||||||
|
|
||||||
tab->hostcache = hc;
|
tab->hostcache = hc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1416,6 +1419,7 @@ rt_free_hostcache(rtable *tab)
|
||||||
}
|
}
|
||||||
|
|
||||||
rfree(hc->slab);
|
rfree(hc->slab);
|
||||||
|
rfree(hc->lp);
|
||||||
mb_free(hc->hash_table);
|
mb_free(hc->hash_table);
|
||||||
mb_free(hc);
|
mb_free(hc);
|
||||||
}
|
}
|
||||||
|
@ -1428,17 +1432,8 @@ rt_notify_hostcache(rtable *tab, net *net)
|
||||||
if (tab->hcu_scheduled)
|
if (tab->hcu_scheduled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
node *n;
|
if (trie_match_prefix(hc->trie, net->n.prefix, net->n.pxlen))
|
||||||
WALK_LIST(n, hc->hostentries)
|
|
||||||
{
|
|
||||||
struct hostentry *he = SKIP_BACK(struct hostentry, ln, n);
|
|
||||||
if (ipa_in_net(he->addr, net->n.prefix, net->n.pxlen) &&
|
|
||||||
(he->pxlen <= net->n.pxlen))
|
|
||||||
{
|
|
||||||
rt_schedule_hcu(tab);
|
rt_schedule_hcu(tab);
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1459,11 +1454,13 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
|
||||||
struct iface *old_iface = he->iface;
|
struct iface *old_iface = he->iface;
|
||||||
ip_addr old_gw = he->gw;
|
ip_addr old_gw = he->gw;
|
||||||
byte old_dest = he->dest;
|
byte old_dest = he->dest;
|
||||||
|
int pxlen = 0;
|
||||||
|
|
||||||
net *n = fib_route(&tab->fib, he->addr, MAX_PREFIX_LENGTH);
|
net *n = fib_route(&tab->fib, he->addr, MAX_PREFIX_LENGTH);
|
||||||
if (n && n->routes)
|
if (n && n->routes)
|
||||||
{
|
{
|
||||||
rta *a = n->routes->attrs;
|
rta *a = n->routes->attrs;
|
||||||
|
pxlen = n->n.pxlen;
|
||||||
|
|
||||||
if (a->dest == RTD_DEVICE)
|
if (a->dest == RTD_DEVICE)
|
||||||
{
|
{
|
||||||
|
@ -1491,8 +1488,6 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
|
||||||
he->gw = a->gw;
|
he->gw = a->gw;
|
||||||
he->dest = a->dest;
|
he->dest = a->dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
he->pxlen = n->n.pxlen;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1500,10 +1495,11 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
|
||||||
he->iface = NULL;
|
he->iface = NULL;
|
||||||
he->gw = IPA_NONE;
|
he->gw = IPA_NONE;
|
||||||
he->dest = RTD_UNREACHABLE;
|
he->dest = RTD_UNREACHABLE;
|
||||||
|
|
||||||
he->pxlen = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add a prefix range to the trie */
|
||||||
|
trie_add_prefix(tab->hostcache->trie, he->addr, MAX_PREFIX_LENGTH, pxlen, MAX_PREFIX_LENGTH);
|
||||||
|
|
||||||
return hostentry_diff(he, old_iface, old_gw, old_dest);
|
return hostentry_diff(he, old_iface, old_gw, old_dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1514,6 +1510,10 @@ rt_update_hostcache(rtable *tab)
|
||||||
struct hostentry *he;
|
struct hostentry *he;
|
||||||
node *n, *x;
|
node *n, *x;
|
||||||
|
|
||||||
|
/* Reset the trie */
|
||||||
|
lp_flush(hc->lp);
|
||||||
|
hc->trie = f_new_trie(hc->lp);
|
||||||
|
|
||||||
WALK_LIST_DELSAFE(n, x, hc->hostentries)
|
WALK_LIST_DELSAFE(n, x, hc->hostentries)
|
||||||
{
|
{
|
||||||
he = SKIP_BACK(struct hostentry, ln, n);
|
he = SKIP_BACK(struct hostentry, ln, n);
|
||||||
|
|
Loading…
Reference in a new issue