static void bgp_free_prefix(struct bgp_ptx_private *c, struct bgp_prefix *px);
static inline int
-bgp_update_prefix(struct bgp_ptx_private *c, struct bgp_prefix *px, struct bgp_bucket *b)
+bgp_update_prefix(struct bgp_ptx_private *c, struct bgp_prefix *px, struct bgp_bucket *b, list *px_free_later)
{
#define IS_WITHDRAW_BUCKET(b) ((b) == c->withdraw_bucket)
#define BPX_TRACE(what) do { \
/* Well, we haven't sent anything yet */
if (!px->last)
- bgp_free_prefix(c, px);
+ if (px_free_later)
+ /* We may not be allowed to free the prefix directly */
+ add_tail(px_free_later, &px->buck_node);
+ else
+ bgp_free_prefix(c, px);
px->cur = NULL;
return 0;
ASSERT_DIE(bc->tx_keep);
+ list px_free_later; init_list(&px_free_later);
HASH_WALK(c->prefix_hash, next, px)
{
if (!px->cur)
px->last = NULL;
/* And send it once again */
- seen += bgp_update_prefix(c, px, last);
+ seen += bgp_update_prefix(c, px, last, &px_free_later);
}
}
HASH_WALK_END;
log(L_TRACE "%s.%s: TX resending %u routes",
bc->c.proto->name, bc->c.name, seen);
+ /* Flush withdrawals */
+ struct bgp_prefix *px;
+ WALK_LIST_FIRST(px, px_free_later)
+ {
+ rem_node(&px->buck_node);
+ bgp_free_prefix(c, px);
+ }
}
if (p->enhanced_refresh)
/* Move all prefixes to the withdraw bucket to unref the "last" prefixes */
struct bgp_bucket *b = bgp_get_withdraw_bucket(c);
+ list px_free_later; init_list(&px_free_later);
HASH_WALK(c->prefix_hash, next, px)
- bgp_update_prefix(c, px, b);
+ bgp_update_prefix(c, px, b, &px_free_later);
HASH_WALK_END;
/* Flush withdrawals */
struct bgp_prefix *px;
+ WALK_LIST_FIRST(px, px_free_later)
+ {
+ rem_node(&px->buck_node);
+ bgp_free_prefix(c, px);
+ }
+
WALK_LIST_FIRST(px, b->prefixes)
bgp_done_prefix(c, px, b);
path = (new ?: old)->src;
/* And queue the notification */
- if (bgp_update_prefix(c, bgp_get_prefix(c, NET_TO_INDEX(n), path, bc->add_path_tx), buck))
+ if (bgp_update_prefix(c, bgp_get_prefix(c, NET_TO_INDEX(n), path, bc->add_path_tx), buck, NULL))
bgp_schedule_packet(p->conn, bc, PKT_UPDATE);
if ((p->cf->tx_size_warning > 0) )