]> git.proxmox.com Git - mirror_frr.git/blobdiff - ripd/rip_northbound.c
Merge pull request #4690 from donaldsharp/staticstuff
[mirror_frr.git] / ripd / rip_northbound.c
index 1e5f86eff80950eb22609b675fe25bea2d6a0bf9..1238d0f0fc8b4ff50e85d78f8e4305767bd92a0a 100644 (file)
@@ -31,7 +31,9 @@
 #include "libfrr.h"
 
 #include "ripd/ripd.h"
+#include "ripd/rip_debug.h"
 #include "ripd/rip_cli.h"
+#include "ripd/rip_interface.h"
 
 /*
  * XPath: /frr-ripd:ripd/instance
@@ -40,41 +42,97 @@ static int ripd_instance_create(enum nb_event event,
                                const struct lyd_node *dnode,
                                union nb_resource *resource)
 {
+       struct rip *rip;
+       struct vrf *vrf;
+       const char *vrf_name;
        int socket;
 
+       vrf_name = yang_dnode_get_string(dnode, "./vrf");
+       vrf = vrf_lookup_by_name(vrf_name);
+
+       /*
+        * Try to create a RIP socket only if the VRF is enabled, otherwise
+        * create a disabled RIP instance and wait for the VRF to be enabled.
+        */
        switch (event) {
        case NB_EV_VALIDATE:
                break;
        case NB_EV_PREPARE:
-               socket = rip_create_socket();
+               if (!vrf || !vrf_is_enabled(vrf))
+                       break;
+
+               socket = rip_create_socket(vrf);
                if (socket < 0)
                        return NB_ERR_RESOURCE;
                resource->fd = socket;
                break;
        case NB_EV_ABORT:
+               if (!vrf || !vrf_is_enabled(vrf))
+                       break;
+
                socket = resource->fd;
                close(socket);
                break;
        case NB_EV_APPLY:
-               socket = resource->fd;
-               rip_create(socket);
+               if (vrf && vrf_is_enabled(vrf))
+                       socket = resource->fd;
+               else
+                       socket = -1;
+
+               rip = rip_create(vrf_name, vrf, socket);
+               nb_running_set_entry(dnode, rip);
                break;
        }
 
        return NB_OK;
 }
 
-static int ripd_instance_delete(enum nb_event event,
-                               const struct lyd_node *dnode)
+static int ripd_instance_destroy(enum nb_event event,
+                                const struct lyd_node *dnode)
 {
+       struct rip *rip;
+
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       rip_clean();
+       rip = nb_running_unset_entry(dnode);
+       rip_clean(rip);
+
+       return NB_OK;
+}
+
+static const void *ripd_instance_get_next(const void *parent_list_entry,
+                                         const void *list_entry)
+{
+       struct rip *rip = (struct rip *)list_entry;
+
+       if (list_entry == NULL)
+               rip = RB_MIN(rip_instance_head, &rip_instances);
+       else
+               rip = RB_NEXT(rip_instance_head, rip);
+
+       return rip;
+}
+
+static int ripd_instance_get_keys(const void *list_entry,
+                                 struct yang_list_keys *keys)
+{
+       const struct rip *rip = list_entry;
+
+       keys->num = 1;
+       strlcpy(keys->key[0], rip->vrf_name, sizeof(keys->key[0]));
 
        return NB_OK;
 }
 
+static const void *ripd_instance_lookup_entry(const void *parent_list_entry,
+                                             const struct yang_list_keys *keys)
+{
+       const char *vrf_name = keys->key[0];
+
+       return rip_lookup_by_vrf_name(vrf_name);
+}
+
 /*
  * XPath: /frr-ripd:ripd/instance/allow-ecmp
  */
@@ -82,12 +140,15 @@ static int ripd_instance_allow_ecmp_modify(enum nb_event event,
                                           const struct lyd_node *dnode,
                                           union nb_resource *resource)
 {
+       struct rip *rip;
+
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        rip->ecmp = yang_dnode_get_bool(dnode, NULL);
        if (!rip->ecmp)
-               rip_ecmp_disable();
+               rip_ecmp_disable(rip);
 
        return NB_OK;
 }
@@ -100,12 +161,14 @@ ripd_instance_default_information_originate_modify(enum nb_event event,
                                                   const struct lyd_node *dnode,
                                                   union nb_resource *resource)
 {
+       struct rip *rip;
        bool default_information;
        struct prefix_ipv4 p;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        default_information = yang_dnode_get_bool(dnode, NULL);
 
        memset(&p, 0, sizeof(struct prefix_ipv4));
@@ -115,11 +178,11 @@ ripd_instance_default_information_originate_modify(enum nb_event event,
 
                memset(&nh, 0, sizeof(nh));
                nh.type = NEXTHOP_TYPE_IPV4;
-               rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p,
-                                    &nh, 0, 0, 0);
+               rip_redistribute_add(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT,
+                                    &p, &nh, 0, 0, 0);
        } else {
-               rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p,
-                                       0);
+               rip_redistribute_delete(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT,
+                                       &p, 0);
        }
 
        return NB_OK;
