]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Track tables allocated by vrf and cleanup
authorDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 6 May 2019 23:42:26 +0000 (19:42 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 9 May 2019 11:11:22 +0000 (07:11 -0400)
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>
zebra/zebra_rib.c
zebra/zebra_vrf.c
zebra/zebra_vrf.h

index 2945a5ef9d186c09a9356371671b86e1b401aefd..af29443aabe724e2db2daf3c0f917e688f83eefd 100644 (file)
@@ -3227,18 +3227,23 @@ unsigned long rib_score_proto(uint8_t proto, unsigned short instance)
 {
        struct vrf *vrf;
        struct zebra_vrf *zvrf;
+       struct other_route_table *ort;
        unsigned long cnt = 0;
 
-       RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
-               if ((zvrf = vrf->info) != NULL)
-                       cnt += rib_score_proto_table(
-                                      proto, instance,
-                                      zvrf->table[AFI_IP][SAFI_UNICAST])
-                              + rib_score_proto_table(
-                                        proto, instance,
-                                        zvrf->table[AFI_IP6][SAFI_UNICAST]);
+       RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
+               zvrf = vrf->info;
+               if (!zvrf)
+                       continue;
 
-       cnt += zebra_router_score_proto(proto, instance);
+               cnt += rib_score_proto_table(proto, instance,
+                                            zvrf->table[AFI_IP][SAFI_UNICAST])
+                      + rib_score_proto_table(
+                              proto, instance,
+                              zvrf->table[AFI_IP6][SAFI_UNICAST]);
+
+               for_each(otable, &zvrf->other_tables, ort) cnt +=
+                       rib_score_proto_table(proto, instance, ort->table);
+       }
 
        return cnt;
 }
index 38f8adeae7b33937f6f2bec7a665bc4a079c451b..4883729c96d1572e07cab8d8c59940a2866da0cd 100644 (file)
@@ -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,
                                        struct route_node *node);
 
+DEFINE_MTYPE_STATIC(ZEBRA, OTHER_TABLE, "Other Table");
+
 /* VRF information update. */
 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();
        vrf->info = zvrf;
        zvrf->vrf = vrf;
+
+       otable_init(&zvrf->other_tables);
+
        router_id_init(zvrf);
        return 0;
 }
@@ -226,6 +231,7 @@ static int zebra_vrf_disable(struct vrf *vrf)
 static int zebra_vrf_delete(struct vrf *vrf)
 {
        struct zebra_vrf *zvrf = vrf->info;
+       struct other_route_table *otable;
        struct route_table *table;
        afi_t afi;
        safi_t safi;
@@ -274,11 +280,22 @@ static int zebra_vrf_delete(struct vrf *vrf)
                        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 */
        zebra_vxlan_vrf_delete(zvrf);
 
        list_delete_all_node(zvrf->rid_all_sorted_list);
        list_delete_all_node(zvrf->rid_lo_sorted_list);
+
+       otable_fini(&zvrf->other_tables);
        XFREE(MTYPE_ZEBRA_VRF, zvrf);
        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)
 {
        struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id);
+       struct other_route_table ort, *otable;
+       struct route_table *table;
 
        if (!zvrf)
                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)
                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,
index 49887f1b6793b20d56b13301c4a353a1f3d675f5..febaf3c844efa0351b80e734514b7339cc2e87c7 100644 (file)
@@ -43,6 +43,18 @@ struct zebra_rmap {
        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.  */
 struct zebra_vrf {
        /* Back pointer */
@@ -69,6 +81,8 @@ struct zebra_vrf {
        /* Import check table (used mostly by BGP */
        struct route_table *import_check_table[AFI_MAX];
 
+       struct otable_head other_tables;
+
        /* 2nd pointer type used primarily to quell a warning on
         * ALL_LIST_ELEMENTS_RO
         */
@@ -192,6 +206,25 @@ static inline bool zvrf_is_active(struct zebra_vrf *zvrf)
        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,
                                                  vrf_id_t vrf_id,
                                                  uint32_t table_id);