]> git.proxmox.com Git - mirror_frr.git/blobdiff - ripngd/ripng_northbound.c
zebra: Allow ns delete to happen after under/over flow checks
[mirror_frr.git] / ripngd / ripng_northbound.c
index 84e4bf43e77375fc150d97c1ccf8dffbc1cbf08b..7993714e8d3540a5c93cfe380320651032239049 100644 (file)
 #include "table.h"
 #include "command.h"
 #include "routemap.h"
+#include "agg_table.h"
 #include "northbound.h"
 #include "libfrr.h"
 
 #include "ripngd/ripngd.h"
+#include "ripngd/ripng_route.h"
 #include "ripngd/ripng_cli.h"
 
 /*
@@ -40,14 +42,38 @@ static int ripngd_instance_create(enum nb_event event,
                                  const struct lyd_node *dnode,
                                  union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       int socket;
+
+       switch (event) {
+       case NB_EV_VALIDATE:
+               break;
+       case NB_EV_PREPARE:
+               socket = ripng_make_socket();
+               if (socket < 0)
+                       return NB_ERR_RESOURCE;
+               resource->fd = socket;
+               break;
+       case NB_EV_ABORT:
+               socket = resource->fd;
+               close(socket);
+               break;
+       case NB_EV_APPLY:
+               socket = resource->fd;
+               ripng_create(socket);
+               break;
+       }
+
        return NB_OK;
 }
 
 static int ripngd_instance_delete(enum nb_event event,
                                  const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ripng_clean();
+
        return NB_OK;
 }
 
@@ -58,7 +84,13 @@ static int ripngd_instance_allow_ecmp_modify(enum nb_event event,
                                             const struct lyd_node *dnode,
                                             union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ripng->ecmp = yang_dnode_get_bool(dnode, NULL);
+       if (!ripng->ecmp)
+               ripng_ecmp_disable();
+
        return NB_OK;
 }
 
@@ -69,7 +101,22 @@ static int ripngd_instance_default_information_originate_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       bool default_information;
+       struct prefix_ipv6 p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       default_information = yang_dnode_get_bool(dnode, NULL);
+       str2prefix_ipv6("::/0", &p);
+       if (default_information) {
+               ripng_redistribute_add(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_DEFAULT,
+                                      &p, 0, NULL, 0);
+       } else {
+               ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG,
+                                         RIPNG_ROUTE_DEFAULT, &p, 0);
+       }
+
        return NB_OK;
 }
 
@@ -80,7 +127,11 @@ static int ripngd_instance_default_metric_modify(enum nb_event event,
                                                 const struct lyd_node *dnode,
                                                 union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ripng->default_metric = yang_dnode_get_uint8(dnode, NULL);
+
        return NB_OK;
 }
 
@@ -91,15 +142,29 @@ static int ripngd_instance_network_create(enum nb_event event,
                                          const struct lyd_node *dnode,
                                          union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       struct prefix p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv6p(&p, dnode, NULL);
+       apply_mask_ipv6((struct prefix_ipv6 *)&p);
+
+       return ripng_enable_network_add(&p);
 }
 
 static int ripngd_instance_network_delete(enum nb_event event,
                                          const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       struct prefix p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv6p(&p, dnode, NULL);
+       apply_mask_ipv6((struct prefix_ipv6 *)&p);
+
+       return ripng_enable_network_delete(&p);
 }
 
 /*
@@ -109,15 +174,27 @@ static int ripngd_instance_interface_create(enum nb_event event,
                                            const struct lyd_node *dnode,
                                            union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       const char *ifname;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifname = yang_dnode_get_string(dnode, NULL);
+
+       return ripng_enable_if_add(ifname);
 }
 
 static int ripngd_instance_interface_delete(enum nb_event event,
                                            const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       const char *ifname;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifname = yang_dnode_get_string(dnode, NULL);
+
+       return ripng_enable_if_delete(ifname);
 }
 
 /*
@@ -127,14 +204,40 @@ static int ripngd_instance_offset_list_create(enum nb_event event,
                                              const struct lyd_node *dnode,
                                              union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       const char *ifname;
+       struct ripng_offset_list *offset;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifname = yang_dnode_get_string(dnode, "./interface");
+
+       offset = ripng_offset_list_new(ifname);
+       yang_dnode_set_entry(dnode, offset);
+
        return NB_OK;
 }
 
 static int ripngd_instance_offset_list_delete(enum nb_event event,
                                              const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       int direct;
+       struct ripng_offset_list *offset;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       direct = yang_dnode_get_enum(dnode, "./direction");
+
+       offset = yang_dnode_get_entry(dnode, true);
+       if (offset->direct[direct].alist_name) {
+               free(offset->direct[direct].alist_name);
+               offset->direct[direct].alist_name = NULL;
+       }
+       if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name == NULL
+           && offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name == NULL)
+               ripng_offset_list_del(offset);
+
        return NB_OK;
 }
 
@@ -146,7 +249,21 @@ ripngd_instance_offset_list_access_list_modify(enum nb_event event,
                                               const struct lyd_node *dnode,
                                               union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       int direct;
+       struct ripng_offset_list *offset;
+       const char *alist_name;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       direct = yang_dnode_get_enum(dnode, "../direction");
+       alist_name = yang_dnode_get_string(dnode, NULL);
+
+       offset = yang_dnode_get_entry(dnode, true);
+       if (offset->direct[direct].alist_name)
+               free(offset->direct[direct].alist_name);
+       offset->direct[direct].alist_name = strdup(alist_name);
+
        return NB_OK;
 }
 
@@ -158,7 +275,19 @@ ripngd_instance_offset_list_metric_modify(enum nb_event event,
                                          const struct lyd_node *dnode,
                                          union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       int direct;
+       uint8_t metric;
+       struct ripng_offset_list *offset;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       direct = yang_dnode_get_enum(dnode, "../direction");
+       metric = yang_dnode_get_uint8(dnode, NULL);
+
+       offset = yang_dnode_get_entry(dnode, true);
+       offset->direct[direct].metric = metric;
+
        return NB_OK;
 }
 
@@ -170,16 +299,28 @@ ripngd_instance_passive_interface_create(enum nb_event event,
                                         const struct lyd_node *dnode,
                                         union nb_resource *resource)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       const char *ifname;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifname = yang_dnode_get_string(dnode, NULL);
+
+       return ripng_passive_interface_set(ifname);
 }
 
 static int
 ripngd_instance_passive_interface_delete(enum nb_event event,
                                         const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
-       return NB_OK;
+       const char *ifname;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifname = yang_dnode_get_string(dnode, NULL);
+
+       return ripng_passive_interface_unset(ifname);
 }
 
 /*
@@ -189,17 +330,33 @@ static int ripngd_instance_redistribute_create(enum nb_event event,
                                               const struct lyd_node *dnode,
                                               union nb_resource *resource)
 {
-       /* TODO: implement me. */
        return NB_OK;
 }
 
 static int ripngd_instance_redistribute_delete(enum nb_event event,
                                               const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       int type;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       type = yang_dnode_get_enum(dnode, "./protocol");
+
+       ripng_redistribute_conf_delete(type);
+
        return NB_OK;
 }
 
