mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-09 12:48:43 +00:00
Hostentry: made src ea_list atomic to help with consistency
This commit is contained in:
parent
a2ddd3d443
commit
ce1a8be9af
@ -622,7 +622,7 @@ struct hostentry {
|
||||
u32 igp_metric; /* Chosen route IGP metric */
|
||||
_Atomic u32 version; /* Bumped on update */
|
||||
byte nexthop_linkable; /* Nexthop list is completely non-device */
|
||||
ea_list *src; /* Source attributes */
|
||||
ea_list * _Atomic src; /* Source attributes */
|
||||
struct lfuc uc; /* Use count */
|
||||
};
|
||||
|
||||
|
@ -3275,13 +3275,14 @@ rta_apply_hostentry(ea_list **to, struct hostentry_adata *head)
|
||||
do {
|
||||
ea_set_attr_u32(to, &ea_gen_igp_metric, 0, he->igp_metric);
|
||||
|
||||
if (!he->src)
|
||||
ea_list *src = atomic_load_explicit(&he->src, memory_order_acquire);
|
||||
if (!src)
|
||||
{
|
||||
ea_set_dest(to, 0, RTD_UNREACHABLE);
|
||||
break;
|
||||
}
|
||||
|
||||
eattr *he_nh_ea = ea_find(he->src, &ea_gen_nexthop);
|
||||
eattr *he_nh_ea = ea_find(src, &ea_gen_nexthop);
|
||||
ASSERT_DIE(he_nh_ea);
|
||||
|
||||
struct nexthop_adata *nhad = (struct nexthop_adata *) he_nh_ea->u.ptr;
|
||||
@ -3291,7 +3292,7 @@ rta_apply_hostentry(ea_list **to, struct hostentry_adata *head)
|
||||
!lnum && he->nexthop_linkable)
|
||||
{
|
||||
/* Just link the nexthop chain, no label append happens. */
|
||||
ea_copy_attr(to, he->src, &ea_gen_nexthop);
|
||||
ea_copy_attr(to, src, &ea_gen_nexthop);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4225,7 +4226,7 @@ hc_new_hostentry(struct hostcache *hc, pool *p, ip_addr a, ip_addr ll, rtable *d
|
||||
static void
|
||||
hc_delete_hostentry(struct hostcache *hc, pool *p, struct hostentry *he)
|
||||
{
|
||||
ea_free(he->src);
|
||||
ea_free(atomic_load_explicit(&he->src, memory_order_relaxed));
|
||||
|
||||
rem_node(&he->ln);
|
||||
hc_remove(hc, he);
|
||||
@ -4351,7 +4352,7 @@ rt_free_hostcache(struct rtable_private *tab)
|
||||
WALK_LIST(n, hc->hostentries)
|
||||
{
|
||||
SKIP_BACK_DECLARE(struct hostentry, he, ln, n);
|
||||
ea_free(he->src);
|
||||
ea_free(atomic_load_explicit(&he->src, memory_order_relaxed));
|
||||
|
||||
if (!lfuc_finished(&he->uc))
|
||||
log(L_ERR "Hostcache is not empty in table %s", tab->name);
|
||||
@ -4397,7 +4398,6 @@ rt_get_igp_metric(const rte *rt)
|
||||
static int
|
||||
rt_update_hostentry(struct rtable_private *tab, struct hostentry *he)
|
||||
{
|
||||
ea_list *old_src = he->src;
|
||||
int direct = 0;
|
||||
int pxlen = 0;
|
||||
|
||||
@ -4405,7 +4405,8 @@ rt_update_hostentry(struct rtable_private *tab, struct hostentry *he)
|
||||
ASSERT_DIE((atomic_fetch_add_explicit(&he->version, 1, memory_order_acq_rel) & 1) == 0);
|
||||
|
||||
/* Reset the hostentry */
|
||||
he->src = NULL;
|
||||
ea_list *old_src = atomic_exchange_explicit(&he->src, NULL, memory_order_acq_rel);
|
||||
ea_list *new_src = NULL;
|
||||
he->nexthop_linkable = 0;
|
||||
he->igp_metric = 0;
|
||||
|
||||
@ -4455,11 +4456,11 @@ rt_update_hostentry(struct rtable_private *tab, struct hostentry *he)
|
||||
direct++;
|
||||
}
|
||||
|
||||
he->src = ea_ref(a);
|
||||
new_src = ea_ref(a);
|
||||
he->nexthop_linkable = !direct;
|
||||
he->igp_metric = rt_get_igp_metric(&e->rte);
|
||||
|
||||
if ((old_src != he->src) && (tab->debug & D_ROUTES))
|
||||
if ((old_src != new_src) && (tab->debug & D_ROUTES))
|
||||
if (ipa_zero(he->link) || ipa_equal(he->link, he->addr))
|
||||
log(L_TRACE "%s: Hostentry %p for %I in %s resolved via %N (%uG)",
|
||||
tab->name, he, he->addr, he->tab->name, e->rte.net, e->rte.src->global_id);
|
||||
@ -4477,6 +4478,7 @@ rt_update_hostentry(struct rtable_private *tab, struct hostentry *he)
|
||||
|
||||
done:
|
||||
/* Signalize work done and wait for readers */
|
||||
ASSERT_DIE(atomic_exchange_explicit(&he->src, new_src, memory_order_acq_rel) == NULL);
|
||||
ASSERT_DIE((atomic_fetch_add_explicit(&he->version, 1, memory_order_acq_rel) & 1) == 1);
|
||||
synchronize_rcu();
|
||||
|
||||
@ -4484,7 +4486,7 @@ done:
|
||||
trie_add_prefix(tab->hostcache->trie, &he_addr, pxlen, he_addr.pxlen);
|
||||
|
||||
ea_free(old_src);
|
||||
return old_src != he->src;
|
||||
return old_src != new_src;
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user