mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 21:47:15 +02:00
zebra: Track tables allocated by vrf and cleanup
For each table created by a vrf, keep track of it and allow for proper cleanup on shutdown of that particular table. Cleanup client shutdown to only cleanup data that the particular vrf owns. Before we were cleaning the same table 2 times. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
8ab39b7f1c
commit
d8612e6545
|
@ -3227,18 +3227,23 @@ unsigned long rib_score_proto(uint8_t proto, unsigned short instance)
|
||||||
{
|
{
|
||||||
struct vrf *vrf;
|
struct vrf *vrf;
|
||||||
struct zebra_vrf *zvrf;
|
struct zebra_vrf *zvrf;
|
||||||
|
struct other_route_table *ort;
|
||||||
unsigned long cnt = 0;
|
unsigned long cnt = 0;
|
||||||
|
|
||||||
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
|
||||||
if ((zvrf = vrf->info) != NULL)
|
zvrf = vrf->info;
|
||||||
cnt += rib_score_proto_table(
|
if (!zvrf)
|
||||||
proto, instance,
|
continue;
|
||||||
|
|
||||||
|
cnt += rib_score_proto_table(proto, instance,
|
||||||
zvrf->table[AFI_IP][SAFI_UNICAST])
|
zvrf->table[AFI_IP][SAFI_UNICAST])
|
||||||
+ rib_score_proto_table(
|
+ rib_score_proto_table(
|
||||||
proto, instance,
|
proto, instance,
|
||||||
zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||||
|
|
||||||
cnt += zebra_router_score_proto(proto, instance);
|
for_each(otable, &zvrf->other_tables, ort) cnt +=
|
||||||
|
rib_score_proto_table(proto, instance, ort->table);
|
||||||
|
}
|
||||||
|
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,8 @@ static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi,
|
||||||
static void zebra_rnhtable_node_cleanup(struct route_table *table,
|
static void zebra_rnhtable_node_cleanup(struct route_table *table,
|
||||||
struct route_node *node);
|
struct route_node *node);
|
||||||
|
|
||||||
|
DEFINE_MTYPE_STATIC(ZEBRA, OTHER_TABLE, "Other Table");
|
||||||
|
|
||||||
/* VRF information update. */
|
/* VRF information update. */
|
||||||
static void zebra_vrf_add_update(struct zebra_vrf *zvrf)
|
static void zebra_vrf_add_update(struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
|
@ -93,6 +95,9 @@ static int zebra_vrf_new(struct vrf *vrf)
|
||||||
zvrf = zebra_vrf_alloc();
|
zvrf = zebra_vrf_alloc();
|
||||||
vrf->info = zvrf;
|
vrf->info = zvrf;
|
||||||
zvrf->vrf = vrf;
|
zvrf->vrf = vrf;
|
||||||
|
|
||||||
|
otable_init(&zvrf->other_tables);
|
||||||
|
|
||||||
router_id_init(zvrf);
|
router_id_init(zvrf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -226,6 +231,7 @@ static int zebra_vrf_disable(struct vrf *vrf)
|
||||||
static int zebra_vrf_delete(struct vrf *vrf)
|
static int zebra_vrf_delete(struct vrf *vrf)
|
||||||
{
|
{
|
||||||
struct zebra_vrf *zvrf = vrf->info;
|
struct zebra_vrf *zvrf = vrf->info;
|
||||||
|
struct other_route_table *otable;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
|
@ -274,11 +280,22 @@ static int zebra_vrf_delete(struct vrf *vrf)
|
||||||
route_table_finish(zvrf->import_check_table[afi]);
|
route_table_finish(zvrf->import_check_table[afi]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
otable = otable_pop(&zvrf->other_tables);
|
||||||
|
while (otable) {
|
||||||
|
zebra_router_release_table(zvrf, otable->table_id,
|
||||||
|
otable->afi, otable->safi);
|
||||||
|
XFREE(MTYPE_OTHER_TABLE, otable);
|
||||||
|
|
||||||
|
otable = otable_pop(&zvrf->other_tables);
|
||||||
|
}
|
||||||
|
|
||||||
/* Cleanup EVPN states for vrf */
|
/* Cleanup EVPN states for vrf */
|
||||||
zebra_vxlan_vrf_delete(zvrf);
|
zebra_vxlan_vrf_delete(zvrf);
|
||||||
|
|
||||||
list_delete_all_node(zvrf->rid_all_sorted_list);
|
list_delete_all_node(zvrf->rid_all_sorted_list);
|
||||||
list_delete_all_node(zvrf->rid_lo_sorted_list);
|
list_delete_all_node(zvrf->rid_lo_sorted_list);
|
||||||
|
|
||||||
|
otable_fini(&zvrf->other_tables);
|
||||||
XFREE(MTYPE_ZEBRA_VRF, zvrf);
|
XFREE(MTYPE_ZEBRA_VRF, zvrf);
|
||||||
vrf->info = NULL;
|
vrf->info = NULL;
|
||||||
|
|
||||||
|
@ -321,6 +338,8 @@ struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
|
||||||
uint32_t table_id)
|
uint32_t table_id)
|
||||||
{
|
{
|
||||||
struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id);
|
struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id);
|
||||||
|
struct other_route_table ort, *otable;
|
||||||
|
struct route_table *table;
|
||||||
|
|
||||||
if (!zvrf)
|
if (!zvrf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -331,7 +350,23 @@ struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
|
||||||
if (table_id == zvrf->table_id)
|
if (table_id == zvrf->table_id)
|
||||||
return zebra_vrf_table(afi, safi, vrf_id);
|
return zebra_vrf_table(afi, safi, vrf_id);
|
||||||
|
|
||||||
return zebra_router_get_table(zvrf, table_id, afi, safi);
|
ort.afi = afi;
|
||||||
|
ort.safi = safi;
|
||||||
|
ort.table_id = table_id;
|
||||||
|
otable = otable_find(&zvrf->other_tables, &ort);
|
||||||
|
if (otable)
|
||||||
|
return otable->table;
|
||||||
|
|
||||||
|
table = zebra_router_get_table(zvrf, table_id, afi, safi);
|
||||||
|
|
||||||
|
otable = XCALLOC(MTYPE_OTHER_TABLE, sizeof(*otable));
|
||||||
|
otable->afi = afi;
|
||||||
|
otable->safi = safi;
|
||||||
|
otable->table_id = table_id;
|
||||||
|
otable->table = table;
|
||||||
|
otable_add(&zvrf->other_tables, otable);
|
||||||
|
|
||||||
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zebra_rtable_node_cleanup(struct route_table *table,
|
void zebra_rtable_node_cleanup(struct route_table *table,
|
||||||
|
|
|
@ -43,6 +43,18 @@ struct zebra_rmap {
|
||||||
struct route_map *map;
|
struct route_map *map;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PREDECL_RBTREE_UNIQ(otable);
|
||||||
|
|
||||||
|
struct other_route_table {
|
||||||
|
struct otable_item next;
|
||||||
|
|
||||||
|
afi_t afi;
|
||||||
|
safi_t safi;
|
||||||
|
uint32_t table_id;
|
||||||
|
|
||||||
|
struct route_table *table;
|
||||||
|
};
|
||||||
|
|
||||||
/* Routing table instance. */
|
/* Routing table instance. */
|
||||||
struct zebra_vrf {
|
struct zebra_vrf {
|
||||||
/* Back pointer */
|
/* Back pointer */
|
||||||
|
@ -69,6 +81,8 @@ struct zebra_vrf {
|
||||||
/* Import check table (used mostly by BGP */
|
/* Import check table (used mostly by BGP */
|
||||||
struct route_table *import_check_table[AFI_MAX];
|
struct route_table *import_check_table[AFI_MAX];
|
||||||
|
|
||||||
|
struct otable_head other_tables;
|
||||||
|
|
||||||
/* 2nd pointer type used primarily to quell a warning on
|
/* 2nd pointer type used primarily to quell a warning on
|
||||||
* ALL_LIST_ELEMENTS_RO
|
* ALL_LIST_ELEMENTS_RO
|
||||||
*/
|
*/
|
||||||
|
@ -192,6 +206,25 @@ static inline bool zvrf_is_active(struct zebra_vrf *zvrf)
|
||||||
return zvrf->vrf->status & VRF_ACTIVE;
|
return zvrf->vrf->status & VRF_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
zvrf_other_table_compare_func(const struct other_route_table *a,
|
||||||
|
const struct other_route_table *b)
|
||||||
|
{
|
||||||
|
if (a->afi != b->afi)
|
||||||
|
return a->afi - b->afi;
|
||||||
|
|
||||||
|
if (a->safi != b->safi)
|
||||||
|
return a->safi - b->safi;
|
||||||
|
|
||||||
|
if (a->table_id != b->table_id)
|
||||||
|
return a->table_id - b->table_id;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_RBTREE_UNIQ(otable, struct other_route_table, next,
|
||||||
|
zvrf_other_table_compare_func)
|
||||||
|
|
||||||
struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
|
struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
|
||||||
vrf_id_t vrf_id,
|
vrf_id_t vrf_id,
|
||||||
uint32_t table_id);
|
uint32_t table_id);
|
||||||
|
|
Loading…
Reference in a new issue