]> git.puffer.fish Git - matthieu/frr.git/commitdiff
isisd: merge algorithm tables
authorHiroki Shirokura <hiroki.shirokura@linecorp.com>
Fri, 21 Jan 2022 16:02:54 +0000 (16:02 +0000)
committerLouis Scalbert <louis.scalbert@6wind.com>
Tue, 18 Apr 2023 09:33:15 +0000 (11:33 +0200)
Create a temporary "merge" route table that contains the routing
information from all algorithms and install the merge route table
into the FIB.

Signed-off-by: Hiroki Shirokura <hiroki.shirokura@linecorp.com>
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
isisd/isis_route.c
isisd/isis_route.h
isisd/isis_spf.c
isisd/isis_spf.h
isisd/isisd.c

index 3191dfa4ff41bde804228957e8ef1e419ceefacc..3983c704ce65b2bf593916bd38990be855ae15c3 100644 (file)
@@ -36,6 +36,7 @@
 #include "isis_spf_private.h"
 #include "isis_route.h"
 #include "isis_zebra.h"
+#include "isis_flex_algo.h"
 
 DEFINE_MTYPE_STATIC(ISISD, ISIS_NEXTHOP,    "ISIS nexthop");
 DEFINE_MTYPE_STATIC(ISISD, ISIS_ROUTE_INFO, "ISIS route info");
@@ -725,7 +726,7 @@ static void _isis_route_verify_table(struct isis_area *area,
                if (CHECK_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE))
                        continue;
 
-               /* Area is either L1 or L2 => we use level route tables
+               /* In case the verify is not for a merge, we use a single table
                 * directly for
                 * validating => no problems with deleting routes. */
                if (!tables) {
@@ -733,13 +734,12 @@ static void _isis_route_verify_table(struct isis_area *area,
                        continue;
                }
 
-               /* If area is L1L2, we work with merge table and
-                * therefore must
-                * delete node from level tables as well before deleting
+               /* If we work on a merged table,
+                * therefore we must
+                * delete node from each table as well before deleting
                 * route info. */
-               for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
-                       drnode = srcdest_rnode_lookup(tables[level - 1],
-                                                     dst_p, src_p);
+               for (int i = 0; tables[i]; i++) {
+                       drnode = srcdest_rnode_lookup(tables[i], dst_p, src_p);
                        if (!drnode)
                                continue;
 
@@ -756,10 +756,36 @@ static void _isis_route_verify_table(struct isis_area *area,
        }
 }
 
+static void _isis_route_verify_merge(struct isis_area *area,
+                                    struct route_table **tables,
+                                    struct route_table **tables_backup,
+                                    int tree);
+
 void isis_route_verify_table(struct isis_area *area, struct route_table *table,
-                            struct route_table *table_backup)
+                            struct route_table *table_backup, int tree)
 {
-       _isis_route_verify_table(area, table, table_backup, NULL);
+       struct route_table *tables[SR_ALGORITHM_COUNT] = {table};
+       struct route_table *tables_backup[SR_ALGORITHM_COUNT] = {table_backup};
+#ifndef FABRICD
+       int tables_next = 1;
+       int level = area->is_type == IS_LEVEL_1 ? ISIS_LEVEL1 : ISIS_LEVEL2;
+       struct listnode *node;
+       struct flex_algo *fa;
+       struct isis_flex_algo_data *data;
+
+       for (ALL_LIST_ELEMENTS_RO(area->flex_algos->flex_algos, node, fa)) {
+               data = fa->data;
+               tables[tables_next] =
+                       data->spftree[tree][level - 1]->route_table;
+               tables_backup[tables_next] =
+                       data->spftree[tree][level - 1]->route_table_backup;
+               _isis_route_verify_table(area, tables[tables_next],
+                                        tables_backup[tables_next], NULL);
+               tables_next++;
+       }
+#endif /* ifndef FABRICD */
+
+       _isis_route_verify_merge(area, tables, tables_backup, tree);
 }
 
 /* Function to validate route tables for L1L2 areas. In this case we can't use
@@ -776,20 +802,27 @@ void isis_route_verify_merge(struct isis_area *area,
                             struct route_table *level1_table,
                             struct route_table *level1_table_backup,
                             struct route_table *level2_table,
-                            struct route_table *level2_table_backup)
+                            struct route_table *level2_table_backup, int tree)
 {
-       struct route_table *tables[] = {level1_table, level2_table};
+       struct route_table *tables[] = {level1_table, level2_table, NULL};
        struct route_table *tables_backup[] = {level1_table_backup,
-                                              level2_table_backup};
+                                              level2_table_backup, NULL};
+       _isis_route_verify_merge(area, tables, tables_backup, tree);
+}
+
+static void _isis_route_verify_merge(struct isis_area *area,
+                                    struct route_table **tables,
+                                    struct route_table **tables_backup,
+                                    int tree)
+{
        struct route_table *merge;
        struct route_node *rnode, *mrnode;
 
        merge = srcdest_table_init();
 
-       for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
-               uint8_t algorithm =
-                       isis_route_table_algorithm(tables[level - 1]);
-               for (rnode = route_top(tables[level - 1]); rnode;
+       for (int i = 0; tables[i]; i++) {
+               uint8_t algorithm = isis_route_table_algorithm(tables[i]);
+               for (rnode = route_top(tables[i]); rnode;
                     rnode = srcdest_route_next(rnode)) {
                        struct isis_route_info *rinfo = rnode->info;
                        struct route_node *rnode_bck;
@@ -805,8 +838,8 @@ void isis_route_verify_merge(struct isis_area *area,
                                               (const struct prefix **)&src_p);
 
                        /* Link primary route to backup route. */