+static void
+ripngd_instance_redistribute_apply_finish(const struct lyd_node *dnode)
+{
+       int type;
+
+       type = yang_dnode_get_enum(dnode, "./protocol");
+       ripng_redistribute_conf_update(type);
+}
+
 /*
  * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map
  */
@@ -208,7 +365,20 @@ ripngd_instance_redistribute_route_map_modify(enum nb_event event,
                                              const struct lyd_node *dnode,
                                              union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       int type;
+       const char *rmap_name;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       type = yang_dnode_get_enum(dnode, "../protocol");
+       rmap_name = yang_dnode_get_string(dnode, NULL);
+
+       if (ripng->route_map[type].name)
+               free(ripng->route_map[type].name);
+       ripng->route_map[type].name = strdup(rmap_name);
+       ripng->route_map[type].map = route_map_lookup_by_name(rmap_name);
+
        return NB_OK;
 }
 
@@ -216,7 +386,17 @@ static int
 ripngd_instance_redistribute_route_map_delete(enum nb_event event,
                                              const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       int type;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       type = yang_dnode_get_enum(dnode, "../protocol");
+
+       free(ripng->route_map[type].name);
+       ripng->route_map[type].name = NULL;
+       ripng->route_map[type].map = NULL;
+
        return NB_OK;
 }
 
