Skip to content

Commit d8612e6

Browse files
committed
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 <[email protected]>
1 parent 8ab39b7 commit d8612e6

File tree

3 files changed

+83
-10
lines changed

3 files changed

+83
-10
lines changed

zebra/zebra_rib.c

+14-9
Original file line numberDiff line numberDiff line change
@@ -3227,18 +3227,23 @@ unsigned long rib_score_proto(uint8_t proto, unsigned short instance)
32273227
{
32283228
struct vrf *vrf;
32293229
struct zebra_vrf *zvrf;
3230+
struct other_route_table *ort;
32303231
unsigned long cnt = 0;
32313232

3232-
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
3233-
if ((zvrf = vrf->info) != NULL)
3234-
cnt += rib_score_proto_table(
3235-
proto, instance,
3236-
zvrf->table[AFI_IP][SAFI_UNICAST])
3237-
+ rib_score_proto_table(
3238-
proto, instance,
3239-
zvrf->table[AFI_IP6][SAFI_UNICAST]);
3233+
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
3234+
zvrf = vrf->info;
3235+
if (!zvrf)
3236+
continue;
32403237

3241-
cnt += zebra_router_score_proto(proto, instance);
3238+
cnt += rib_score_proto_table(proto, instance,
3239+
zvrf->table[AFI_IP][SAFI_UNICAST])
3240+
+ rib_score_proto_table(
3241+
proto, instance,
3242+
zvrf->table[AFI_IP6][SAFI_UNICAST]);
3243+
3244+
for_each(otable, &zvrf->other_tables, ort) cnt +=
3245+
rib_score_proto_table(proto, instance, ort->table);
3246+
}
32423247

32433248
return cnt;
32443249
}

zebra/zebra_vrf.c

+36-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi,
4747
static void zebra_rnhtable_node_cleanup(struct route_table *table,
4848
struct route_node *node);
4949

50+
DEFINE_MTYPE_STATIC(ZEBRA, OTHER_TABLE, "Other Table");
51+
5052
/* VRF information update. */
5153
static void zebra_vrf_add_update(struct zebra_vrf *zvrf)
5254
{
@@ -93,6 +95,9 @@ static int zebra_vrf_new(struct vrf *vrf)
9395
zvrf = zebra_vrf_alloc();
9496
vrf->info = zvrf;
9597
zvrf->vrf = vrf;
98+
99+
otable_init(&zvrf->other_tables);
100+
96101
router_id_init(zvrf);
97102
return 0;
98103
}
@@ -226,6 +231,7 @@ static int zebra_vrf_disable(struct vrf *vrf)
226231
static int zebra_vrf_delete(struct vrf *vrf)
227232
{
228233
struct zebra_vrf *zvrf = vrf->info;
234+
struct other_route_table *otable;
229235
struct route_table *table;
230236
afi_t afi;
231237
safi_t safi;
@@ -274,11 +280,22 @@ static int zebra_vrf_delete(struct vrf *vrf)
274280
route_table_finish(zvrf->import_check_table[afi]);
275281
}
276282

283+
otable = otable_pop(&zvrf->other_tables);
284+
while (otable) {
285+
zebra_router_release_table(zvrf, otable->table_id,
286+
otable->afi, otable->safi);
287+
XFREE(MTYPE_OTHER_TABLE, otable);
288+
289+
otable = otable_pop(&zvrf->other_tables);
290+
}
291+
277292
/* Cleanup EVPN states for vrf */
278293
zebra_vxlan_vrf_delete(zvrf);
279294

280295
list_delete_all_node(zvrf->rid_all_sorted_list);
281296
list_delete_all_node(zvrf->rid_lo_sorted_list);
297+
298+
otable_fini(&zvrf->other_tables);
282299
XFREE(MTYPE_ZEBRA_VRF, zvrf);
283300
vrf->info = NULL;
284301

@@ -321,6 +338,8 @@ struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
321338
uint32_t table_id)
322339
{
323340
struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id);
341+
struct other_route_table ort, *otable;
342+
struct route_table *table;
324343

325344
if (!zvrf)
326345
return NULL;
@@ -331,7 +350,23 @@ struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
331350
if (table_id == zvrf->table_id)
332351
return zebra_vrf_table(afi, safi, vrf_id);
333352

334-
return zebra_router_get_table(zvrf, table_id, afi, safi);
353+
ort.afi = afi;
354+
ort.safi = safi;
355+
ort.table_id = table_id;
356+
otable = otable_find(&zvrf->other_tables, &ort);
357+
if (otable)
358+
return otable->table;
359+
360+
table = zebra_router_get_table(zvrf, table_id, afi, safi);
361+
362+
otable = XCALLOC(MTYPE_OTHER_TABLE, sizeof(*otable));
363+
otable->afi = afi;
364+
otable->safi = safi;
365+
otable->table_id = table_id;
366+
otable->table = table;
367+
otable_add(&zvrf->other_tables, otable);
368+
369+
return table;
335370
}
336371

337372
void zebra_rtable_node_cleanup(struct route_table *table,

zebra/zebra_vrf.h

+33
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ struct zebra_rmap {
4343
struct route_map *map;
4444
};
4545

46+
PREDECL_RBTREE_UNIQ(otable);
47+
48+
struct other_route_table {
49+
struct otable_item next;
50+
51+
afi_t afi;
52+
safi_t safi;
53+
uint32_t table_id;
54+
55+
struct route_table *table;
56+
};
57+
4658
/* Routing table instance. */
4759
struct zebra_vrf {
4860
/* Back pointer */
@@ -69,6 +81,8 @@ struct zebra_vrf {
6981
/* Import check table (used mostly by BGP */
7082
struct route_table *import_check_table[AFI_MAX];
7183

84+
struct otable_head other_tables;
85+
7286
/* 2nd pointer type used primarily to quell a warning on
7387
* ALL_LIST_ELEMENTS_RO
7488
*/
@@ -192,6 +206,25 @@ static inline bool zvrf_is_active(struct zebra_vrf *zvrf)
192206
return zvrf->vrf->status & VRF_ACTIVE;
193207
}
194208

209+
static inline int
210+
zvrf_other_table_compare_func(const struct other_route_table *a,
211+
const struct other_route_table *b)
212+
{
213+
if (a->afi != b->afi)
214+
return a->afi - b->afi;
215+
216+
if (a->safi != b->safi)
217+
return a->safi - b->safi;
218+
219+
if (a->table_id != b->table_id)
220+
return a->table_id - b->table_id;
221+
222+
return 0;
223+
}
224+
225+
DECLARE_RBTREE_UNIQ(otable, struct other_route_table, next,
226+
zvrf_other_table_compare_func)
227+
195228
struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
196229
vrf_id_t vrf_id,
197230
uint32_t table_id);

0 commit comments

Comments
 (0)