0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-09 20:58:44 +00:00

BGP/BMP: Moved temporary allocation checks to the freeing functions

This commit is contained in:
Maria Matejka 2023-10-11 22:23:34 +02:00
parent 2ed9b2d769
commit b20b6a9ad2
3 changed files with 30 additions and 41 deletions

View File

@ -1631,6 +1631,9 @@ bgp_defer_bucket(struct bgp_channel *c, struct bgp_bucket *b)
void
bgp_withdraw_bucket(struct bgp_channel *c, struct bgp_bucket *b)
{
if (b->bmp)
return;
struct bgp_proto *p = (void *) c->c.proto;
struct bgp_bucket *wb = bgp_get_withdraw_bucket(c);
@ -1710,6 +1713,14 @@ bgp_get_prefix(struct bgp_channel *c, net_addr *net, u32 path_id)
void
bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *px)
{
/* BMP hack */
if (
!NODE_VALID(px->buck_node.prev) &&
!NODE_VALID(px->buck_node.next) &&
!SKIP_BACK(struct bgp_bucket, prefixes.head, px->buck_node.prev)->bmp
)
return;
rem_node(&px->buck_node);
HASH_REMOVE2(c->prefix_hash, PXH, c->pool, px);

View File

@ -413,6 +413,7 @@ struct bgp_bucket {
struct bgp_bucket *next; /* Node in bucket hash table */
list prefixes; /* Prefixes in this bucket (struct bgp_prefix) */
u32 hash; /* Hash over extended attributes */
u32 bmp:1; /* Temporary bucket for BMP encoding */
ea_list eattrs[0]; /* Per-bucket extended attributes */
};
@ -439,7 +440,6 @@ struct bgp_write_state {
int as4_session;
int add_path;
int mpls;
int sham;
eattr *mp_next_hop;
const adata *mpls_labels;

View File

@ -1575,10 +1575,7 @@ bgp_encode_nlri_ip4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu
memcpy(pos, &a, b);
ADVANCE(pos, size, b);
if (!s->sham)
bgp_free_prefix(s->channel, px);
else
rem_node(&px->buck_node);
bgp_free_prefix(s->channel, px);
}
return pos - buf;
@ -1663,10 +1660,7 @@ bgp_encode_nlri_ip6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu
memcpy(pos, &a, b);
ADVANCE(pos, size, b);
if (!s->sham)
bgp_free_prefix(s->channel, px);
else
rem_node(&px->buck_node);
bgp_free_prefix(s->channel, px);
}
return pos - buf;
@ -1754,10 +1748,7 @@ bgp_encode_nlri_vpn4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *b
memcpy(pos, &a, b);
ADVANCE(pos, size, b);
if (!s->sham)
bgp_free_prefix(s->channel, px);
else
rem_node(&px->buck_node);
bgp_free_prefix(s->channel, px);
}
return pos - buf;
@ -1854,10 +1845,7 @@ bgp_encode_nlri_vpn6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *b
memcpy(pos, &a, b);
ADVANCE(pos, size, b);
if (!s->sham)
bgp_free_prefix(s->channel, px);
else
rem_node(&px->buck_node);
bgp_free_prefix(s->channel, px);
}
return pos - buf;
@ -1944,10 +1932,7 @@ bgp_encode_nlri_flow4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *
memcpy(pos, net->data, flen);
ADVANCE(pos, size, flen);
if (!s->sham)
bgp_free_prefix(s->channel, px);
else
rem_node(&px->buck_node);
bgp_free_prefix(s->channel, px);
}
return pos - buf;
@ -2039,10 +2024,7 @@ bgp_encode_nlri_flow6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *
memcpy(pos, net->data, flen);
ADVANCE(pos, size, flen);
if (!s->sham)
bgp_free_prefix(s->channel, px);
else
rem_node(&px->buck_node);
bgp_free_prefix(s->channel, px);
}
return pos - buf;
@ -2286,8 +2268,7 @@ bgp_create_ip_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu
if (la < 0)
{
/* Attribute list too long */
if (!s->sham)
bgp_withdraw_bucket(s->channel, buck);
bgp_withdraw_bucket(s->channel, buck);
return NULL;
}
@ -2334,8 +2315,7 @@ bgp_create_mp_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu
if (la < 0)
{
/* Attribute list too long */
if (!s->sham)
bgp_withdraw_bucket(s->channel, buck);
bgp_withdraw_bucket(s->channel, buck);
return NULL;
}
@ -2427,9 +2407,6 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck,
byte *res = NULL;
/* FIXME: must be a bit shorter */
struct lp_state tmpp;
lp_save(tmp_linpool, &tmpp);
struct bgp_caps *peer = p->conn->remote_caps;
const struct bgp_af_caps *rem = bgp_find_af_caps(peer, c->afi);
@ -2441,7 +2418,6 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck,
.as4_session = 1,
.add_path = c->add_path_rx,
.mpls = c->desc->mpls,
.sham = 1,
};
if (!update)
@ -2457,8 +2433,6 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck,
bgp_create_mp_reach(&s, buck, buf, end);
}
lp_restore(tmp_linpool, &tmpp);
return res;
}
@ -2484,17 +2458,19 @@ bgp_bmp_encode_rte(struct bgp_channel *c, byte *buf, const net_addr *n,
uint bucket_size = sizeof(struct bgp_bucket) + ea_size;
uint prefix_size = sizeof(struct bgp_prefix) + n->length;
/* Sham bucket */
struct bgp_bucket *b = alloca(bucket_size);
*b = (struct bgp_bucket) { };
struct lp_state tmpp;
lp_save(tmp_linpool, &tmpp);
/* Temporary bucket */
struct bgp_bucket *b = tmp_allocz(bucket_size);
b->bmp = 1;
init_list(&b->prefixes);
if (attrs)
memcpy(b->eattrs, attrs, ea_size);
/* Sham prefix */
struct bgp_prefix *px = alloca(prefix_size);
*px = (struct bgp_prefix) { };
/* Temporary prefix */
struct bgp_prefix *px = tmp_allocz(prefix_size);
px->path_id = src->private_id;
net_copy(px->net, n);
add_tail(&b->prefixes, &px->buck_node);
@ -2504,6 +2480,8 @@ bgp_bmp_encode_rte(struct bgp_channel *c, byte *buf, const net_addr *n,
if (end)
bgp_bmp_prepare_bgp_hdr(buf, end - buf, PKT_UPDATE);
lp_restore(tmp_linpool, &tmpp);
return end;
}