]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd: make isis work with default vrf name different than 'default' 9908/head
authorPhilippe Guibert <philippe.guibert@6wind.com>
Wed, 27 Oct 2021 12:56:37 +0000 (14:56 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Wed, 27 Oct 2021 14:54:19 +0000 (16:54 +0200)
The problem is related to startup configuration, which is not operational
on default vrf name.

To reproduce the issue, run the two daemons:
zebra -o vrf0 &
isisd -f /tmp/isisd.conf

router isis 1
 lsp-gen-interval 2
 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0000.00
 metric-style wide
 redistribute ipv4 connected level-2
 redistribute ipv6 connected level-2

The obtained show running-config looks like below:

router isis 1 vrf default
 lsp-gen-interval 2
 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0000.00
 metric-style wide
 redistribute ipv4 connected level-2
 redistribute ipv6 connected level-2

The default vrf name is obtained by zebra daemon. While isis is not
connected to zebra, i.e. at startup, when loading a startup configuration,
the macro VRF_DEFAULT_NAME is used and returns 'default'.

But because zebra connected and forces to a new default vrf name, the
configuration is not seen as the default one, and further attempts to
configure the isis instance via 'router isis 1' will trigger creation
of an other instance.

To handle this situation, at vrf_enable() event, which is called for
each default vrf name change, the associated isis instance is updated
with th new vrf name. The same is done for NB yang path.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
isisd/isisd.c

index 65764654ee859be4f5d456a78440afba0c66999c..8c26a57bef4ffedc11a5ba0e614279d00c325f72 100644 (file)
@@ -646,7 +646,52 @@ static int isis_vrf_enable(struct vrf *vrf)
                           vrf->vrf_id);
 
        isis = isis_lookup_by_vrfname(vrf->name);
-       if (isis) {
+       if (!isis) {
+               char *old_vrf_name = NULL;
+
+               isis = (struct isis *)vrf->info;
+               if (!isis)
+                       return 0;
+               /* update vrf name */
+               if (isis->name)
+                       old_vrf_name = isis->name;
+               isis->name = XSTRDUP(MTYPE_ISIS_NAME, vrf->name);
+               /*
+                * HACK: Change the ISIS VRF in the running configuration
+                * directly, bypassing the northbound layer. This is necessary
+                * to avoid deleting the ISIS and readding it in the new VRF,
+                * which would have several implications.
+                */
+               if (yang_module_find("frr-isisd") && old_vrf_name) {
+                       struct lyd_node *isis_dnode;
+                       struct isis_area *area;
+                       char oldpath[XPATH_MAXLEN];
+                       char newpath[XPATH_MAXLEN];
+                       struct listnode *node, *nnode;
+
+                       for (ALL_LIST_ELEMENTS(isis->area_list, node, nnode,
+                                              area)) {
+                               isis_dnode = yang_dnode_getf(
+                                       running_config->dnode,
+                                       "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']/vrf",
+                                       area->area_tag, old_vrf_name);
+                               if (isis_dnode) {
+                                       yang_dnode_get_path(
+                                               lyd_parent(isis_dnode), oldpath,
+                                               sizeof(oldpath));
+                                       yang_dnode_change_leaf(isis_dnode,
+                                                              vrf->name);
+                                       yang_dnode_get_path(
+                                               lyd_parent(isis_dnode), newpath,
+                                               sizeof(newpath));
+                                       nb_running_move_tree(oldpath, newpath);
+                                       running_config->version++;
+                               }
+                       }
+               }
+               XFREE(MTYPE_ISIS_NAME, old_vrf_name);
+       }
+       if (isis && isis->vrf_id != vrf->vrf_id) {
                old_vrf_id = isis->vrf_id;
                /* We have instance configured, link to VRF and make it "up". */
                isis_vrf_link(isis, vrf);
@@ -654,12 +699,10 @@ static int isis_vrf_enable(struct vrf *vrf)
                        zlog_debug(
                                "%s: isis linked to vrf %s vrf_id %u (old id %u)",
                                __func__, vrf->name, isis->vrf_id, old_vrf_id);
-               if (old_vrf_id != isis->vrf_id) {
-                       /* start zebra redist to us for new vrf */
-                       isis_set_redist_vrf_bitmaps(isis, true);
+               /* start zebra redist to us for new vrf */
+               isis_set_redist_vrf_bitmaps(isis, true);
 
-                       isis_zebra_vrf_register(isis);
-               }
+               isis_zebra_vrf_register(isis);
        }
 
        return 0;