]> git.proxmox.com Git - mirror_frr.git/commitdiff
isisd: fix redistribution in vrf
authorIgor Ryzhov <iryzhov@nfware.com>
Tue, 4 May 2021 21:10:31 +0000 (00:10 +0300)
committerIgor Ryzhov <iryzhov@nfware.com>
Fri, 14 May 2021 14:12:35 +0000 (17:12 +0300)
When the redistribution is configured in non-default VRF, isisd should
redistribute routes from this VRF instead of default.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
20 files changed:
isisd/isis_redist.c
isisd/isis_redist.h
isisd/isis_zebra.c
isisd/isis_zebra.h
isisd/isisd.c
tests/topotests/isis_topo1_vrf/r1/r1_route.json
tests/topotests/isis_topo1_vrf/r1/r1_route6.json
tests/topotests/isis_topo1_vrf/r1/r1_topology.json
tests/topotests/isis_topo1_vrf/r2/r2_route.json
tests/topotests/isis_topo1_vrf/r2/r2_route6.json
tests/topotests/isis_topo1_vrf/r2/r2_topology.json
tests/topotests/isis_topo1_vrf/r3/r3_route.json
tests/topotests/isis_topo1_vrf/r3/r3_route6.json
tests/topotests/isis_topo1_vrf/r3/r3_topology.json
tests/topotests/isis_topo1_vrf/r4/r4_route.json
tests/topotests/isis_topo1_vrf/r4/r4_route6.json
tests/topotests/isis_topo1_vrf/r4/r4_topology.json
tests/topotests/isis_topo1_vrf/r5/r5_route.json
tests/topotests/isis_topo1_vrf/r5/r5_route6.json
tests/topotests/isis_topo1_vrf/r5/r5_topology.json

index 843df3a849b74f00d273c423d3978edea268103f..ce0f44bf7a8f71265ed86fe2637ca5318fd16c49 100644 (file)
@@ -56,7 +56,7 @@ static int redist_protocol(int family)
        return 0;
 }
 
-static afi_t afi_for_redist_protocol(int protocol)
+afi_t afi_for_redist_protocol(int protocol)
 {
        if (protocol == 0)
                return AFI_IP;
@@ -350,6 +350,9 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis)
        int level;
        int protocol;
 
+       if (isis->vrf_id == VRF_UNKNOWN)
+               return;
+
        char do_subscribe[REDIST_PROTOCOL_COUNT][ZEBRA_ROUTE_MAX + 1];
 
        memset(do_subscribe, 0, sizeof(do_subscribe));
@@ -378,9 +381,11 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis)
                        afi_t afi = afi_for_redist_protocol(protocol);
 
                        if (do_subscribe[protocol][type])
-                               isis_zebra_redistribute_set(afi, type);
+                               isis_zebra_redistribute_set(afi, type,
+                                                           isis->vrf_id);
                        else
-                               isis_zebra_redistribute_unset(afi, type);
+                               isis_zebra_redistribute_unset(afi, type,
+                                                             isis->vrf_id);
                }
 }
 
index fcc4ceadf49b92e170182855a5c1c44bf490617e..10dccbc5187735547615fdd706815705e2a7d317 100644 (file)
@@ -47,6 +47,8 @@ struct prefix;
 struct prefix_ipv6;
 struct vty;
 
+afi_t afi_for_redist_protocol(int protocol);
+
 struct route_table *get_ext_reach(struct isis_area *area, int family,
                                  int level);
 void isis_redist_add(struct isis *isis, int type, struct prefix *p,
index 9c80f4e836038f6dcf270851a00e224fb6749b11..0142e30b2be63aa647931e852bcc229c76fd6add 100644 (file)
@@ -523,24 +523,24 @@ int isis_distribute_list_update(int routetype)
        return 0;
 }
 