-                       rnode_bck = srcdest_rnode_lookup(
-                               tables_backup[level - 1], prefix, src_p);
+                       rnode_bck = srcdest_rnode_lookup(tables_backup[i],
+                                                        prefix, src_p);
                        if (rnode_bck) {
                                rinfo->backup = rnode_bck->info;
                                rinfo->sr_algo[algorithm].nexthops_backup =
index 79b604b779f32268ae492003186f072c7fb499c0..4d49a5ae9cf5bdd94706488b53727c7969ede51e 100644 (file)
@@ -60,14 +60,14 @@ void isis_route_delete(struct isis_area *area, struct route_node *rode,
 /* Walk the given table and install new routes to zebra and remove old ones.
  * route status is tracked using ISIS_ROUTE_FLAG_ACTIVE */
 void isis_route_verify_table(struct isis_area *area, struct route_table *table,
-                            struct route_table *table_backup);
+                            struct route_table *table_backup, int tree);
 
 /* Same as isis_route_verify_table, but merge L1 and L2 routes before */
 void isis_route_verify_merge(struct isis_area *area,
                             struct route_table *level1_table,
                             struct route_table *level1_table_backup,
                             struct route_table *level2_table,
-                            struct route_table *level2_table_backup);
+                            struct route_table *level2_table_backup, int tree);
 
 /* Unset ISIS_ROUTE_FLAG_ACTIVE on all routes. Used before running spf. */
 void isis_route_invalidate_table(struct isis_area *area,
index cc8c5168e45d3718c0095cd7fd52d1a42199ec1c..faaf8d94d34fc4cd4b99a04b837b2a9e79269fc5 100644 (file)
@@ -1933,19 +1933,20 @@ static void isis_run_spf_with_protection(struct isis_area *area,
                isis_spf_run_lfa(area, spftree);
 }
 
-void isis_spf_verify_routes(struct isis_area *area, struct isis_spftree **trees)
+void isis_spf_verify_routes(struct isis_area *area, struct isis_spftree **trees,
+                           int tree)
 {
        if (area->is_type == IS_LEVEL_1) {
                isis_route_verify_table(area, trees[0]->route_table,
-                                       trees[0]->route_table_backup);
+                                       trees[0]->route_table_backup, tree);
        } else if (area->is_type == IS_LEVEL_2) {
                isis_route_verify_table(area, trees[1]->route_table,
-                                       trees[1]->route_table_backup);
+                                       trees[1]->route_table_backup, tree);
        } else {
                isis_route_verify_merge(area, trees[0]->route_table,
                                        trees[0]->route_table_backup,
                                        trees[1]->route_table,
-                                       trees[1]->route_table_backup);
+                                       trees[1]->route_table_backup, tree);
        }
 }
 
index bf79a084bba9d7a9bdbaf2f07b888e91ed62db52..9af4d1bdcf48c184aaec263b22400d708a828a28 100644 (file)
@@ -44,8 +44,8 @@ isis_spftree_new(struct isis_area *area, struct lspdb_head *lspdb,
 struct isis_vertex *isis_spf_prefix_sid_lookup(struct isis_spftree *spftree,
                                               struct isis_prefix_sid *psid);
 void isis_spf_invalidate_routes(struct isis_spftree *tree);
-void isis_spf_verify_routes(struct isis_area *area,
-                           struct isis_spftree **trees);
+void isis_spf_verify_routes(struct isis_area *area, struct isis_spftree **trees,
+                           int tree);
 void isis_spf_switchover_routes(struct isis_area *area,
                                struct isis_spftree **trees, int family,
                                union g_addr *nexthop_ip, ifindex_t ifindex,
index 195f9f16f10243d10fc97a2125f5b18c1adf419b..e4689b0323d5f82e5688cd8e1c8c96daba4183ff 100644 (file)
@@ -3097,7 +3097,7 @@ void isis_area_invalidate_routes(struct isis_area *area, int levels)
 void isis_area_verify_routes(struct isis_area *area)
 {
        for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++)
-               isis_spf_verify_routes(area, area->spftree[tree]);
+               isis_spf_verify_routes(area, area->spftree[tree], tree);
 }
 
 void isis_area_switchover_routes(struct isis_area *area, int family,