]> git.proxmox.com Git - mirror_frr.git/commitdiff
isisd: fix wrongly disabled flex-algo
authorLouis Scalbert <louis.scalbert@6wind.com>
Wed, 31 May 2023 14:53:58 +0000 (16:53 +0200)
committerLouis Scalbert <louis.scalbert@6wind.com>
Thu, 1 Jun 2023 12:26:39 +0000 (14:26 +0200)
A configured flex-algo algorithm may remain in disabled state after its
definition is advertised on the area.

It happens sometimes that, in isis_sr_flex_algo_topo1 topotest step 4 or
8, flex-algo 203 is disabled. It depends on the following sequence:

 1. Flex-algo 203 is configured on a remote router to be re-advertised.
 2. A LSP is received on the local router and contains the algo 203
    definition.
 3. The local router re-builds its own LSP with lsp_build().
 4. local router isis_run_spf() recomputes the algo 203 SPF tree.

A 1. 2. 3. 4. sequence results in a working test. The reception of the
remote LSP (2.) does not trigger the built of the local LSP. If for
some reasons, the sequence is 1. 3. 4. 2. 4., isis_run_spf() will not
knows that flex-algo 203 has been re-enabled because
flex_algo_get_state() only returns the state from the local LSP.

Compare in sequence step 4. the flex-algo state from the local LSP with
the actual state. If the state is not the same, request a new local LSP
generation and quits the re-computation of algo SPF tree. The SPF tree
will be recomputed just after the built of the local LSP.

Fixes: 3f55b8c621 ("isisd: fix disabled flex-algo on race condition")
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
isisd/isis_spf.c

index de467c8262d73af0e5ce08d65678cae3fccc8ea7..e114467e07ccdd9a36c5b8bdd3bb4f5d28e49717 100644 (file)
@@ -1843,6 +1843,9 @@ void isis_run_spf(struct isis_spftree *spftree)
        struct timeval time_end;
        struct isis_mt_router_info *mt_router_info;
        uint16_t mtid = 0;
+#ifndef FABRICD
+       bool flex_algo_enabled;
+#endif /* ifndef FABRICD */
 
        /* Get time that can't roll backwards. */
        monotime(&time_start);
@@ -1885,16 +1888,27 @@ void isis_run_spf(struct isis_spftree *spftree)
         * not supported by the node, it MUST stop participating in such
         * Flexible-Algorithm.
         */
-       if (flex_algo_id_valid(spftree->algorithm) &&
-           !flex_algo_get_state(spftree->area->flex_algos,
-                                spftree->algorithm)) {
-               if (!CHECK_FLAG(spftree->flags, F_SPFTREE_DISABLED)) {
-                       isis_spftree_clear(spftree);
-                       SET_FLAG(spftree->flags, F_SPFTREE_DISABLED);
+       if (flex_algo_id_valid(spftree->algorithm)) {
+               flex_algo_enabled = isis_flex_algo_elected_supported(
+                       spftree->algorithm, spftree->area);
+               if (flex_algo_enabled !=
+                   flex_algo_get_state(spftree->area->flex_algos,
+                                       spftree->algorithm)) {
+                       /* actual state is inconsistent with local LSP */
                        lsp_regenerate_schedule(spftree->area,
                                                spftree->area->is_type, 0);
+                       goto out;
+               }
+               if (!flex_algo_enabled) {
+                       if (!CHECK_FLAG(spftree->flags, F_SPFTREE_DISABLED)) {
+                               isis_spftree_clear(spftree);
+                               SET_FLAG(spftree->flags, F_SPFTREE_DISABLED);
+                               lsp_regenerate_schedule(spftree->area,
+                                                       spftree->area->is_type,
+                                                       0);
+                       }
+                       goto out;
                }
-               goto out;
        }
 #endif /* ifndef FABRICD */