-void isis_zebra_redistribute_set(afi_t afi, int type)
+void isis_zebra_redistribute_set(afi_t afi, int type, vrf_id_t vrf_id)
 {
        if (type == DEFAULT_ROUTE)
                zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
-                                            zclient, afi, VRF_DEFAULT);
+                                            zclient, afi, vrf_id);
        else
                zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
-                                    0, VRF_DEFAULT);
+                                    0, vrf_id);
 }
 
-void isis_zebra_redistribute_unset(afi_t afi, int type)
+void isis_zebra_redistribute_unset(afi_t afi, int type, vrf_id_t vrf_id)
 {
        if (type == DEFAULT_ROUTE)
                zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
-                                            zclient, afi, VRF_DEFAULT);
+                                            zclient, afi, vrf_id);
        else
                zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
-                                    type, 0, VRF_DEFAULT);
+                                    type, 0, vrf_id);
 }
 
 /**
index 006f020757bfc3542aff8a5ee0757b2afec50afb..348d7b3eab6fcbede58ca05952cc3f7de3aaf232 100644 (file)
@@ -57,8 +57,8 @@ void isis_zebra_prefix_sid_uninstall(struct isis_area *area,
                                     struct isis_sr_psid_info *psid);
 void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra);
 int isis_distribute_list_update(int routetype);
-void isis_zebra_redistribute_set(afi_t afi, int type);
-void isis_zebra_redistribute_unset(afi_t afi, int type);
+void isis_zebra_redistribute_set(afi_t afi, int type, vrf_id_t vrf_id);
+void isis_zebra_redistribute_unset(afi_t afi, int type, vrf_id_t vrf_id);
 int isis_zebra_rlfa_register(struct isis_spftree *spftree, struct rlfa *rlfa);
 void isis_zebra_rlfa_unregister_all(struct isis_spftree *spftree);
 bool isis_zebra_label_manager_ready(void);
index 4f276901975cbbe50fd8393f00ea809e28f78cbe..172d20215031493b3a8fa2cdf771b695a031b101 100644 (file)
@@ -200,6 +200,8 @@ struct isis *isis_new(const char *vrf_name)
        else
                isis->vrf_id = VRF_UNKNOWN;
 
+       isis_zebra_vrf_register(isis);
+
        if (IS_DEBUG_EVENTS)
                zlog_debug(
                        "%s: Create new isis instance with vrf_name %s vrf_id %u",
@@ -227,6 +229,8 @@ void isis_finish(struct isis *isis)
 
        listnode_delete(im->isis, isis);
 
+       isis_zebra_vrf_deregister(isis);
+
        vrf = vrf_lookup_by_name(isis->name);
        if (vrf)
                isis_vrf_unlink(isis, vrf);
@@ -595,6 +599,68 @@ static int isis_vrf_delete(struct vrf *vrf)
        return 0;
 }
 
+static void isis_set_redist_vrf_bitmaps(struct isis *isis, bool set)
+{
+       struct listnode *node;
+       struct isis_area *area;
+       int type;
+       int level;
+       int protocol;
+
+       char do_subscribe[REDIST_PROTOCOL_COUNT][ZEBRA_ROUTE_MAX + 1];
+
+       memset(do_subscribe, 0, sizeof(do_subscribe));
+
+       for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
+               for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++)
+                       for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++)
+                               for (level = 0; level < ISIS_LEVELS; level++)
+                                       if (area->redist_settings[protocol]
+                                                                [type][level]
+                                                                        .redist
+                                           == 1)
+                                               do_subscribe[protocol][type] =
+                                                       1;
+
+       for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++)
+               for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) {
+                       /* This field is actually controlling transmission of
+                        * the IS-IS
+                        * routes to Zebra and has nothing to do with
+                        * redistribution,
+                        * so skip it. */
+                       if (type == PROTO_TYPE)
+                               continue;
+
+                       if (!do_subscribe[protocol][type])
+                               continue;
+
+                       afi_t afi = afi_for_redist_protocol(protocol);
+
+                       if (type == DEFAULT_ROUTE) {
+                               if (set)
+                                       vrf_bitmap_set(
+                                               zclient->default_information
+                                                       [afi],
+                                               isis->vrf_id);
+                               else
+                                       vrf_bitmap_unset(
+                                               zclient->default_information
+                                                       [afi],
+                                               isis->vrf_id);
+                       } else {
+                               if (set)
+                                       vrf_bitmap_set(
+                                               zclient->redist[afi][type],
+                                               isis->vrf_id);
+                               else
+                                       vrf_bitmap_unset(
+                                               zclient->redist[afi][type],
+                                               isis->vrf_id);
+                       }
+               }
+}
+
 static int isis_vrf_enable(struct vrf *vrf)
 {
        struct isis *isis;
@@ -615,6 +681,8 @@ static int isis_vrf_enable(struct vrf *vrf)
                                __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);