@@ -228,7 +408,18 @@ ripngd_instance_redistribute_metric_modify(enum nb_event event,
                                           const struct lyd_node *dnode,
                                           union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       int type;
+       uint8_t metric;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       type = yang_dnode_get_enum(dnode, "../protocol");
+       metric = yang_dnode_get_uint8(dnode, NULL);
+
+       ripng->route_map[type].metric_config = true;
+       ripng->route_map[type].metric = metric;
+
        return NB_OK;
 }
 
@@ -236,7 +427,16 @@ static int
 ripngd_instance_redistribute_metric_delete(enum nb_event event,
                                           const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       int type;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       type = yang_dnode_get_enum(dnode, "../protocol");
+
+       ripng->route_map[type].metric_config = false;
+       ripng->route_map[type].metric = 0;
+
        return NB_OK;
 }
 
@@ -247,14 +447,33 @@ static int ripngd_instance_static_route_create(enum nb_event event,
                                               const struct lyd_node *dnode,
                                               union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct prefix_ipv6 p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv6p(&p, dnode, NULL);
+       apply_mask_ipv6(&p);
+
+       ripng_redistribute_add(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, 0,
+                              NULL, 0);
+
        return NB_OK;
 }
 
 static int ripngd_instance_static_route_delete(enum nb_event event,
                                               const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       struct prefix_ipv6 p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv6p(&p, dnode, NULL);
+       apply_mask_ipv6(&p);
+
+       ripng_redistribute_delete(ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, 0);
+
        return NB_OK;
 }
 
@@ -266,7 +485,16 @@ ripngd_instance_aggregate_address_create(enum nb_event event,
                                         const struct lyd_node *dnode,
                                         union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct prefix_ipv6 p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv6p(&p, dnode, NULL);
+       apply_mask_ipv6(&p);
+
+       ripng_aggregate_add((struct prefix *)&p);
+
        return NB_OK;
 }
 
@@ -274,10 +502,28 @@ static int
 ripngd_instance_aggregate_address_delete(enum nb_event event,
                                         const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       struct prefix_ipv6 p;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv6p(&p, dnode, NULL);
+       apply_mask_ipv6(&p);
+
+       ripng_aggregate_delete((struct prefix *)&p);
+
        return NB_OK;
 }
 
+/*
+ * XPath: /frr-ripngd:ripngd/instance/timers
+ */
+static void ripngd_instance_timers_apply_finish(const struct lyd_node *dnode)
+{
+       /* Reset update timer thread. */
+       ripng_event(RIPNG_UPDATE_EVENT, 0);
+}
+
 /*
  * XPath: /frr-ripngd:ripngd/instance/timers/flush-interval
  */
@@ -286,7 +532,11 @@ ripngd_instance_timers_flush_interval_modify(enum nb_event event,
                                             const struct lyd_node *dnode,
                                             union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ripng->garbage_time = yang_dnode_get_uint16(dnode, NULL);
+
        return NB_OK;
 }
 
@@ -298,7 +548,11 @@ ripngd_instance_timers_holddown_interval_modify(enum nb_event event,
                                                const struct lyd_node *dnode,
                                                union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ripng->timeout_time = yang_dnode_get_uint16(dnode, NULL);
+
        return NB_OK;
 }
 
@@ -310,7 +564,11 @@ ripngd_instance_timers_update_interval_modify(enum nb_event event,
                                              const struct lyd_node *dnode,
                                              union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ripng->update_time = yang_dnode_get_uint16(dnode, NULL);
+
        return NB_OK;
 }
 
