]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: use a new vertex list for every SPF run 7003/head
authorGalaxyGorilla <sascha@netdef.org>
Tue, 25 Aug 2020 14:13:08 +0000 (14:13 +0000)
committerGalaxyGorilla <sascha@netdef.org>
Thu, 27 Aug 2020 09:05:51 +0000 (09:05 +0000)
In the context of TI-LFA it is necessary to have multiple
representations of SPFs for so called P and Q spaces. Hence it makes
sense to start with fresh vertex lists, and only delete them when
the SPF calculation is not a 'dry run'.

Signed-off-by: GalaxyGorilla <sascha@netdef.org>
ospfd/ospf_spf.c
ospfd/ospf_spf.h
ospfd/ospfd.h

index 6d09d91c5dc237cd5f30cbf8ec75d0b0e75d08a2..f5e393a13c0da1b91bff582b06b03b5800cbfbe2 100644 (file)
@@ -68,12 +68,6 @@ static void ospf_spf_set_reason(ospf_spf_reason_t reason)
 }
 
 static void ospf_vertex_free(void *);
-/*
- * List of allocated vertices, to simplify cleanup of SPF.
- * Not thread-safe obviously. If it ever needs to be, it'd have to be
- * dynamically allocated at begin of ospf_spf_calculate
- */
-static struct list vertex_list = {.del = ospf_vertex_free};
 
 /*
  * Heap related functions, for the managment of the candidates, to
@@ -184,7 +178,8 @@ static int vertex_parent_cmp(void *aa, void *bb)
        return IPV4_ADDR_CMP(&a->nexthop->router, &b->nexthop->router);
 }
 
-static struct vertex *ospf_vertex_new(struct ospf_lsa *lsa)
+static struct vertex *ospf_vertex_new(struct ospf_area *area,
+                                     struct ospf_lsa *lsa)
 {
        struct vertex *new;
 
@@ -202,7 +197,7 @@ static struct vertex *ospf_vertex_new(struct ospf_lsa *lsa)
 
        lsa->stat = new;
 
-       listnode_add(&vertex_list, new);
+       listnode_add(area->spf_vertex_list, new);
 
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug("%s: Created %s vertex %s", __func__,
@@ -292,12 +287,18 @@ static void ospf_vertex_add_parent(struct vertex *v)
 static void ospf_spf_init(struct ospf_area *area, struct ospf_lsa *root_lsa,
                          bool is_dry_run, bool is_root_node)
 {
+       struct list *vertex_list;
        struct vertex *v;
 
-       /* Create root node. */
-       v = ospf_vertex_new(root_lsa);
+       /* Create vertex list */
+       vertex_list = list_new();
+       vertex_list->del = ospf_vertex_free;
+       area->spf_vertex_list = vertex_list;
 
+       /* Create root node. */
+       v = ospf_vertex_new(area, root_lsa);
        area->spf = v;
+
        area->spf_dry_run = is_dry_run;
        area->spf_root_node = is_root_node;
 
@@ -956,7 +957,7 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
                /* Is there already vertex W in candidate list? */
                if (w_lsa->stat == LSA_SPF_NOT_EXPLORED) {
                        /* prepare vertex W. */
-                       w = ospf_vertex_new(w_lsa);
+                       w = ospf_vertex_new(area, w_lsa);
 
                        /* Calculate nexthop to W. */
                        if (ospf_nexthop_calculation(area, v, w, l, distance,
@@ -1146,6 +1147,19 @@ void ospf_rtrs_free(struct route_table *rtrs)
        route_table_finish(rtrs);
 }
 
+void ospf_spf_cleanup(struct vertex *spf, struct list *vertex_list)
+{
+       /*
+        * Free nexthop information, canonical versions of which are
+        * attached the first level of router vertices attached to the
+        * root vertex, see ospf_nexthop_calculation.
+        */
+       ospf_canonical_nexthops_free(spf);
+
+       /* Free SPF vertices list with deconstructor ospf_vertex_free. */
+       list_delete(&vertex_list);
+}
+
 #if 0
 static void
 ospf_rtrs_print (struct route_table *rtrs)
@@ -1311,20 +1325,8 @@ void ospf_spf_calculate(struct ospf_area *area, struct ospf_lsa *root_lsa,
                           mtype_stats_alloc(MTYPE_OSPF_VERTEX));
 
        /* If this is a dry run then keep the SPF data in place */
-       if (!area->spf_dry_run) {
-               /*
-                * Free nexthop information, canonical versions of which are
-                * attached the first level of router vertices attached to the
-                * root vertex, see ospf_nexthop_calculation.
-                */
-               ospf_canonical_nexthops_free(area->spf);
-
-               /*
-                * Free SPF vertices, but not the list. List has
-                * ospf_vertex_free as deconstructor.
-                */
-               list_delete_all_node(&vertex_list);
-       }
+       if (!area->spf_dry_run)
+               ospf_spf_cleanup(area->spf, area->spf_vertex_list);
 }
 
 int ospf_spf_calculate_areas(struct ospf *ospf, struct route_table *new_table,
index 03711464204a6efc5bbc40cd1f0eb7b052ba8f94..2dc0f8b88663281acd6a302cb4104472da8317fa 100644 (file)
@@ -82,6 +82,7 @@ extern int ospf_spf_calculate_areas(struct ospf *ospf,
                                    struct route_table *new_rtrs,
                                    bool is_dry_run, bool is_root_node);
 extern void ospf_rtrs_free(struct route_table *);
+extern void ospf_spf_cleanup(struct vertex *spf, struct list *vertex_list);
 
 extern void ospf_spf_print(struct vty *vty, struct vertex *v, int i);
 
index 8a1469469fa91bea649f3577d141179606f6a83c..e5e07875e87ba3647e00975a520aca9e9de51398 100644 (file)
@@ -414,6 +414,8 @@ struct ospf_area {
 
        /* Shortest Path Tree. */
        struct vertex *spf;
+       struct list *spf_vertex_list;
+
        bool spf_dry_run;   /* flag for checking if the SPF calculation is
                               intended for the local RIB */
        bool spf_root_node; /* flag for checking if the calculating node is the