@@ -132,9 +195,12 @@ static int ripd_instance_default_metric_modify(enum nb_event event,
                                               const struct lyd_node *dnode,
                                               union nb_resource *resource)
 {
+       struct rip *rip;
+
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        rip->default_metric = yang_dnode_get_uint8(dnode, NULL);
        /* rip_update_default_metric (); */
 
@@ -148,9 +214,12 @@ static int ripd_instance_distance_default_modify(enum nb_event event,
                                                 const struct lyd_node *dnode,
                                                 union nb_resource *resource)
 {
+       struct rip *rip;
+
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        rip->distance = yang_dnode_get_uint8(dnode, NULL);
 
        return NB_OK;
@@ -163,6 +232,7 @@ static int ripd_instance_distance_source_create(enum nb_event event,
                                                const struct lyd_node *dnode,
                                                union nb_resource *resource)
 {
+       struct rip *rip;
        struct prefix_ipv4 prefix;
        struct route_node *rn;
 
@@ -173,15 +243,16 @@ static int ripd_instance_distance_source_create(enum nb_event event,
        apply_mask_ipv4(&prefix);
 
        /* Get RIP distance node. */
-       rn = route_node_get(rip_distance_table, (struct prefix *)&prefix);
+       rip = nb_running_get_entry(dnode, NULL, true);
+       rn = route_node_get(rip->distance_table, (struct prefix *)&prefix);
        rn->info = rip_distance_new();
-       yang_dnode_set_entry(dnode, rn);
+       nb_running_set_entry(dnode, rn);
 
        return NB_OK;
 }
 
-static int ripd_instance_distance_source_delete(enum nb_event event,
-                                               const struct lyd_node *dnode)
+static int ripd_instance_distance_source_destroy(enum nb_event event,
+                                                const struct lyd_node *dnode)
 {
        struct route_node *rn;
        struct rip_distance *rdistance;
@@ -189,12 +260,9 @@ static int ripd_instance_distance_source_delete(enum nb_event event,
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       rn = yang_dnode_get_entry(dnode, true);
+       rn = nb_running_unset_entry(dnode);
        rdistance = rn->info;
-       if (rdistance->access_list)
-               free(rdistance->access_list);
        rip_distance_free(rdistance);
-
        rn->info = NULL;
        route_unlock_node(rn);
 
@@ -217,7 +285,7 @@ ripd_instance_distance_source_distance_modify(enum nb_event event,
                return NB_OK;
 
        /* Set distance value. */
-       rn = yang_dnode_get_entry(dnode, true);
+       rn = nb_running_get_entry(dnode, NULL, true);
        distance = yang_dnode_get_uint8(dnode, NULL);
        rdistance = rn->info;
        rdistance->distance = distance;
@@ -243,7 +311,7 @@ ripd_instance_distance_source_access_list_modify(enum nb_event event,
        acl_name = yang_dnode_get_string(dnode, NULL);
 
        /* Set access-list */
-       rn = yang_dnode_get_entry(dnode, true);
+       rn = nb_running_get_entry(dnode, NULL, true);
        rdistance = rn->info;
        if (rdistance->access_list)
                free(rdistance->access_list);
@@ -253,8 +321,8 @@ ripd_instance_distance_source_access_list_modify(enum nb_event event,
 }
 
 static int
-ripd_instance_distance_source_access_list_delete(enum nb_event event,
-                                                const struct lyd_node *dnode)
+ripd_instance_distance_source_access_list_destroy(enum nb_event event,
+                                                 const struct lyd_node *dnode)
 {
        struct route_node *rn;
        struct rip_distance *rdistance;
@@ -263,7 +331,7 @@ ripd_instance_distance_source_access_list_delete(enum nb_event event,
                return NB_OK;
 
        /* Reset access-list configuration. */
-       rn = yang_dnode_get_entry(dnode, true);
+       rn = nb_running_get_entry(dnode, NULL, true);
        rdistance = rn->info;
        free(rdistance->access_list);
        rdistance->access_list = NULL;
@@ -278,31 +346,35 @@ static int ripd_instance_explicit_neighbor_create(enum nb_event event,
                                                  const struct lyd_node *dnode,
                                                  union nb_resource *resource)
 {
+       struct rip *rip;
        struct prefix_ipv4 p;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        p.family = AF_INET;
        p.prefixlen = IPV4_MAX_BITLEN;
        yang_dnode_get_ipv4(&p.prefix, dnode, NULL);
 
-       return rip_neighbor_add(&p);
+       return rip_neighbor_add(rip, &p);
 }
 
-static int ripd_instance_explicit_neighbor_delete(enum nb_event event,
-                                                 const struct lyd_node *dnode)
+static int ripd_instance_explicit_neighbor_destroy(enum nb_event event,
+                                                  const struct lyd_node *dnode)
 {
+       struct rip *rip;
        struct prefix_ipv4 p;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        p.family = AF_INET;
        p.prefixlen = IPV4_MAX_BITLEN;
        yang_dnode_get_ipv4(&p.prefix, dnode, NULL);
 
-       return rip_neighbor_delete(&p);
+       return rip_neighbor_delete(rip, &p);
 }
 
 /*
@@ -312,29 +384,33 @@ static int ripd_instance_network_create(enum nb_event event,
                                        const struct lyd_node *dnode,
                                        union nb_resource *resource)
 {
+       struct rip *rip;
        struct prefix p;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        yang_dnode_get_ipv4p(&p, dnode, NULL);
        apply_mask_ipv4((struct prefix_ipv4 *)&p);
 
-       return rip_enable_network_add(&p);
+       return rip_enable_network_add(rip, &p);
 }
 
-static int ripd_instance_network_delete(enum nb_event event,
-                                       const struct lyd_node *dnode)
+static int ripd_instance_network_destroy(enum nb_event event,
+                                        const struct lyd_node *dnode)
 {
+       struct rip *rip;
        struct prefix p;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        yang_dnode_get_ipv4p(&p, dnode, NULL);
        apply_mask_ipv4((struct prefix_ipv4 *)&p);
 
-       return rip_enable_network_delete(&p);
+       return rip_enable_network_delete(rip, &p);
 }
 
 /*
@@ -344,27 +420,31 @@ static int ripd_instance_interface_create(enum nb_event event,
                                          const struct lyd_node *dnode,
                                          union nb_resource *resource)
 {
+       struct rip *rip;
        const char *ifname;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        ifname = yang_dnode_get_string(dnode, NULL);
 
-       return rip_enable_if_add(ifname);
+       return rip_enable_if_add(rip, ifname);
 }
 
-static int ripd_instance_interface_delete(enum nb_event event,
-                                         const struct lyd_node *dnode)
+static int ripd_instance_interface_destroy(enum nb_event event,
+                                          const struct lyd_node *dnode)
 {
+       struct rip *rip;
        const char *ifname;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        ifname = yang_dnode_get_string(dnode, NULL);
 
-       return rip_enable_if_delete(ifname);
+       return rip_enable_if_delete(rip, ifname);
 }
 
 /*
@@ -374,22 +454,24 @@ static int ripd_instance_offset_list_create(enum nb_event event,
                                            const struct lyd_node *dnode,
                                            union nb_resource *resource)
 {
+       struct rip *rip;
        const char *ifname;
        struct rip_offset_list *offset;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        ifname = yang_dnode_get_string(dnode, "./interface");
 
-       offset = rip_offset_list_new(ifname);
-       yang_dnode_set_entry(dnode, offset);
+       offset = rip_offset_list_new(rip, ifname);
+       nb_running_set_entry(dnode, offset);
 
        return NB_OK;
 }
 
-static int ripd_instance_offset_list_delete(enum nb_event event,
-                                           const struct lyd_node *dnode)
+static int ripd_instance_offset_list_destroy(enum nb_event event,
+                                            const struct lyd_node *dnode)
 {
        int direct;
        struct rip_offset_list *offset;
@@ -399,7 +481,7 @@ static int ripd_instance_offset_list_delete(enum nb_event event,
 
        direct = yang_dnode_get_enum(dnode, "./direction");
 
-       offset = yang_dnode_get_entry(dnode, true);
+       offset = nb_running_unset_entry(dnode);
        if (offset->direct[direct].alist_name) {
                free(offset->direct[direct].alist_name);
                offset->direct[direct].alist_name = NULL;
@@ -429,7 +511,7 @@ ripd_instance_offset_list_access_list_modify(enum nb_event event,
        direct = yang_dnode_get_enum(dnode, "../direction");
        alist_name = yang_dnode_get_string(dnode, NULL);
 
-       offset = yang_dnode_get_entry(dnode, true);
+       offset = nb_running_get_entry(dnode, NULL, true);
        if (offset->direct[direct].alist_name)
                free(offset->direct[direct].alist_name);
        offset->direct[direct].alist_name = strdup(alist_name);
@@ -454,7 +536,7 @@ static int ripd_instance_offset_list_metric_modify(enum nb_event event,
        direct = yang_dnode_get_enum(dnode, "../direction");
        metric = yang_dnode_get_uint8(dnode, NULL);
 
-       offset = yang_dnode_get_entry(dnode, true);
+       offset = nb_running_get_entry(dnode, NULL, true);
        offset->direct[direct].metric = metric;
 
        return NB_OK;
@@ -467,11 +549,14 @@ static int ripd_instance_passive_default_modify(enum nb_event event,
                                                const struct lyd_node *dnode,
                                                union nb_resource *resource)
 {
+       struct rip *rip;
+
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        rip->passive_default = yang_dnode_get_bool(dnode, NULL);
-       rip_passive_nondefault_clean();
+       rip_passive_nondefault_clean(rip);
 
        return NB_OK;
 }
@@ -483,27 +568,31 @@ static int ripd_instance_passive_interface_create(enum nb_event event,
                                                  const struct lyd_node *dnode,
                                                  union nb_resource *resource)
 {
+       struct rip *rip;
        const char *ifname;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        ifname = yang_dnode_get_string(dnode, NULL);
 
-       return rip_passive_nondefault_set(ifname);
+       return rip_passive_nondefault_set(rip, ifname);
 }
 
-static int ripd_instance_passive_interface_delete(enum nb_event event,
-                                                 const struct lyd_node *dnode)
+static int ripd_instance_passive_interface_destroy(enum nb_event event,
+                                                  const struct lyd_node *dnode)
 {
+       struct rip *rip;
        const char *ifname;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        ifname = yang_dnode_get_string(dnode, NULL);
 
-       return rip_passive_nondefault_unset(ifname);
+       return rip_passive_nondefault_unset(rip, ifname);
 }
 
 /*
@@ -514,28 +603,32 @@ ripd_instance_non_passive_interface_create(enum nb_event event,
                                           const struct lyd_node *dnode,
                                           union nb_resource *resource)
 {
+       struct rip *rip;
        const char *ifname;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        ifname = yang_dnode_get_string(dnode, NULL);
 
-       return rip_passive_nondefault_unset(ifname);
+       return rip_passive_nondefault_unset(rip, ifname);
 }
 
 static int
-ripd_instance_non_passive_interface_delete(enum nb_event event,
-                                          const struct lyd_node *dnode)
+ripd_instance_non_passive_interface_destroy(enum nb_event event,
+                                           const struct lyd_node *dnode)
 {
+       struct rip *rip;
        const char *ifname;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        ifname = yang_dnode_get_string(dnode, NULL);
 
-       return rip_passive_nondefault_set(ifname);
+       return rip_passive_nondefault_set(rip, ifname);
 }
 
 /*
@@ -545,20 +638,43 @@ static int ripd_instance_redistribute_create(enum nb_event event,
                                             const struct lyd_node *dnode,
                                             union nb_resource *resource)
 {
+       struct rip *rip;
+       int type;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       rip = nb_running_get_entry(dnode, NULL, true);
+       type = yang_dnode_get_enum(dnode, "./protocol");
+
+       rip->redist[type].enabled = true;
+
        return NB_OK;
 }
 
-static int ripd_instance_redistribute_delete(enum nb_event event,
-                                            const struct lyd_node *dnode)
+static int ripd_instance_redistribute_destroy(enum nb_event event,
+                                             const struct lyd_node *dnode)
 {
+       struct rip *rip;
        int type;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        type = yang_dnode_get_enum(dnode, "./protocol");
 
-       rip_redistribute_conf_delete(type);
+       rip->redist[type].enabled = false;
+       if (rip->redist[type].route_map.name) {
+               free(rip->redist[type].route_map.name);
+               rip->redist[type].route_map.name = NULL;
+               rip->redist[type].route_map.map = NULL;
+       }
+       rip->redist[type].metric_config = false;
+       rip->redist[type].metric = 0;
+
+       if (rip->enabled)
+               rip_redistribute_conf_delete(rip, type);
 
        return NB_OK;
 }
@@ -566,10 +682,14 @@ static int ripd_instance_redistribute_delete(enum nb_event event,
 static void
 ripd_instance_redistribute_apply_finish(const struct lyd_node *dnode)
 {
+       struct rip *rip;
        int type;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        type = yang_dnode_get_enum(dnode, "./protocol");
-       rip_redistribute_conf_update(type);
+
+       if (rip->enabled)
+               rip_redistribute_conf_update(rip, type);
 }
 
 /*
@@ -580,37 +700,41 @@ ripd_instance_redistribute_route_map_modify(enum nb_event event,
                                            const struct lyd_node *dnode,
                                            union nb_resource *resource)
 {
+       struct rip *rip;
        int type;
        const char *rmap_name;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        type = yang_dnode_get_enum(dnode, "../protocol");
        rmap_name = yang_dnode_get_string(dnode, NULL);
 
-       if (rip->route_map[type].name)
-               free(rip->route_map[type].name);
-       rip->route_map[type].name = strdup(rmap_name);
-       rip->route_map[type].map = route_map_lookup_by_name(rmap_name);
+       if (rip->redist[type].route_map.name)
+               free(rip->redist[type].route_map.name);
+       rip->redist[type].route_map.name = strdup(rmap_name);
+       rip->redist[type].route_map.map = route_map_lookup_by_name(rmap_name);
 
        return NB_OK;
 }
 
 static int
-ripd_instance_redistribute_route_map_delete(enum nb_event event,
-                                           const struct lyd_node *dnode)
+ripd_instance_redistribute_route_map_destroy(enum nb_event event,
+                                            const struct lyd_node *dnode)
 {
+       struct rip *rip;
        int type;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        type = yang_dnode_get_enum(dnode, "../protocol");
 
-       free(rip->route_map[type].name);
-       rip->route_map[type].name = NULL;
-       rip->route_map[type].map = NULL;
+       free(rip->redist[type].route_map.name);
+       rip->redist[type].route_map.name = NULL;
+       rip->redist[type].route_map.map = NULL;
 
        return NB_OK;
 }
@@ -623,34 +747,38 @@ ripd_instance_redistribute_metric_modify(enum nb_event event,
                                         const struct lyd_node *dnode,
                                         union nb_resource *resource)
 {
+       struct rip *rip;
        int type;
        uint8_t metric;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        type = yang_dnode_get_enum(dnode, "../protocol");
        metric = yang_dnode_get_uint8(dnode, NULL);
 
-       rip->route_map[type].metric_config = true;
-       rip->route_map[type].metric = metric;
+       rip->redist[type].metric_config = true;
+       rip->redist[type].metric = metric;
 
        return NB_OK;
 }
 
 static int
-ripd_instance_redistribute_metric_delete(enum nb_event event,
-                                        const struct lyd_node *dnode)
+ripd_instance_redistribute_metric_destroy(enum nb_event event,
+                                         const struct lyd_node *dnode)
 {
+       struct rip *rip;
        int type;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        type = yang_dnode_get_enum(dnode, "../protocol");
 
-       rip->route_map[type].metric_config = false;
-       rip->route_map[type].metric = 0;
+       rip->redist[type].metric_config = false;
+       rip->redist[type].metric = 0;
 
        return NB_OK;
 }
@@ -662,35 +790,39 @@ static int ripd_instance_static_route_create(enum nb_event event,
                                             const struct lyd_node *dnode,
                                             union nb_resource *resource)
 {
+       struct rip *rip;
        struct nexthop nh;
        struct prefix_ipv4 p;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        yang_dnode_get_ipv4p(&p, dnode, NULL);
        apply_mask_ipv4(&p);
 
        memset(&nh, 0, sizeof(nh));
        nh.type = NEXTHOP_TYPE_IPV4;
-       rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, &nh, 0, 0,
-                            0);
+       rip_redistribute_add(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, &nh, 0,
+                            0, 0);
 
        return NB_OK;
 }
 
-static int ripd_instance_static_route_delete(enum nb_event event,
-                                            const struct lyd_node *dnode)
+static int ripd_instance_static_route_destroy(enum nb_event event,
+                                             const struct lyd_node *dnode)
 {
+       struct rip *rip;
        struct prefix_ipv4 p;
 
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        yang_dnode_get_ipv4p(&p, dnode, NULL);
        apply_mask_ipv4(&p);
 
-       rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
+       rip_redistribute_delete(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
 
        return NB_OK;
 }
@@ -700,8 +832,12 @@ static int ripd_instance_static_route_delete(enum nb_event event,
  */
 static void ripd_instance_timers_apply_finish(const struct lyd_node *dnode)
 {
+       struct rip *rip;
+
+       rip = nb_running_get_entry(dnode, NULL, true);
+
        /* Reset update timer thread. */
-       rip_event(RIP_UPDATE_EVENT, 0);
+       rip_event(rip, RIP_UPDATE_EVENT, 0);
 }
 
 /*
@@ -712,9 +848,12 @@ ripd_instance_timers_flush_interval_modify(enum nb_event event,
                                           const struct lyd_node *dnode,
                                           union nb_resource *resource)
 {
+       struct rip *rip;
+
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        rip->garbage_time = yang_dnode_get_uint32(dnode, NULL);
 
        return NB_OK;
@@ -728,9 +867,12 @@ ripd_instance_timers_holddown_interval_modify(enum nb_event event,
                                              const struct lyd_node *dnode,
                                              union nb_resource *resource)
 {
+       struct rip *rip;
+
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        rip->timeout_time = yang_dnode_get_uint32(dnode, NULL);
 
        return NB_OK;
@@ -744,9 +886,12 @@ ripd_instance_timers_update_interval_modify(enum nb_event event,
                                            const struct lyd_node *dnode,
                                            union nb_resource *resource)
 {
+       struct rip *rip;
+
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        rip->update_time = yang_dnode_get_uint32(dnode, NULL);
 
        return NB_OK;
@@ -759,9 +904,12 @@ static int ripd_instance_version_receive_modify(enum nb_event event,
                                                const struct lyd_node *dnode,
                                                union nb_resource *resource)
 {
+       struct rip *rip;
+
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        rip->version_recv = yang_dnode_get_enum(dnode, NULL);
 
        return NB_OK;
@@ -774,9 +922,12 @@ static int ripd_instance_version_send_modify(enum nb_event event,
                                             const struct lyd_node *dnode,
                                             union nb_resource *resource)
 {
+       struct rip *rip;
+
        if (event != NB_EV_APPLY)
                return NB_OK;
 
+       rip = nb_running_get_entry(dnode, NULL, true);
        rip->version_send = yang_dnode_get_enum(dnode, NULL);
 
        return NB_OK;
@@ -795,7 +946,7 @@ static int lib_interface_rip_split_horizon_modify(enum nb_event event,
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode, true);
+       ifp = nb_running_get_entry(dnode, NULL, true);
        ri = ifp->info;
        ri->split_horizon = yang_dnode_get_enum(dnode, NULL);
 
@@ -815,7 +966,7 @@ static int lib_interface_rip_v2_broadcast_modify(enum nb_event event,
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode, true);
+       ifp = nb_running_get_entry(dnode, NULL, true);
        ri = ifp->info;
        ri->v2_broadcast = yang_dnode_get_bool(dnode, NULL);
 
@@ -836,7 +987,7 @@ lib_interface_rip_version_receive_modify(enum nb_event event,
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode, true);
+       ifp = nb_running_get_entry(dnode, NULL, true);
        ri = ifp->info;
        ri->ri_receive = yang_dnode_get_enum(dnode, NULL);
 
@@ -856,7 +1007,7 @@ static int lib_interface_rip_version_send_modify(enum nb_event event,
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode, true);
+       ifp = nb_running_get_entry(dnode, NULL, true);
        ri = ifp->info;
        ri->ri_send = yang_dnode_get_enum(dnode, NULL);
 
@@ -876,7 +1027,7 @@ static int lib_interface_rip_authentication_scheme_mode_modify(
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode, true);
+       ifp = nb_running_get_entry(dnode, NULL, true);
        ri = ifp->info;
        ri->auth_type = yang_dnode_get_enum(dnode, NULL);
 
@@ -897,14 +1048,14 @@ static int lib_interface_rip_authentication_scheme_md5_auth_length_modify(
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode, true);
+       ifp = nb_running_get_entry(dnode, NULL, true);
        ri = ifp->info;
        ri->md5_auth_len = yang_dnode_get_enum(dnode, NULL);
 
        return NB_OK;
 }
 
-static int lib_interface_rip_authentication_scheme_md5_auth_length_delete(
+static int lib_interface_rip_authentication_scheme_md5_auth_length_destroy(
        enum nb_event event, const struct lyd_node *dnode)
 {
        struct interface *ifp;
@@ -913,7 +1064,7 @@ static int lib_interface_rip_authentication_scheme_md5_auth_length_delete(
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode, true);
+       ifp = nb_running_get_entry(dnode, NULL, true);
        ri = ifp->info;
        ri->md5_auth_len = yang_get_default_enum(
                "%s/authentication-scheme/md5-auth-length", RIP_IFACE);
@@ -935,10 +1086,9 @@ lib_interface_rip_authentication_password_modify(enum nb_event event,
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode, true);
+       ifp = nb_running_get_entry(dnode, NULL, true);
        ri = ifp->info;
-       if (ri->auth_str)
-               XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
+       XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
        ri->auth_str = XSTRDUP(MTYPE_RIP_INTERFACE_STRING,
                               yang_dnode_get_string(dnode, NULL));
 
@@ -946,8 +1096,8 @@ lib_interface_rip_authentication_password_modify(enum nb_event event,
 }
 
 static int
-lib_interface_rip_authentication_password_delete(enum nb_event event,
-                                                const struct lyd_node *dnode)
+lib_interface_rip_authentication_password_destroy(enum nb_event event,
+                                                 const struct lyd_node *dnode)
 {
        struct interface *ifp;
        struct rip_interface *ri;
@@ -955,7 +1105,7 @@ lib_interface_rip_authentication_password_delete(enum nb_event event,
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode, true);
+       ifp = nb_running_get_entry(dnode, NULL, true);
        ri = ifp->info;
        XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
 
@@ -976,10 +1126,9 @@ lib_interface_rip_authentication_key_chain_modify(enum nb_event event,
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode, true);
+       ifp = nb_running_get_entry(dnode, NULL, true);
        ri = ifp->info;
-       if (ri->key_chain)
-               XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
+       XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
        ri->key_chain = XSTRDUP(MTYPE_RIP_INTERFACE_STRING,
                                yang_dnode_get_string(dnode, NULL));
 
@@ -987,8 +1136,8 @@ lib_interface_rip_authentication_key_chain_modify(enum nb_event event,
 }
 
 static int
-lib_interface_rip_authentication_key_chain_delete(enum nb_event event,
-                                                 const struct lyd_node *dnode)
+lib_interface_rip_authentication_key_chain_destroy(enum nb_event event,
+                                                  const struct lyd_node *dnode)
 {
        struct interface *ifp;
        struct rip_interface *ri;
@@ -996,7 +1145,7 @@ lib_interface_rip_authentication_key_chain_delete(enum nb_event event,
        if (event != NB_EV_APPLY)
                return NB_OK;
 
-       ifp = yang_dnode_get_entry(dnode, true);
+       ifp = nb_running_get_entry(dnode, NULL, true);
        ri = ifp->info;
        XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
 
@@ -1004,24 +1153,26 @@ lib_interface_rip_authentication_key_chain_delete(enum nb_event event,
 }
 
 /*
- * XPath: /frr-ripd:ripd/state/neighbors/neighbor
+ * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor
  */
 static const void *
-ripd_state_neighbors_neighbor_get_next(const void *parent_list_entry,
-                                      const void *list_entry)
+ripd_instance_state_neighbors_neighbor_get_next(const void *parent_list_entry,
+                                               const void *list_entry)
 {
+       const struct rip *rip = parent_list_entry;
        struct listnode *node;
 
        if (list_entry == NULL)
-               node = listhead(peer_list);
+               node = listhead(rip->peer_list);
        else
                node = listnextnode((struct listnode *)list_entry);
 
        return node;
 }
 
-static int ripd_state_neighbors_neighbor_get_keys(const void *list_entry,
-                                                 struct yang_list_keys *keys)
+static int
+ripd_instance_state_neighbors_neighbor_get_keys(const void *list_entry,
+                                               struct yang_list_keys *keys)
 {
        const struct listnode *node = list_entry;
        const struct rip_peer *peer = listgetdata(node);
@@ -1033,17 +1184,17 @@ static int ripd_state_neighbors_neighbor_get_keys(const void *list_entry,
        return NB_OK;
 }
 
-static const void *
-ripd_state_neighbors_neighbor_lookup_entry(const void *parent_list_entry,
-                                          const struct yang_list_keys *keys)
+static const void *ripd_instance_state_neighbors_neighbor_lookup_entry(
+       const void *parent_list_entry, const struct yang_list_keys *keys)
 {
+       const struct rip *rip = parent_list_entry;
        struct in_addr address;
        struct rip_peer *peer;
        struct listnode *node;
 
        yang_str2ipv4(keys->key[0], &address);
 
-       for (ALL_LIST_ELEMENTS_RO(peer_list, node, peer)) {
+       for (ALL_LIST_ELEMENTS_RO(rip->peer_list, node, peer)) {
                if (IPV4_ADDR_SAME(&peer->addr, &address))
                        return node;
        }
@@ -1052,11 +1203,11 @@ ripd_state_neighbors_neighbor_lookup_entry(const void *parent_list_entry,
 }
 
 /*
- * XPath: /frr-ripd:ripd/state/neighbors/neighbor/address
+ * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/address
  */
 static struct yang_data *
-ripd_state_neighbors_neighbor_address_get_elem(const char *xpath,
-                                              const void *list_entry)
+ripd_instance_state_neighbors_neighbor_address_get_elem(const char *xpath,
+                                                       const void *list_entry)
 {
        const struct listnode *node = list_entry;
        const struct rip_peer *peer = listgetdata(node);
@@ -1065,22 +1216,22 @@ ripd_state_neighbors_neighbor_address_get_elem(const char *xpath,
 }
 
 /*
- * XPath: /frr-ripd:ripd/state/neighbors/neighbor/last-update
+ * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/last-update
  */
 static struct yang_data *
-ripd_state_neighbors_neighbor_last_update_get_elem(const char *xpath,
-                                                  const void *list_entry)
+ripd_instance_state_neighbors_neighbor_last_update_get_elem(
+       const char *xpath, const void *list_entry)
 {
        /* TODO: yang:date-and-time is tricky */
        return NULL;
 }
 
 /*
- * XPath: /frr-ripd:ripd/state/neighbors/neighbor/bad-packets-rcvd
+ * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-packets-rcvd
  */
 static struct yang_data *
-ripd_state_neighbors_neighbor_bad_packets_rcvd_get_elem(const char *xpath,
-                                                       const void *list_entry)
+ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
+       const char *xpath, const void *list_entry)
 {
        const struct listnode *node = list_entry;
        const struct rip_peer *peer = listgetdata(node);
@@ -1089,11 +1240,11 @@ ripd_state_neighbors_neighbor_bad_packets_rcvd_get_elem(const char *xpath,
 }
 
 /*
- * XPath: /frr-ripd:ripd/state/neighbors/neighbor/bad-routes-rcvd
+ * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-routes-rcvd
  */
 static struct yang_data *
-ripd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath,
-                                                      const void *list_entry)
+ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem(
+       const char *xpath, const void *list_entry)
 {
        const struct listnode *node = list_entry;
        const struct rip_peer *peer = listgetdata(node);
@@ -1102,17 +1253,15 @@ ripd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath,
 }
 
 /*
- * XPath: /frr-ripd:ripd/state/routes/route
+ * XPath: /frr-ripd:ripd/instance/state/routes/route
  */
 static const void *
-ripd_state_routes_route_get_next(const void *parent_list_entry,
-                                const void *list_entry)
+ripd_instance_state_routes_route_get_next(const void *parent_list_entry,
+                                         const void *list_entry)
 {
+       const struct rip *rip = parent_list_entry;
        struct route_node *rn;
 
-       if (rip == NULL)
-               return NULL;
-
        if (list_entry == NULL)
                rn = route_top(rip->table);
        else
@@ -1123,8 +1272,9 @@ ripd_state_routes_route_get_next(const void *parent_list_entry,
        return rn;
 }
 
-static int ripd_state_routes_route_get_keys(const void *list_entry,
-                                           struct yang_list_keys *keys)
+static int
+ripd_instance_state_routes_route_get_keys(const void *list_entry,
+                                         struct yang_list_keys *keys)
 {
        const struct route_node *rn = list_entry;
 
@@ -1135,9 +1285,10 @@ static int ripd_state_routes_route_get_keys(const void *list_entry,
 }
 
 static const void *
-ripd_state_routes_route_lookup_entry(const void *parent_list_entry,
-                                    const struct yang_list_keys *keys)
+ripd_instance_state_routes_route_lookup_entry(const void *parent_list_entry,
+                                             const struct yang_list_keys *keys)
 {
+       const struct rip *rip = parent_list_entry;
        struct prefix prefix;
        struct route_node *rn;
 
@@ -1153,11 +1304,11 @@ ripd_state_routes_route_lookup_entry(const void *parent_list_entry,
 }
 
 /*
- * XPath: /frr-ripd:ripd/state/routes/route/prefix
+ * XPath: /frr-ripd:ripd/instance/state/routes/route/prefix
  */
 static struct yang_data *
-ripd_state_routes_route_prefix_get_elem(const char *xpath,
-                                       const void *list_entry)
+ripd_instance_state_routes_route_prefix_get_elem(const char *xpath,
+                                                const void *list_entry)
 {
        const struct route_node *rn = list_entry;
        const struct rip_info *rinfo = listnode_head(rn->info);
@@ -1166,11 +1317,11 @@ ripd_state_routes_route_prefix_get_elem(const char *xpath,
 }
 
 /*
- * XPath: /frr-ripd:ripd/state/routes/route/next-hop
+ * XPath: /frr-ripd:ripd/instance/state/routes/route/next-hop
  */
 static struct yang_data *
-ripd_state_routes_route_next_hop_get_elem(const char *xpath,
-                                         const void *list_entry)
+ripd_instance_state_routes_route_next_hop_get_elem(const char *xpath,
+                                                  const void *list_entry)
 {
        const struct route_node *rn = list_entry;
        const struct rip_info *rinfo = listnode_head(rn->info);
@@ -1185,31 +1336,33 @@ ripd_state_routes_route_next_hop_get_elem(const char *xpath,
 }
 
 /*
- * XPath: /frr-ripd:ripd/state/routes/route/interface
+ * XPath: /frr-ripd:ripd/instance/state/routes/route/interface
  */
 static struct yang_data *
-ripd_state_routes_route_interface_get_elem(const char *xpath,
-                                          const void *list_entry)
+ripd_instance_state_routes_route_interface_get_elem(const char *xpath,
+                                                   const void *list_entry)
 {
        const struct route_node *rn = list_entry;
        const struct rip_info *rinfo = listnode_head(rn->info);
+       const struct rip *rip = rip_info_get_instance(rinfo);
 
        switch (rinfo->nh.type) {
        case NEXTHOP_TYPE_IFINDEX:
        case NEXTHOP_TYPE_IPV4_IFINDEX:
                return yang_data_new_string(
-                       xpath, ifindex2ifname(rinfo->nh.ifindex, VRF_DEFAULT));
+                       xpath,
+                       ifindex2ifname(rinfo->nh.ifindex, rip->vrf->vrf_id));
        default:
                return NULL;
        }
 }
 
 /*
- * XPath: /frr-ripd:ripd/state/routes/route/metric
+ * XPath: /frr-ripd:ripd/instance/state/routes/route/metric
  */
 static struct yang_data *
-ripd_state_routes_route_metric_get_elem(const char *xpath,
-                                       const void *list_entry)
+ripd_instance_state_routes_route_metric_get_elem(const char *xpath,
+                                                const void *list_entry)
 {
        const struct route_node *rn = list_entry;
        const struct rip_info *rinfo = listnode_head(rn->info);
@@ -1220,16 +1373,19 @@ ripd_state_routes_route_metric_get_elem(const char *xpath,
 /*
  * XPath: /frr-ripd:clear-rip-route
  */
-static int clear_rip_route_rpc(const char *xpath, const struct list *input,
-                              struct list *output)
+static void clear_rip_route(struct rip *rip)
 {
        struct route_node *rp;
-       struct rip_info *rinfo;
-       struct list *list;
-       struct listnode *listnode;
+
+       if (IS_RIP_DEBUG_EVENT)
+               zlog_debug("Clearing all RIP routes (VRF %s)", rip->vrf_name);
 
        /* Clear received RIP routes */
        for (rp = route_top(rip->table); rp; rp = route_next(rp)) {
+               struct list *list;
+               struct listnode *listnode;
+               struct rip_info *rinfo;
+
                list = rp->info;
                if (!list)
                        continue;
@@ -1239,7 +1395,7 @@ static int clear_rip_route_rpc(const char *xpath, const struct list *input,
                                continue;
 
                        if (CHECK_FLAG(rinfo->flags, RIP_RTF_FIB))
-                               rip_zebra_ipv4_delete(rp);
+                               rip_zebra_ipv4_delete(rip, rp);
                        break;
                }
 
@@ -1256,6 +1412,30 @@ static int clear_rip_route_rpc(const char *xpath, const struct list *input,
                        route_unlock_node(rp);
                }
        }
+}
+
+static int clear_rip_route_rpc(const char *xpath, const struct list *input,
+                              struct list *output)
+{
+       struct rip *rip;
+       struct yang_data *yang_vrf;
+
+       yang_vrf = yang_data_list_find(input, "%s/%s", xpath, "input/vrf");
+       if (yang_vrf) {
+               rip = rip_lookup_by_vrf_name(yang_vrf->value);
+               if (rip)
+                       clear_rip_route(rip);
+       } else {
+               struct vrf *vrf;
+
+               RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+                       rip = vrf->info;
+                       if (!rip)
+                               continue;
+
+                       clear_rip_route(rip);
+               }
+       }
 
        return NB_OK;
 }
@@ -1304,238 +1484,337 @@ const struct frr_yang_module_info frr_ripd_info = {
        .nodes = {
                {
                        .xpath = "/frr-ripd:ripd/instance",
-                       .cbs.create = ripd_instance_create,
-                       .cbs.destroy = ripd_instance_delete,
-                       .cbs.cli_show = cli_show_router_rip,
+                       .cbs = {
+                               .cli_show = cli_show_router_rip,
+                               .create = ripd_instance_create,
+                               .destroy = ripd_instance_destroy,
+                               .get_keys = ripd_instance_get_keys,
+                               .get_next = ripd_instance_get_next,
+                               .lookup_entry = ripd_instance_lookup_entry,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/allow-ecmp",
-                       .cbs.modify = ripd_instance_allow_ecmp_modify,
-                       .cbs.cli_show = cli_show_rip_allow_ecmp,
+                       .cbs = {
+                               .cli_show = cli_show_rip_allow_ecmp,
+                               .modify = ripd_instance_allow_ecmp_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/default-information-originate",
-                       .cbs.modify = ripd_instance_default_information_originate_modify,
-                       .cbs.cli_show = cli_show_rip_default_information_originate,
+                       .cbs = {
+                               .cli_show = cli_show_rip_default_information_originate,
+                               .modify = ripd_instance_default_information_originate_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/default-metric",
-                       .cbs.modify = ripd_instance_default_metric_modify,
-                       .cbs.cli_show = cli_show_rip_default_metric,
+                       .cbs = {
+                               .cli_show = cli_show_rip_default_metric,
+                               .modify = ripd_instance_default_metric_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/distance/default",
-                       .cbs.modify = ripd_instance_distance_default_modify,
-                       .cbs.cli_show = cli_show_rip_distance,
+                       .cbs = {
+                               .cli_show = cli_show_rip_distance,
+                               .modify = ripd_instance_distance_default_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/distance/source",
-                       .cbs.create = ripd_instance_distance_source_create,
-                       .cbs.destroy = ripd_instance_distance_source_delete,
-                       .cbs.cli_show = cli_show_rip_distance_source,
+                       .cbs = {
+                               .cli_show = cli_show_rip_distance_source,
+                               .create = ripd_instance_distance_source_create,
+                               .destroy = ripd_instance_distance_source_destroy,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/distance/source/distance",
-                       .cbs.modify = ripd_instance_distance_source_distance_modify,
+                       .cbs = {
+                               .modify = ripd_instance_distance_source_distance_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/distance/source/access-list",
-                       .cbs.modify = ripd_instance_distance_source_access_list_modify,
-                       .cbs.destroy = ripd_instance_distance_source_access_list_delete,
+                       .cbs = {
+                               .destroy = ripd_instance_distance_source_access_list_destroy,
+                               .modify = ripd_instance_distance_source_access_list_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/explicit-neighbor",
-                       .cbs.create = ripd_instance_explicit_neighbor_create,
-                       .cbs.destroy = ripd_instance_explicit_neighbor_delete,
-                       .cbs.cli_show = cli_show_rip_neighbor,
+                       .cbs = {
+                               .cli_show = cli_show_rip_neighbor,
+                               .create = ripd_instance_explicit_neighbor_create,
+                               .destroy = ripd_instance_explicit_neighbor_destroy,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/network",
-                       .cbs.create = ripd_instance_network_create,
-                       .cbs.destroy = ripd_instance_network_delete,
-                       .cbs.cli_show = cli_show_rip_network_prefix,
+                       .cbs = {
+                               .cli_show = cli_show_rip_network_prefix,
+                               .create = ripd_instance_network_create,
+                               .destroy = ripd_instance_network_destroy,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/interface",
-                       .cbs.create = ripd_instance_interface_create,
-                       .cbs.destroy = ripd_instance_interface_delete,
-                       .cbs.cli_show = cli_show_rip_network_interface,
+                       .cbs = {
+                               .cli_show = cli_show_rip_network_interface,
+                               .create = ripd_instance_interface_create,
+                               .destroy = ripd_instance_interface_destroy,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/offset-list",
-                       .cbs.create = ripd_instance_offset_list_create,
-                       .cbs.destroy = ripd_instance_offset_list_delete,
-                       .cbs.cli_show = cli_show_rip_offset_list,
+                       .cbs = {
+                               .cli_show = cli_show_rip_offset_list,
+                               .create = ripd_instance_offset_list_create,
+                               .destroy = ripd_instance_offset_list_destroy,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/offset-list/access-list",
-                       .cbs.modify = ripd_instance_offset_list_access_list_modify,
+                       .cbs = {
+                               .modify = ripd_instance_offset_list_access_list_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/offset-list/metric",
-                       .cbs.modify = ripd_instance_offset_list_metric_modify,
+                       .cbs = {
+                               .modify = ripd_instance_offset_list_metric_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/passive-default",
-                       .cbs.modify = ripd_instance_passive_default_modify,
-                       .cbs.cli_show = cli_show_rip_passive_default,
+                       .cbs = {
+                               .cli_show = cli_show_rip_passive_default,
+                               .modify = ripd_instance_passive_default_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/passive-interface",
-                       .cbs.create = ripd_instance_passive_interface_create,
-                       .cbs.destroy = ripd_instance_passive_interface_delete,
-                       .cbs.cli_show = cli_show_rip_passive_interface,
+                       .cbs = {
+                               .cli_show = cli_show_rip_passive_interface,
+                               .create = ripd_instance_passive_interface_create,
+                               .destroy = ripd_instance_passive_interface_destroy,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/non-passive-interface",
-                       .cbs.create = ripd_instance_non_passive_interface_create,
-                       .cbs.destroy = ripd_instance_non_passive_interface_delete,
-                       .cbs.cli_show = cli_show_rip_non_passive_interface,
+                       .cbs = {
+                               .cli_show = cli_show_rip_non_passive_interface,
+                               .create = ripd_instance_non_passive_interface_create,
+                               .destroy = ripd_instance_non_passive_interface_destroy,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/redistribute",
-                       .cbs.create = ripd_instance_redistribute_create,
-                       .cbs.destroy = ripd_instance_redistribute_delete,
-                       .cbs.apply_finish = ripd_instance_redistribute_apply_finish,
-                       .cbs.cli_show = cli_show_rip_redistribute,
+                       .cbs = {
+                               .apply_finish = ripd_instance_redistribute_apply_finish,
+                               .cli_show = cli_show_rip_redistribute,
+                               .create = ripd_instance_redistribute_create,
+                               .destroy = ripd_instance_redistribute_destroy,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/redistribute/route-map",
-                       .cbs.modify = ripd_instance_redistribute_route_map_modify,
-                       .cbs.destroy = ripd_instance_redistribute_route_map_delete,
+                       .cbs = {
+                               .destroy = ripd_instance_redistribute_route_map_destroy,
+                               .modify = ripd_instance_redistribute_route_map_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/redistribute/metric",
-                       .cbs.modify = ripd_instance_redistribute_metric_modify,
-                       .cbs.destroy = ripd_instance_redistribute_metric_delete,
+                       .cbs = {
+                               .destroy = ripd_instance_redistribute_metric_destroy,
+                               .modify = ripd_instance_redistribute_metric_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/static-route",
-                       .cbs.create = ripd_instance_static_route_create,
-                       .cbs.destroy = ripd_instance_static_route_delete,
-                       .cbs.cli_show = cli_show_rip_route,
+                       .cbs = {
+                               .cli_show = cli_show_rip_route,
+                               .create = ripd_instance_static_route_create,
+                               .destroy = ripd_instance_static_route_destroy,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/timers",
-                       .cbs.apply_finish = ripd_instance_timers_apply_finish,
-                       .cbs.cli_show = cli_show_rip_timers,
+                       .cbs = {
+                               .apply_finish = ripd_instance_timers_apply_finish,
+                               .cli_show = cli_show_rip_timers,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/timers/flush-interval",
-                       .cbs.modify = ripd_instance_timers_flush_interval_modify,
+                       .cbs = {
+                               .modify = ripd_instance_timers_flush_interval_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/timers/holddown-interval",
-                       .cbs.modify = ripd_instance_timers_holddown_interval_modify,
+                       .cbs = {
+                               .modify = ripd_instance_timers_holddown_interval_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/timers/update-interval",
-                       .cbs.modify = ripd_instance_timers_update_interval_modify,
+                       .cbs = {
+                               .modify = ripd_instance_timers_update_interval_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/version",
-                       .cbs.cli_show = cli_show_rip_version,
+                       .cbs = {
+                               .cli_show = cli_show_rip_version,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/version/receive",
-                       .cbs.modify = ripd_instance_version_receive_modify,
+                       .cbs = {
+                               .modify = ripd_instance_version_receive_modify,
+                       },
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/version/send",
-                       .cbs.modify = ripd_instance_version_send_modify,
+                       .cbs = {
+                               .modify = ripd_instance_version_send_modify,
+                       },
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-ripd:rip/split-horizon",
-                       .cbs.modify = lib_interface_rip_split_horizon_modify,
-                       .cbs.cli_show = cli_show_ip_rip_split_horizon,
+                       .cbs = {
+                               .cli_show = cli_show_ip_rip_split_horizon,
+                               .modify = lib_interface_rip_split_horizon_modify,
+                       },
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-ripd:rip/v2-broadcast",
-                       .cbs.modify = lib_interface_rip_v2_broadcast_modify,
-                       .cbs.cli_show = cli_show_ip_rip_v2_broadcast,
+                       .cbs = {
+                               .cli_show = cli_show_ip_rip_v2_broadcast,
+                               .modify = lib_interface_rip_v2_broadcast_modify,
+                       },
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-receive",
-                       .cbs.modify = lib_interface_rip_version_receive_modify,
-                       .cbs.cli_show = cli_show_ip_rip_receive_version,
+                       .cbs = {
+                               .cli_show = cli_show_ip_rip_receive_version,
+                               .modify = lib_interface_rip_version_receive_modify,
+                       },
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-send",
-                       .cbs.modify = lib_interface_rip_version_send_modify,
-                       .cbs.cli_show = cli_show_ip_rip_send_version,
+                       .cbs = {
+                               .cli_show = cli_show_ip_rip_send_version,
+                               .modify = lib_interface_rip_version_send_modify,
+                       },
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme",
-                       .cbs.cli_show = cli_show_ip_rip_authentication_scheme,
+                       .cbs = {
+                               .cli_show = cli_show_ip_rip_authentication_scheme,
+                       },
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode",
-                       .cbs.modify = lib_interface_rip_authentication_scheme_mode_modify,
+                       .cbs = {
+                               .modify = lib_interface_rip_authentication_scheme_mode_modify,
+                       },
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length",
-                       .cbs.modify = lib_interface_rip_authentication_scheme_md5_auth_length_modify,
-                       .cbs.destroy = lib_interface_rip_authentication_scheme_md5_auth_length_delete,
+                       .cbs = {
+                               .destroy = lib_interface_rip_authentication_scheme_md5_auth_length_destroy,
+                               .modify = lib_interface_rip_authentication_scheme_md5_auth_length_modify,
+                       },
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-password",
-                       .cbs.modify = lib_interface_rip_authentication_password_modify,
-                       .cbs.destroy = lib_interface_rip_authentication_password_delete,
-                       .cbs.cli_show = cli_show_ip_rip_authentication_string,
+                       .cbs = {
+                               .cli_show = cli_show_ip_rip_authentication_string,
+                               .destroy = lib_interface_rip_authentication_password_destroy,
+                               .modify = lib_interface_rip_authentication_password_modify,
+                       },
                },
                {
                        .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain",
-                       .cbs.modify = lib_interface_rip_authentication_key_chain_modify,
-                       .cbs.destroy = lib_interface_rip_authentication_key_chain_delete,
-                       .cbs.cli_show = cli_show_ip_rip_authentication_key_chain,
+                       .cbs = {
+                               .cli_show = cli_show_ip_rip_authentication_key_chain,
+                               .destroy = lib_interface_rip_authentication_key_chain_destroy,
+                               .modify = lib_interface_rip_authentication_key_chain_modify,
+                       },
                },
                {
-                       .xpath = "/frr-ripd:ripd/state/neighbors/neighbor",
-                       .cbs.get_next = ripd_state_neighbors_neighbor_get_next,
-                       .cbs.get_keys = ripd_state_neighbors_neighbor_get_keys,
-                       .cbs.lookup_entry = ripd_state_neighbors_neighbor_lookup_entry,
+                       .xpath = "/frr-ripd:ripd/instance/state/neighbors/neighbor",
+                       .cbs = {
+                               .get_keys = ripd_instance_state_neighbors_neighbor_get_keys,
+                               .get_next = ripd_instance_state_neighbors_neighbor_get_next,
+                               .lookup_entry = ripd_instance_state_neighbors_neighbor_lookup_entry,
+                       },
                },
                {
-                       .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/address",
-                       .cbs.get_elem = ripd_state_neighbors_neighbor_address_get_elem,
+                       .xpath = "/frr-ripd:ripd/instance/state/neighbors/neighbor/address",
+                       .cbs = {
+                               .get_elem = ripd_instance_state_neighbors_neighbor_address_get_elem,
+                       },
                },
                {
-                       .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/last-update",
-                       .cbs.get_elem = ripd_state_neighbors_neighbor_last_update_get_elem,
+                       .xpath = "/frr-ripd:ripd/instance/state/neighbors/neighbor/last-update",
+                       .cbs = {
+                               .get_elem = ripd_instance_state_neighbors_neighbor_last_update_get_elem,
+                       },
                },
                {
-                       .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/bad-packets-rcvd",
-                       .cbs.get_elem = ripd_state_neighbors_neighbor_bad_packets_rcvd_get_elem,
+                       .xpath = "/frr-ripd:ripd/instance/state/neighbors/neighbor/bad-packets-rcvd",
+                       .cbs = {
+                               .get_elem = ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem,
+                       },
                },
                {
-                       .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/bad-routes-rcvd",
-                       .cbs.get_elem = ripd_state_neighbors_neighbor_bad_routes_rcvd_get_elem,
+                       .xpath = "/frr-ripd:ripd/instance/state/neighbors/neighbor/bad-routes-rcvd",
+                       .cbs = {
+                               .get_elem = ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem,
+                       },
                },
                {
-                       .xpath = "/frr-ripd:ripd/state/routes/route",
-                       .cbs.get_next = ripd_state_routes_route_get_next,
-                       .cbs.get_keys = ripd_state_routes_route_get_keys,
-                       .cbs.lookup_entry = ripd_state_routes_route_lookup_entry,
+                       .xpath = "/frr-ripd:ripd/instance/state/routes/route",
+                       .cbs = {
+                               .get_keys = ripd_instance_state_routes_route_get_keys,
+                               .get_next = ripd_instance_state_routes_route_get_next,
+                               .lookup_entry = ripd_instance_state_routes_route_lookup_entry,
+                       },
                },
                {
-                       .xpath = "/frr-ripd:ripd/state/routes/route/prefix",
-                       .cbs.get_elem = ripd_state_routes_route_prefix_get_elem,
+                       .xpath = "/frr-ripd:ripd/instance/state/routes/route/prefix",
+                       .cbs = {
+                               .get_elem = ripd_instance_state_routes_route_prefix_get_elem,
+                       },
                },
                {
-                       .xpath = "/frr-ripd:ripd/state/routes/route/next-hop",
-                       .cbs.get_elem = ripd_state_routes_route_next_hop_get_elem,
+                       .xpath = "/frr-ripd:ripd/instance/state/routes/route/next-hop",
+                       .cbs = {
+                               .get_elem = ripd_instance_state_routes_route_next_hop_get_elem,
+                       },
                },
                {
-                       .xpath = "/frr-ripd:ripd/state/routes/route/interface",
-                       .cbs.get_elem = ripd_state_routes_route_interface_get_elem,
+                       .xpath = "/frr-ripd:ripd/instance/state/routes/route/interface",
+                       .cbs = {
+                               .get_elem = ripd_instance_state_routes_route_interface_get_elem,
+                       },
                },
                {
-                       .xpath = "/frr-ripd:ripd/state/routes/route/metric",
-                       .cbs.get_elem = ripd_state_routes_route_metric_get_elem,
+                       .xpath = "/frr-ripd:ripd/instance/state/routes/route/metric",
+                       .cbs = {
+                               .get_elem = ripd_instance_state_routes_route_metric_get_elem,
+                       },
                },
                {
                        .xpath = "/frr-ripd:clear-rip-route",
-                       .cbs.rpc = clear_rip_route_rpc,
+                       .cbs = {
+                               .rpc = clear_rip_route_rpc,
+                       },
                },
                {
                        .xpath = NULL,