@@ -321,14 +579,26 @@ static const void *
 ripngd_state_neighbors_neighbor_get_next(const void *parent_list_entry,
                                         const void *list_entry)
 {
-       /* TODO: implement me. */
-       return NULL;
+       struct listnode *node;
+
+       if (list_entry == NULL)
+               node = listhead(peer_list);
+       else
+               node = listnextnode((struct listnode *)list_entry);
+
+       return node;
 }
 
 static int ripngd_state_neighbors_neighbor_get_keys(const void *list_entry,
                                                    struct yang_list_keys *keys)
 {
-       /* TODO: implement me. */
+       const struct listnode *node = list_entry;
+       const struct ripng_peer *peer = listgetdata(node);
+
+       keys->num = 1;
+       (void)inet_ntop(AF_INET6, &peer->addr, keys->key[0],
+                       sizeof(keys->key[0]));
+
        return NB_OK;
 }
 
@@ -336,7 +606,17 @@ static const void *
 ripngd_state_neighbors_neighbor_lookup_entry(const void *parent_list_entry,
                                             const struct yang_list_keys *keys)
 {
-       /* TODO: implement me. */
+       struct in6_addr address;
+       struct ripng_peer *peer;
+       struct listnode *node;
+
+       yang_str2ipv6(keys->key[0], &address);
+
+       for (ALL_LIST_ELEMENTS_RO(peer_list, node, peer)) {
+               if (IPV6_ADDR_SAME(&peer->addr, &address))
+                       return node;
+       }
+
        return NULL;
 }
 
@@ -347,8 +627,10 @@ static struct yang_data *
 ripngd_state_neighbors_neighbor_address_get_elem(const char *xpath,
                                                 const void *list_entry)
 {
-       /* TODO: implement me. */
-       return NULL;
+       const struct listnode *node = list_entry;
+       const struct ripng_peer *peer = listgetdata(node);
+
+       return yang_data_new_ipv6(xpath, &peer->addr);
 }
 
 /*
@@ -358,7 +640,7 @@ static struct yang_data *
 ripngd_state_neighbors_neighbor_last_update_get_elem(const char *xpath,
                                                     const void *list_entry)
 {
-       /* TODO: implement me. */
+       /* TODO: yang:date-and-time is tricky */
        return NULL;
 }
 
@@ -369,8 +651,10 @@ static struct yang_data *
 ripngd_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
        const char *xpath, const void *list_entry)
 {
-       /* TODO: implement me. */
-       return NULL;
+       const struct listnode *node = list_entry;
+       const struct ripng_peer *peer = listgetdata(node);
+
+       return yang_data_new_uint32(xpath, peer->recv_badpackets);
 }
 
 /*
@@ -380,8 +664,10 @@ static struct yang_data *
 ripngd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath,
                                                         const void *list_entry)
 {
-       /* TODO: implement me. */
-       return NULL;
+       const struct listnode *node = list_entry;
+       const struct ripng_peer *peer = listgetdata(node);
+
+       return yang_data_new_uint32(xpath, peer->recv_badroutes);
 }
 
 /*
@@ -391,14 +677,29 @@ static const void *
 ripngd_state_routes_route_get_next(const void *parent_list_entry,
                                   const void *list_entry)
 {
-       /* TODO: implement me. */
-       return NULL;
+       struct agg_node *rn;
+
+       if (ripng == NULL)
+               return NULL;
+
+       if (list_entry == NULL)
+               rn = agg_route_top(ripng->table);
+       else
+               rn = agg_route_next((struct agg_node *)list_entry);
+       while (rn && rn->info == NULL)
+               rn = agg_route_next(rn);
+
+       return rn;
 }
 
 static int ripngd_state_routes_route_get_keys(const void *list_entry,
                                              struct yang_list_keys *keys)
 {
-       /* TODO: implement me. */
+       const struct agg_node *rn = list_entry;
+
+       keys->num = 1;
+       (void)prefix2str(&rn->p, keys->key[0], sizeof(keys->key[0]));
+
        return NB_OK;
 }
 
