mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 07:31:54 +00:00
Using ea_lookup_tmp() for temporarily keeping attribute references
To avoid needs for keeping local temporary references for attributes, now one can use ea_lookup_tmp() to ensure that the attributes are valid and stored until the task ends. After that, the attributes are automatically unref'd and also deallocated if needed.
This commit is contained in:
parent
29cd2c0170
commit
091130e84b
23
lib/route.h
23
lib/route.h
@ -557,6 +557,29 @@ static inline ea_list *ea_lookup(ea_list *r, u32 squash_upto, enum ea_stored oid
|
|||||||
return ea_lookup_slow(r, squash_upto, oid);
|
return ea_lookup_slow(r, squash_upto, oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ea_free_deferred {
|
||||||
|
struct deferred_call dc;
|
||||||
|
ea_list *attrs;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ea_free_deferred(struct deferred_call *dc);
|
||||||
|
|
||||||
|
static inline ea_list *ea_free_later(ea_list *r)
|
||||||
|
{
|
||||||
|
struct ea_free_deferred efd = {
|
||||||
|
.dc.hook = ea_free_deferred,
|
||||||
|
.attrs = r,
|
||||||
|
};
|
||||||
|
|
||||||
|
defer_call(&efd.dc, sizeof efd);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ea_list *ea_lookup_tmp(ea_list *r, u32 squash_upto, enum ea_stored oid)
|
||||||
|
{
|
||||||
|
return ea_free_later(ea_lookup(r, squash_upto, oid));
|
||||||
|
}
|
||||||
|
|
||||||
static inline ea_list *ea_strip_to(ea_list *r, u32 strip_to)
|
static inline ea_list *ea_strip_to(ea_list *r, u32 strip_to)
|
||||||
{
|
{
|
||||||
ASSERT_DIE(strip_to);
|
ASSERT_DIE(strip_to);
|
||||||
|
@ -1770,6 +1770,12 @@ ea__free(struct ea_storage *a)
|
|||||||
RTA_UNLOCK;
|
RTA_UNLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ea_free_deferred(struct deferred_call *dc)
|
||||||
|
{
|
||||||
|
ea_free(SKIP_BACK(struct ea_free_deferred, dc, dc)->attrs);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rta_dump_all - dump attribute cache
|
* rta_dump_all - dump attribute cache
|
||||||
*
|
*
|
||||||
|
@ -1861,11 +1861,9 @@ rte_update(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
|||||||
|
|
||||||
ASSERT(c->channel_state == CS_UP);
|
ASSERT(c->channel_state == CS_UP);
|
||||||
|
|
||||||
ea_list *ea_prefilter = NULL, *ea_postfilter = NULL;
|
|
||||||
|
|
||||||
/* Storing prefilter routes as an explicit layer */
|
/* Storing prefilter routes as an explicit layer */
|
||||||
if (new && (c->in_keep & RIK_PREFILTER))
|
if (new && (c->in_keep & RIK_PREFILTER))
|
||||||
ea_prefilter = new->attrs = ea_lookup(new->attrs, 0, EALS_PREIMPORT);
|
new->attrs = ea_lookup_tmp(new->attrs, 0, EALS_PREIMPORT);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
debug("%s.%s -(prefilter)-> %s: %N ", c->proto->name, c->name, c->table->name, n);
|
debug("%s.%s -(prefilter)-> %s: %N ", c->proto->name, c->name, c->table->name, n);
|
||||||
@ -1908,8 +1906,8 @@ rte_update(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
|||||||
|
|
||||||
if (new)
|
if (new)
|
||||||
{
|
{
|
||||||
ea_postfilter = new->attrs = ea_lookup(new->attrs,
|
new->attrs = ea_lookup_tmp(new->attrs,
|
||||||
ea_prefilter ? BIT32_ALL(EALS_PREIMPORT) : 0, EALS_FILTERED);
|
(c->in_keep & RIK_PREFILTER) ? BIT32_ALL(EALS_PREIMPORT) : 0, EALS_FILTERED);
|
||||||
|
|
||||||
if (net_is_flow(n))
|
if (net_is_flow(n))
|
||||||
rt_flowspec_resolve_rte(new, c);
|
rt_flowspec_resolve_rte(new, c);
|
||||||
@ -1934,11 +1932,6 @@ rte_update(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
|||||||
mpls_unlock_fec(fec);
|
mpls_unlock_fec(fec);
|
||||||
DBGL( "Unlock FEC %p (rte_update %N)", fec, n);
|
DBGL( "Unlock FEC %p (rte_update %N)", fec, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now the route attributes are kept by the in-table cached version
|
|
||||||
* and we may drop the local handles */
|
|
||||||
ea_free(ea_prefilter);
|
|
||||||
ea_free(ea_postfilter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -519,7 +519,6 @@ struct bgp_parse_state {
|
|||||||
/* Cached state for bgp_rte_update() */
|
/* Cached state for bgp_rte_update() */
|
||||||
u32 last_id;
|
u32 last_id;
|
||||||
struct rte_src *last_src;
|
struct rte_src *last_src;
|
||||||
ea_list *cached_ea;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BGP_PORT 179
|
#define BGP_PORT 179
|
||||||
|
@ -1533,10 +1533,6 @@ bgp_rte_update(struct bgp_parse_state *s, const net_addr *n, u32 path_id, ea_lis
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare cached route attributes */
|
|
||||||
if (!s->mpls && (s->cached_ea == NULL))
|
|
||||||
a0 = s->cached_ea = ea_lookup(a0, 0, EALS_CUSTOM);
|
|
||||||
|
|
||||||
rte e0 = {
|
rte e0 = {
|
||||||
.attrs = a0,
|
.attrs = a0,
|
||||||
.src = s->last_src,
|
.src = s->last_src,
|
||||||
@ -1593,10 +1589,6 @@ bgp_decode_mpls_labels(struct bgp_parse_state *s, byte **pos, uint *len, uint *p
|
|||||||
/* Update next hop entry in rta */
|
/* Update next hop entry in rta */
|
||||||
bgp_apply_mpls_labels(s, to, lnum, labels);
|
bgp_apply_mpls_labels(s, to, lnum, labels);
|
||||||
|
|
||||||
/* Attributes were changed, invalidate cached entry */
|
|
||||||
ea_free(s->cached_ea);
|
|
||||||
s->cached_ea = NULL;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1642,6 +1634,7 @@ bgp_decode_nlri_ip4(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a)
|
|||||||
{
|
{
|
||||||
while (len)
|
while (len)
|
||||||
{
|
{
|
||||||
|
ea_list *ea = a;
|
||||||
net_addr_ip4 net;
|
net_addr_ip4 net;
|
||||||
u32 path_id = 0;
|
u32 path_id = 0;
|
||||||
|
|
||||||
@ -1664,7 +1657,7 @@ bgp_decode_nlri_ip4(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a)
|
|||||||
|
|
||||||
/* Decode MPLS labels */
|
/* Decode MPLS labels */
|
||||||
if (s->mpls)
|
if (s->mpls)
|
||||||
bgp_decode_mpls_labels(s, &pos, &len, &l, &a);
|
bgp_decode_mpls_labels(s, &pos, &len, &l, &ea);
|
||||||
|
|
||||||
if (l > IP4_MAX_PREFIX_LENGTH)
|
if (l > IP4_MAX_PREFIX_LENGTH)
|
||||||
bgp_parse_error(s, 10);
|
bgp_parse_error(s, 10);
|
||||||
@ -1680,7 +1673,7 @@ bgp_decode_nlri_ip4(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a)
|
|||||||
|
|
||||||
// XXXX validate prefix
|
// XXXX validate prefix
|
||||||
|
|
||||||
bgp_rte_update(s, (net_addr *) &net, path_id, a);
|
bgp_rte_update(s, (net_addr *) &net, path_id, ea);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1727,6 +1720,7 @@ bgp_decode_nlri_ip6(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a)
|
|||||||
{
|
{
|
||||||
while (len)
|
while (len)
|
||||||
{
|
{
|
||||||
|
ea_list *ea = a;
|
||||||
net_addr_ip6 net;
|
net_addr_ip6 net;
|
||||||
u32 path_id = 0;
|
u32 path_id = 0;
|
||||||
|
|
||||||
@ -1749,7 +1743,7 @@ bgp_decode_nlri_ip6(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a)
|
|||||||
|
|
||||||
/* Decode MPLS labels */
|
/* Decode MPLS labels */
|
||||||
if (s->mpls)
|
if (s->mpls)
|
||||||
bgp_decode_mpls_labels(s, &pos, &len, &l, &a);
|
bgp_decode_mpls_labels(s, &pos, &len, &l, &ea);
|
||||||
|
|
||||||
if (l > IP6_MAX_PREFIX_LENGTH)
|
if (l > IP6_MAX_PREFIX_LENGTH)
|
||||||
bgp_parse_error(s, 10);
|
bgp_parse_error(s, 10);
|
||||||
@ -1765,7 +1759,7 @@ bgp_decode_nlri_ip6(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a)
|
|||||||
|
|
||||||
// XXXX validate prefix
|
// XXXX validate prefix
|
||||||
|
|
||||||
bgp_rte_update(s, (net_addr *) &net, path_id, a);
|
bgp_rte_update(s, (net_addr *) &net, path_id, ea);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1815,6 +1809,7 @@ bgp_decode_nlri_vpn4(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a)
|
|||||||
{
|
{
|
||||||
while (len)
|
while (len)
|
||||||
{
|
{
|
||||||
|
ea_list *ea = a;
|
||||||
net_addr_vpn4 net;
|
net_addr_vpn4 net;
|
||||||
u32 path_id = 0;
|
u32 path_id = 0;
|
||||||
|
|
||||||
@ -1837,7 +1832,7 @@ bgp_decode_nlri_vpn4(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a)
|
|||||||
|
|
||||||
/* Decode MPLS labels */
|
/* Decode MPLS labels */
|
||||||
if (s->mpls)
|
if (s->mpls)
|
||||||
bgp_decode_mpls_labels(s, &pos, &len, &l, &a);
|
bgp_decode_mpls_labels(s, &pos, &len, &l, &ea);
|
||||||
|
|
||||||
/* Decode route distinguisher */
|
/* Decode route distinguisher */
|
||||||
if (l < 64)
|
if (l < 64)
|
||||||
@ -1861,7 +1856,7 @@ bgp_decode_nlri_vpn4(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a)
|
|||||||
|
|
||||||
// XXXX validate prefix
|
// XXXX validate prefix
|
||||||
|
|
||||||
bgp_rte_update(s, (net_addr *) &net, path_id, a);
|
bgp_rte_update(s, (net_addr *) &net, path_id, ea);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1912,6 +1907,7 @@ bgp_decode_nlri_vpn6(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a)
|
|||||||
{
|
{
|
||||||
while (len)
|
while (len)
|
||||||
{
|
{
|
||||||
|
ea_list *ea = a;
|
||||||
net_addr_vpn6 net;
|
net_addr_vpn6 net;
|
||||||
u32 path_id = 0;
|
u32 path_id = 0;
|
||||||
|
|
||||||
@ -1934,7 +1930,7 @@ bgp_decode_nlri_vpn6(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a)
|
|||||||
|
|
||||||
/* Decode MPLS labels */
|
/* Decode MPLS labels */
|
||||||
if (s->mpls)
|
if (s->mpls)
|
||||||
bgp_decode_mpls_labels(s, &pos, &len, &l, &a);
|
bgp_decode_mpls_labels(s, &pos, &len, &l, &ea);
|
||||||
|
|
||||||
/* Decode route distinguisher */
|
/* Decode route distinguisher */
|
||||||
if (l < 64)
|
if (l < 64)
|
||||||
@ -1958,7 +1954,7 @@ bgp_decode_nlri_vpn6(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a)
|
|||||||
|
|
||||||
// XXXX validate prefix
|
// XXXX validate prefix
|
||||||
|
|
||||||
bgp_rte_update(s, (net_addr *) &net, path_id, a);
|
bgp_rte_update(s, (net_addr *) &net, path_id, ea);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2707,13 +2703,13 @@ bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_lis
|
|||||||
/* Handle withdraw during next hop decoding */
|
/* Handle withdraw during next hop decoding */
|
||||||
if (s->err_withdraw)
|
if (s->err_withdraw)
|
||||||
ea = NULL;
|
ea = NULL;
|
||||||
|
|
||||||
|
if (ea)
|
||||||
|
ea = ea_lookup_tmp(ea, 0, EALS_CUSTOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
c->desc->decode_nlri(s, nlri, len, ea);
|
c->desc->decode_nlri(s, nlri, len, ea);
|
||||||
|
|
||||||
ea_free(s->cached_ea);
|
|
||||||
s->cached_ea = NULL;
|
|
||||||
|
|
||||||
rt_unlock_source(s->last_src);
|
rt_unlock_source(s->last_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2820,7 +2816,6 @@ bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len)
|
|||||||
ea, s.mp_next_hop_data, s.mp_next_hop_len);
|
ea, s.mp_next_hop_data, s.mp_next_hop_len);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
ea_free(s.cached_ea);
|
|
||||||
lp_restore(tmp_linpool, tmpp);
|
lp_restore(tmp_linpool, tmpp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user