+
                        isis_zebra_vrf_register(isis);
                }
        }
@@ -639,6 +707,8 @@ static int isis_vrf_disable(struct vrf *vrf)
 
                isis_zebra_vrf_deregister(isis);
 
+               isis_set_redist_vrf_bitmaps(isis, false);
+
                /* We have instance configured, unlink
                 * from VRF and make it "down".
                 */
index f0a3593a4c4e72a4ce8296eb85c73627dcb5594d..8359baadafad3e69119dd7119fcd553365b94791 100644 (file)
@@ -2,7 +2,7 @@
   "10.0.10.0/24": [
     {
       "distance": 115, 
-      "metric": 20, 
+      "metric": 10, 
       "nexthops": [
         {
           "active": true, 
index 888b9e2c424145f1604134b91c0e48bf8cb03417..74961262b49ebf5752104e81ac21a925339e9ccd 100644 (file)
@@ -18,7 +18,7 @@
   "2001:db8:2:1::/64": [
     {
       "distance": 115, 
-      "metric": 20, 
+      "metric": 10, 
       "nexthops": [
         {
           "active": true, 
index 1a6fe6d5c616a5c9ce56cd441939e8e0d0b53067..666fa52b19a21b68aefb0ef09ad9eabc331ca4bd 100644 (file)
@@ -33,7 +33,7 @@
         },
         {
           "interface": "r1-eth0",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r3",
           "parent": "r3(4)",
           "type": "IP TE",
@@ -41,7 +41,7 @@
         },
         {
           "interface": "r1-eth0",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r3",
           "parent": "r3(4)",
           "type": "IP TE",
@@ -67,8 +67,8 @@
           "vertex": "r3"
         },
         {
+          "metric": "10",
           "interface": "r1-eth0",
-          "metric": "20",
           "next-hop": "r3",
           "parent": "r3(4)",
           "type": "IP6 internal",
index a26cdfad8eb68c4536944e2ce8d31bcce0be7f75..e2eee112b3c2f814ada51a8f764411ad8dbcae1e 100644 (file)
@@ -2,7 +2,7 @@
   "10.0.11.0/24": [
     {
       "distance": 115, 
-      "metric": 20, 
+      "metric": 10, 
       "nexthops": [
         {
           "active": true, 
index b01789b8d90a4e6783a7d8e3e07769cd8a224ec2..21b953d0f7e052b119382d9b368518e98b235607 100644 (file)
@@ -18,7 +18,7 @@
   "2001:db8:2:2::/64": [
     {
       "distance": 115, 
-      "metric": 20, 
+      "metric": 10, 
       "nexthops": [
         {
           "active": true, 
index a77f7977f940196e6db4bfeb651c074a8e3da297..c26ad1ee37e4d8654f443d96d0a82c3581d6dfd2 100644 (file)
@@ -33,7 +33,7 @@
         },
         {
           "interface": "r2-eth0",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r4",
           "parent": "r4(4)",
           "type": "IP TE",
@@ -41,7 +41,7 @@
         },
         {
           "interface": "r2-eth0",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r4",
           "parent": "r4(4)",
           "type": "IP TE",
@@ -67,8 +67,8 @@
           "vertex": "r4"
         },
         {
+          "metric": "10",
           "interface": "r2-eth0",
-          "metric": "20",
           "next-hop": "r4",
           "parent": "r4(4)",
           "type": "IP6 internal",
index 9717df5c1afdeb7d85b305e216b336ba87e50d8a..33ad90cda1cc943204f104f441d31643d8a6cca1 100644 (file)
@@ -2,7 +2,7 @@
   "10.0.10.0/24": [
     {
       "distance": 115, 
-      "metric": 20, 
+      "metric": 10, 
       "nexthops": [
         {
           "afi": "ipv4", 
@@ -32,7 +32,7 @@
   "10.0.11.0/24": [
     {
       "distance": 115, 
-      "metric": 20, 
+      "metric": 10, 
       "nexthops": [
         {
           "active": true, 
@@ -67,7 +67,7 @@
   "10.0.21.0/24": [
     {
       "distance": 115, 
-      "metric": 30, 
+      "metric": 20, 
       "nexthops": [
         {
           "active": true, 
index 31a1e4620fb9075b86d0301b4e0b3adbe3d16b27..519fe4968a77ab17f7d74f2b717277b400cfc35f 100644 (file)
@@ -18,7 +18,7 @@
   "2001:db8:1:2::/64": [
     {
       "distance": 115, 
-      "metric": 30, 
+      "metric": 20, 
       "nexthops": [
         {
           "active": true, 
@@ -52,7 +52,7 @@
   "2001:db8:2:2::/64": [
     {
       "distance": 115, 
-      "metric": 20, 
+      "metric": 10, 
       "nexthops": [
         {
           "active": true, 
index 1e5d331965b9f08a8545c74f9dfa7d9dbfeaee3e..34892d4a3a2bc59116682e39a362678eb213dbf5 100644 (file)
@@ -21,7 +21,7 @@
         },
         {
           "interface": "r3-eth1",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r5",
           "parent": "r5(4)",
           "type": "IP TE",
@@ -29,7 +29,7 @@
         },
         {
           "interface": "r3-eth1",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r5",
           "parent": "r5(4)",
           "type": "IP TE",
@@ -37,7 +37,7 @@
         },
         {
           "interface": "r3-eth1",
-          "metric": "30",
+          "metric": "20",
           "next-hop": "r5",
           "parent": "r4(4)",
           "type": "IP TE",
           "vertex": "r5"
         },
         {
+          "metric": "10",
           "interface": "r3-eth1",
-          "metric": "20",
           "next-hop": "r5",
           "parent": "r5(4)",
           "type": "IP6 internal",
           "vertex": "2001:db8:2:2::/64"
         },
         {
+          "metric": "20",
           "interface": "r3-eth1",
-          "metric": "30",
           "next-hop": "r5",
           "parent": "r4(4)",
           "type": "IP6 internal",
         },
         {
           "interface": "r3-eth0",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r3",
           "parent": "r3(4)",
           "type": "IP TE",
index 6cb79b03015d9a9a6647ade61f2ba71c20035fb3..6fb3bd99d1fee5b1a6ef95bbaa3b142d91a4a96a 100644 (file)
@@ -1,7 +1,7 @@
 {
   "10.0.10.0/24": [
     {
-      "metric": 20, 
+      "metric": 10, 
       "nexthops": [
         {
           "active": true, 
index 88a91749c21ccf7b5f5c3be2a4568c1f67672247..702a83fb7295fd1f8b445122b4184dadf19ed0fa 100644 (file)
@@ -2,7 +2,7 @@
   "2001:db8:1:1::/64": [
     {
       "distance": 115, 
-      "metric": 30, 
+      "metric": 20, 
       "nexthops": [
         {
           "active": true, 
@@ -36,7 +36,7 @@
   "2001:db8:2:1::/64": [
     {
       "distance": 115, 
-      "metric": 20, 
+      "metric": 10, 
       "nexthops": [
         {
           "active": true, 
index 34f5ac9ca41353b46c7777fe052641dc59ab891d..d40008aa3013529513175a5efd179ee21d005c48 100644 (file)
@@ -21,7 +21,7 @@
         },
         {
           "interface": "r4-eth1",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r5",
           "parent": "r5(4)",
           "type": "IP TE",
@@ -29,7 +29,7 @@
         },
         {
           "interface": "r4-eth1",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r5",
           "parent": "r5(4)",
           "type": "IP TE",
@@ -37,7 +37,7 @@
         },
         {
           "interface": "r4-eth1",
-          "metric": "30",
+          "metric": "20",
           "next-hop": "r5",
           "parent": "r3(4)",
           "type": "IP TE",
           "vertex": "r5"
         },
         {
+          "metric": "10",
           "interface": "r4-eth1",
-          "metric": "20",
           "next-hop": "r5",
           "parent": "r5(4)",
           "type": "IP6 internal",
           "vertex": "2001:db8:2:1::/64"
         },
         {
+          "metric": "20",
           "interface": "r4-eth1",
-          "metric": "30",
           "next-hop": "r5",
           "parent": "r3(4)",
           "type": "IP6 internal",
         },
         {
           "interface": "r4-eth0",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r2",
           "parent": "r2(4)",
           "type": "IP TE",
index 5efa36bce678837a6c62b130cadbcb76b6924cc3..a254b6fdd5de651a2520f936c597359ebf7e3f5a 100644 (file)
@@ -2,7 +2,7 @@
   "10.0.10.0/24": [
     {
       "distance": 115, 
-      "metric": 20, 
+      "metric": 10, 
       "nexthops": [
         {
           "afi": "ipv4", 
index 5e8f6364af4d838369eeb6ad3ecc79b836e58eba..06fc78f70383634624b866d70b26a2b4b8d01044 100644 (file)
@@ -2,7 +2,7 @@
   "2001:db8:1:1::/64": [
     {
       "distance": 115, 
-      "metric": 20, 
+      "metric": 10, 
       "nexthops": [
         {
           "active": true, 
@@ -20,7 +20,7 @@
   "2001:db8:1:2::/64": [
     {
       "distance": 115, 
-      "metric": 20, 
+      "metric": 10, 
       "nexthops": [
         {
           "active": true, 
index ace56536e9f34c09bef7d361839a1b646923564b..2a088cae306119398ef345cfaec0a162384356b4 100644 (file)
@@ -35,7 +35,7 @@
         },
         {
           "interface": "r5-eth0",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r3",
           "parent": "r3(4)",
           "type": "IP TE",
@@ -43,7 +43,7 @@
         },
         {
           "interface": "r5-eth0",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r3",
           "parent": "r3(4)",
           "type": "IP TE",
@@ -51,7 +51,7 @@
         },
         {
           "interface": "r5-eth1",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r4",
           "parent": "r4(4)",
           "type": "IP TE",
@@ -59,7 +59,7 @@
         },
         {
           "interface": "r5-eth1",
-          "metric": "20",
+          "metric": "10",
           "next-hop": "r4",
           "parent": "r4(4)",
           "type": "IP TE",
           "vertex": "r4"
         },
         {
+          "metric": "10",
           "interface": "r5-eth0",
-          "metric": "20",
           "next-hop": "r3",
           "parent": "r3(4)",
           "type": "IP6 internal",
           "vertex": "2001:db8:1:1::/64"
         },
         {
+          "metric": "10",
           "interface": "r5-eth1",
-          "metric": "20",
           "next-hop": "r4",
           "parent": "r4(4)",
           "type": "IP6 internal",