@@ -406,8 +707,18 @@ static const void *
 ripngd_state_routes_route_lookup_entry(const void *parent_list_entry,
                                       const struct yang_list_keys *keys)
 {
-       /* TODO: implement me. */
-       return NULL;
+       struct prefix prefix;
+       struct agg_node *rn;
+
+       yang_str2ipv6p(keys->key[0], &prefix);
+
+       rn = agg_node_lookup(ripng->table, &prefix);
+       if (!rn || !rn->info)
+               return NULL;
+
+       agg_unlock_node(rn);
+
+       return rn;
 }
 
 /*
@@ -417,8 +728,10 @@ static struct yang_data *
 ripngd_state_routes_route_prefix_get_elem(const char *xpath,
                                          const void *list_entry)
 {
-       /* TODO: implement me. */
-       return NULL;
+       const struct agg_node *rn = list_entry;
+       const struct ripng_info *rinfo = listnode_head(rn->info);
+
+       return yang_data_new_ipv6p(xpath, &rinfo->rp->p);
 }
 
 /*
@@ -428,8 +741,10 @@ static struct yang_data *
 ripngd_state_routes_route_next_hop_get_elem(const char *xpath,
                                            const void *list_entry)
 {
-       /* TODO: implement me. */
-       return NULL;
+       const struct agg_node *rn = list_entry;
+       const struct ripng_info *rinfo = listnode_head(rn->info);
+
+       return yang_data_new_ipv6(xpath, &rinfo->nexthop);
 }
 
 /*
@@ -439,8 +754,11 @@ static struct yang_data *
 ripngd_state_routes_route_interface_get_elem(const char *xpath,
                                             const void *list_entry)
 {
-       /* TODO: implement me. */
-       return NULL;
+       const struct agg_node *rn = list_entry;
+       const struct ripng_info *rinfo = listnode_head(rn->info);
+
+       return yang_data_new_string(
+               xpath, ifindex2ifname(rinfo->ifindex, VRF_DEFAULT));
 }
 
 /*
@@ -450,8 +768,10 @@ static struct yang_data *
 ripngd_state_routes_route_metric_get_elem(const char *xpath,
                                          const void *list_entry)
 {
-       /* TODO: implement me. */
-       return NULL;
+       const struct agg_node *rn = list_entry;
+       const struct ripng_info *rinfo = listnode_head(rn->info);
+
+       return yang_data_new_uint8(xpath, rinfo->metric);
 }
 
 /*
@@ -460,7 +780,40 @@ ripngd_state_routes_route_metric_get_elem(const char *xpath,
 static int clear_ripng_route_rpc(const char *xpath, const struct list *input,
                                 struct list *output)
 {
-       /* TODO: implement me. */
+       struct agg_node *rp;
+       struct ripng_info *rinfo;
+       struct list *list;
+       struct listnode *listnode;
+
+       /* Clear received RIPng routes */
+       for (rp = agg_route_top(ripng->table); rp; rp = agg_route_next(rp)) {
+               list = rp->info;
+               if (list == NULL)
+                       continue;
+
+               for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
+                       if (!ripng_route_rte(rinfo))
+                               continue;
+
+                       if (CHECK_FLAG(rinfo->flags, RIPNG_RTF_FIB))
+                               ripng_zebra_ipv6_delete(rp);
+                       break;
+               }
+
+               if (rinfo) {
+                       RIPNG_TIMER_OFF(rinfo->t_timeout);
+                       RIPNG_TIMER_OFF(rinfo->t_garbage_collect);
+                       listnode_delete(list, rinfo);
+                       ripng_info_free(rinfo);
+               }
+
+               if (list_isempty(list)) {
+                       list_delete(&list);
+                       rp->info = NULL;
+                       agg_unlock_node(rp);
+               }
+       }
+
        return NB_OK;
 }
 
@@ -472,7 +825,16 @@ lib_interface_ripng_split_horizon_modify(enum nb_event event,
                                         const struct lyd_node *dnode,
                                         union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct interface *ifp;
+       struct ripng_interface *ri;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifp = yang_dnode_get_entry(dnode, true);
+       ri = ifp->info;
+       ri->split_horizon = yang_dnode_get_enum(dnode, NULL);
+
        return NB_OK;
 }
 
