(v).data = mb_allocz(pool, HASH_SIZE(v) * sizeof(* (v).data)); \
})
+#define HASH_FREE(v) \
+ ({ \
+ mb_free((v).data); \
+ (v) = (typeof(v)){ }; \
+ })
+
#define HASH_FIND(v,id,key...) \
({ \
u32 _h = HASH_FN(v, id, key); \
p->prefix_slab = sl_new(p->p.pool, sizeof(struct bgp_prefix));
}
+void
+bgp_free_prefix_table(struct bgp_proto *p)
+{
+ HASH_FREE(p->prefix_hash);
+
+ rfree(p->prefix_slab);
+ p->prefix_slab = NULL;
+}
+
static struct bgp_prefix *
bgp_get_prefix(struct bgp_proto *p, ip_addr prefix, int pxlen, u32 path_id)
{
// fib_init(&p->prefix_fib, p->p.pool, sizeof(struct bgp_prefix), 0, bgp_init_prefix);
}
+void
+bgp_free_bucket_table(struct bgp_proto *p)
+{
+ mb_free(p->bucket_hash);
+ p->bucket_hash = NULL;
+
+ struct bgp_bucket *b;
+ WALK_LIST_FIRST(b, p->bucket_queue)
+ {
+ rem_node(&b->send_node);
+ mb_free(b);
+ }
+
+ mb_free(p->withdraw_bucket);
+ p->withdraw_bucket = NULL;
+}
+
void
bgp_get_route_info(rte *e, byte *buf, ea_list *attrs)
{
BGP_TRACE(D_EVENTS, "BGP session closed");
p->conn = NULL;
+ bgp_free_prefix_table(p);
+ bgp_free_bucket_table(p);
+
if (p->p.proto_state == PS_UP)
bgp_stop(p, 0);
}
void bgp_rt_notify(struct proto *P, rtable *tbl UNUSED, net *n, rte *new, rte *old UNUSED, ea_list *attrs);
int bgp_import_control(struct proto *, struct rte **, struct ea_list **, struct linpool *);
void bgp_init_bucket_table(struct bgp_proto *);
+void bgp_free_bucket_table(struct bgp_proto *p);
void bgp_free_bucket(struct bgp_proto *p, struct bgp_bucket *buck);
void bgp_init_prefix_table(struct bgp_proto *p, u32 order);
+void bgp_free_prefix_table(struct bgp_proto *p);
void bgp_free_prefix(struct bgp_proto *p, struct bgp_prefix *bp);
uint bgp_encode_attrs(struct bgp_proto *p, byte *w, ea_list *attrs, int remains);
void bgp_get_route_info(struct rte *, byte *buf, struct ea_list *attrs);