@@ -484,33 +846,40 @@ const struct frr_yang_module_info frr_ripngd_info = {
                        .xpath = "/frr-ripngd:ripngd/instance",
                        .cbs.create = ripngd_instance_create,
                        .cbs.delete = ripngd_instance_delete,
+                       .cbs.cli_show = cli_show_router_ripng,
                },
                {
                        .xpath = "/frr-ripngd:ripngd/instance/allow-ecmp",
                        .cbs.modify = ripngd_instance_allow_ecmp_modify,
+                       .cbs.cli_show = cli_show_ripng_allow_ecmp,
                },
                {
                        .xpath = "/frr-ripngd:ripngd/instance/default-information-originate",
                        .cbs.modify = ripngd_instance_default_information_originate_modify,
+                       .cbs.cli_show = cli_show_ripng_default_information_originate,
                },
                {
                        .xpath = "/frr-ripngd:ripngd/instance/default-metric",
                        .cbs.modify = ripngd_instance_default_metric_modify,
+                       .cbs.cli_show = cli_show_ripng_default_metric,
                },
                {
                        .xpath = "/frr-ripngd:ripngd/instance/network",
                        .cbs.create = ripngd_instance_network_create,
                        .cbs.delete = ripngd_instance_network_delete,
+                       .cbs.cli_show = cli_show_ripng_network_prefix,
                },
                {
                        .xpath = "/frr-ripngd:ripngd/instance/interface",
                        .cbs.create = ripngd_instance_interface_create,
                        .cbs.delete = ripngd_instance_interface_delete,
+                       .cbs.cli_show = cli_show_ripng_network_interface,
                },
                {
                        .xpath = "/frr-ripngd:ripngd/instance/offset-list",
                        .cbs.create = ripngd_instance_offset_list_create,
                        .cbs.delete = ripngd_instance_offset_list_delete,
+                       .cbs.cli_show = cli_show_ripng_offset_list,
                },
                {
                        .xpath = "/frr-ripngd:ripngd/instance/offset-list/access-list",
@@ -524,11 +893,14 @@ const struct frr_yang_module_info frr_ripngd_info = {
                        .xpath = "/frr-ripngd:ripngd/instance/passive-interface",
                        .cbs.create = ripngd_instance_passive_interface_create,
                        .cbs.delete = ripngd_instance_passive_interface_delete,
+                       .cbs.cli_show = cli_show_ripng_passive_interface,
                },
                {
                        .xpath = "/frr-ripngd:ripngd/instance/redistribute",
                        .cbs.create = ripngd_instance_redistribute_create,
                        .cbs.delete = ripngd_instance_redistribute_delete,
+                       .cbs.apply_finish = ripngd_instance_redistribute_apply_finish,
+                       .cbs.cli_show = cli_show_ripng_redistribute,
                },
                {
                        .xpath = "/frr-ripngd:ripngd/instance/redistribute/route-map",
@@ -544,11 +916,18 @@ const struct frr_yang_module_info frr_ripngd_info = {
                        .xpath = "/frr-ripngd:ripngd/instance/static-route",
                        .cbs.create = ripngd_instance_static_route_create,
                        .cbs.delete = ripngd_instance_static_route_delete,
+                       .cbs.cli_show = cli_show_ripng_route,
                },
                {
                        .xpath = "/frr-ripngd:ripngd/instance/aggregate-address",
                        .cbs.create = ripngd_instance_aggregate_address_create,
                        .cbs.delete = ripngd_instance_aggregate_address_delete,
+                       .cbs.cli_show = cli_show_ripng_aggregate_address,
+               },
+               {
+                       .xpath = "/frr-ripngd:ripngd/instance/timers",
+                       .cbs.apply_finish = ripngd_instance_timers_apply_finish,
+                       .cbs.cli_show = cli_show_ripng_timers,
                },
                {
                        .xpath = "/frr-ripngd:ripngd/instance/timers/flush-interval",
@@ -613,6 +992,7 @@ const struct frr_yang_module_info frr_ripngd_info = {
                {
                        .xpath = "/frr-interface:lib/interface/frr-ripngd:ripng/split-horizon",
                        .cbs.modify = lib_interface_ripng_split_horizon_modify,
+                       .cbs.cli_show = cli_show_ipv6_ripng_split_horizon,
                },
                {
                        .xpath = NULL,