]> git.puffer.fish Git - mirror/frr.git/commitdiff
Merge remote-tracking branch 'frr/master' into rip-vrf
authorRenato Westphal <renato@opensourcerouting.org>
Sat, 2 Mar 2019 18:00:46 +0000 (15:00 -0300)
committerRenato Westphal <renatowestphal@gmail.com>
Fri, 29 Mar 2019 14:32:21 +0000 (11:32 -0300)
Merge commit to solve a bunch of conflicts with other PRs that were
merged in the previous weeks.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
16 files changed:
1  2 
lib/vrf.c
lib/vrf.h
lib/yang.c
lib/yang.h
ripd/rip_cli.c
ripd/rip_main.c
ripd/rip_northbound.c
ripd/ripd.c
ripd/ripd.h
ripngd/ripng_cli.c
ripngd/ripng_interface.c
ripngd/ripng_main.c
ripngd/ripng_northbound.c
ripngd/ripngd.c
ripngd/ripngd.h
vtysh/vtysh.c

diff --cc lib/vrf.c
Simple merge
diff --cc lib/vrf.h
Simple merge
diff --cc lib/yang.c
Simple merge
diff --cc lib/yang.h
index 09d92cafddf128bffcce93a33e585ad7f0f70fef,885218272a5fb0ef1853d074a29e655f3287222c..15f0ec7ae6af0854809adf7de806880f46a6d495
@@@ -509,21 -513,11 +513,26 @@@ extern void yang_data_free(struct yang_
   */
  extern struct list *yang_data_list_new(void);
  
 +/*
 + * Find the yang_data structure corresponding to an XPath in a list.
 + *
 + * list
 + *    list of yang_data structures to operate on.
 + *
 + * xpath_fmt
 + *    XPath to search for (format string).
 + *
 + * Returns:
 + *    Pointer to yang_data if found, NULL otherwise.
 + */
 +extern struct yang_data *yang_data_list_find(const struct list *list,
 +                                           const char *xpath_fmt, ...);
 +
+ /*
+  * Create and set up a libyang context (for use by the translator)
+  */
+ extern struct ly_ctx *yang_ctx_new_setup(void);
  /*
   * Initialize the YANG subsystem. Should be called only once during the
   * daemon initialization process.
diff --cc ripd/rip_cli.c
index 149b30b5d478344646dc570c99a24f7b44d687ca,6fbcdc059be0f87e900f9b344585d6834c4027f4..6b94258ea55d189aad929061ae7522604c8ca45a
@@@ -64,21 -57,13 +64,21 @@@ DEFPY_NOSH (router_rip
  
  DEFPY (no_router_rip,
         no_router_rip_cmd,
 -       "no router rip",
 +       "no router rip [vrf NAME]",
         NO_STR
         "Enable a routing process\n"
 -       "Routing Information Protocol (RIP)\n")
 +       "Routing Information Protocol (RIP)\n"
 +       VRF_CMD_HELP_STR)
  {
 -      nb_cli_enqueue_change(vty, "/frr-ripd:ripd/instance", NB_OP_DESTROY,
 -                            NULL);
 +      char xpath[XPATH_MAXLEN];
 +
 +      /* Build RIP instance XPath. */
 +      if (!vrf)
 +              vrf = VRF_DEFAULT_NAME;
 +      snprintf(xpath, sizeof(xpath), "/frr-ripd:ripd/instance[vrf='%s']",
 +               vrf);
 +
-       nb_cli_enqueue_change(vty, xpath, NB_OP_DELETE, NULL);
++      nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
  
        return nb_cli_apply_changes(vty, NULL);
  }
@@@ -915,7 -893,7 +915,7 @@@ DEFPY (no_ip_rip_authentication_string
         "Authentication string\n"
         "Authentication string\n")
  {
-       nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_DELETE,
 -      nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_MODIFY,
++      nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_DESTROY,
                              NULL);
  
        return nb_cli_apply_changes(vty, "./frr-ripd:rip");
diff --cc ripd/rip_main.c
index 8b6e3a620a75f822ea9ba8ee5b01529d21123eac,5db9c4b7e9e0250d9240a9404d5163de9db210e6..65da51f83abd066e52ea130fa6726a1bae828f80
@@@ -34,6 -34,6 +34,7 @@@
  #include "sigevent.h"
  #include "zclient.h"
  #include "vrf.h"
++#include "if_rmap.h"
  #include "libfrr.h"
  
  #include "ripd/ripd.h"
@@@ -81,7 -81,8 +82,8 @@@ static void sigint(void
  {
        zlog_notice("Terminating on signal");
  
 -      rip_clean();
 -
 +      rip_vrf_terminate();
++      if_rmap_terminate();
        rip_zclient_stop();
        frr_fini();
  
index 13520d11de1024add933222a71960649ff5dc726,1e5f86eff80950eb22609b675fe25bea2d6a0bf9..2c53824ea12039db9b9ef5c922a0cb2ff3a152e3
@@@ -1486,10 -1305,7 +1486,10 @@@ const struct frr_yang_module_info frr_r
                {
                        .xpath = "/frr-ripd:ripd/instance",
                        .cbs.create = ripd_instance_create,
-                       .cbs.delete = ripd_instance_delete,
+                       .cbs.destroy = ripd_instance_delete,
 +                      .cbs.get_next = ripd_instance_get_next,
 +                      .cbs.get_keys = ripd_instance_get_keys,
 +                      .cbs.lookup_entry = ripd_instance_lookup_entry,
                        .cbs.cli_show = cli_show_router_rip,
                },
                {
diff --cc ripd/ripd.c
index 7fe8fc8c8b050edfa752f5075135f346dcb968dc,d2fc9eb303271aede6cd3d9d236f6fc2b176c51c..9683e26b56c2ad3c26e6ebcaf5c5c63ec235310a
@@@ -2699,41 -2691,33 +2698,46 @@@ struct rip *rip_create(const char *vrf_
        rip->version_recv =
                yang_get_default_enum("%s/version/receive", RIP_INSTANCE);
  
 -      /* Initialize RIP routig table. */
 +      /* Initialize RIP data structures. */
        rip->table = route_table_init();
 +      route_table_set_info(rip->table, rip);
        rip->neighbor = route_table_init();
 +      rip->peer_list = list_new();
 +      rip->peer_list->cmp = (int (*)(void *, void *))rip_peer_list_cmp;
 +      rip->peer_list->del = rip_peer_list_del;
 +      rip->distance_table = route_table_init();
 +      rip->distance_table->cleanup = rip_distance_table_node_cleanup;
 +      rip->enable_interface = vector_init(1);
 +      rip->enable_network = route_table_init();
 +      rip->passive_nondefault = vector_init(1);
 +      rip->offset_list_master = list_new();
 +      rip->offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp;
 +      rip->offset_list_master->del = (void (*)(void *))offset_list_del;
  
 -      /* Make output stream. */
 -      rip->obuf = stream_new(1500);
 -
 -      /* Set socket. */
 -      rip->sock = socket;
 -
 -      /* Create read and timer thread. */
 -      rip_event(RIP_READ, rip->sock);
 -      rip_event(RIP_UPDATE_EVENT, 1);
        /* Distribute list install. */
 -      rip->distribute_ctx = distribute_list_ctx_create(
 -                                       vrf_lookup_by_id(VRF_DEFAULT));
 -      distribute_list_add_hook(rip->distribute_ctx,
 -                               rip_distribute_update);
 -      distribute_list_delete_hook(rip->distribute_ctx,
 -                                  rip_distribute_update);
 +      rip->distribute_ctx = distribute_list_ctx_create(vrf);
 +      distribute_list_add_hook(rip->distribute_ctx, rip_distribute_update);
 +      distribute_list_delete_hook(rip->distribute_ctx, rip_distribute_update);
  
 -      rip->if_rmap_ctx = if_rmap_ctx_create(VRF_DEFAULT_NAME);
+       /* if rmap install. */
 -      return 0;
++      rip->if_rmap_ctx = if_rmap_ctx_create(vrf_name);
+       if_rmap_hook_add(rip->if_rmap_ctx, rip_if_rmap_update);
+       if_rmap_hook_delete(rip->if_rmap_ctx, rip_if_rmap_update);
 +      /* Make output stream. */
 +      rip->obuf = stream_new(1500);
 +
 +      /* Enable the routing instance if possible. */
 +      if (vrf && vrf_is_enabled(vrf))
 +              rip_instance_enable(rip, vrf, socket);
 +      else {
 +              rip->vrf = NULL;
 +              rip->sock = -1;
 +      }
 +
 +      RB_INSERT(rip_instance_head, &rip_instances, rip);
 +
 +      return rip;
  }
  
  /* Sned RIP request to the destination. */
@@@ -3269,15 -3229,12 +3273,14 @@@ static int config_write_rip(struct vty 
                nb_cli_show_dnode_cmds(vty, dnode, false);
  
                /* Distribute configuration. */
 -              write += config_write_distribute(vty,
 -                                               rip->distribute_ctx);
 +              config_write_distribute(vty, rip->distribute_ctx);
  
                /* Interface routemap configuration */
-               if (strmatch(rip->vrf_name, VRF_DEFAULT_NAME))
-                       config_write_if_rmap(vty);
 -              write += config_write_if_rmap(vty, rip->if_rmap_ctx);
++              config_write_if_rmap(vty, rip->if_rmap_ctx);
 +
 +              write = 1;
        }
 +
        return write;
  }
  
@@@ -3373,43 -3328,91 +3376,49 @@@ static void rip_distribute_update_all_w
  }
  
  /* Delete all added rip route. */
 -void rip_clean(void)
 +void rip_clean(struct rip *rip)
  {
 -      int i;
 -      struct route_node *rp;
 -      struct rip_info *rinfo = NULL;
 -      struct list *list = NULL;
 -      struct listnode *listnode = NULL;
 -
 -      if (rip) {
 -              /* Clear RIP routes */
 -              for (rp = route_top(rip->table); rp; rp = route_next(rp))
 -                      if ((list = rp->info) != NULL) {
 -                              rinfo = listgetdata(listhead(list));
 -                              if (rip_route_rte(rinfo))
 -                                      rip_zebra_ipv4_delete(rp);
 -
 -                              for (ALL_LIST_ELEMENTS_RO(list, listnode,
 -                                                        rinfo)) {
 -                                      RIP_TIMER_OFF(rinfo->t_timeout);
 -                                      RIP_TIMER_OFF(rinfo->t_garbage_collect);
 -                                      rip_info_free(rinfo);
 -                              }
 -                              list_delete(&list);
 -                              rp->info = NULL;
 -                              route_unlock_node(rp);
 -                      }
 -
 -              /* Cancel RIP related timers. */
 -              RIP_TIMER_OFF(rip->t_update);
 -              RIP_TIMER_OFF(rip->t_triggered_update);
 -              RIP_TIMER_OFF(rip->t_triggered_interval);
 -
 -              /* Cancel read thread. */
 -              THREAD_READ_OFF(rip->t_read);
 -
 -              /* Close RIP socket. */
 -              if (rip->sock >= 0) {
 -                      close(rip->sock);
 -                      rip->sock = -1;
 -              }
 -
 -              stream_free(rip->obuf);
 -
 -              /* RIP neighbor configuration. */
 -              for (rp = route_top(rip->neighbor); rp; rp = route_next(rp))
 -                      if (rp->info) {
 -                              rp->info = NULL;
 -                              route_unlock_node(rp);
 -                      }
 +      if (rip->enabled)
 +              rip_instance_disable(rip);
  
 -              for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
 -                      if (rip->route_map[i].name)
 -                              free(rip->route_map[i].name);
 +      stream_free(rip->obuf);
  
 -              route_table_finish(rip->table);
 -              route_table_finish(rip->neighbor);
 +      for (int i = 0; i < ZEBRA_ROUTE_MAX; i++)
 +              if (rip->redist[i].route_map.name)
 +                      free(rip->redist[i].route_map.name);
  
 -              distribute_list_delete(&rip->distribute_ctx);
 +      route_table_finish(rip->table);
 +      route_table_finish(rip->neighbor);
 +      list_delete(&rip->peer_list);
 +      distribute_list_delete(&rip->distribute_ctx);
++      if_rmap_ctx_delete(rip->if_rmap_ctx);
  
 -              if_rmap_ctx_delete(rip->if_rmap_ctx);
 +      rip_clean_network(rip);
 +      rip_passive_nondefault_clean(rip);
 +      vector_free(rip->enable_interface);
 +      route_table_finish(rip->enable_network);
 +      vector_free(rip->passive_nondefault);
 +      list_delete(&rip->offset_list_master);
 +      rip_interfaces_clean(rip);
 +      route_table_finish(rip->distance_table);
  
 -              XFREE(MTYPE_RIP, rip);
 -              rip = NULL;
 -      }
 -      rip_clean_network();
 -      rip_passive_nondefault_clean();
 -      rip_offset_clean();
 -      rip_interfaces_clean();
 -      rip_distance_reset();
 -      rip_redistribute_clean();
 -      if_rmap_terminate();
 +      RB_REMOVE(rip_instance_head, &rip_instances, rip);
 +      XFREE(MTYPE_RIP_VRF_NAME, rip->vrf_name);
 +      XFREE(MTYPE_RIP, rip);
  }
  
- static void rip_if_rmap_update(struct if_rmap *if_rmap)
+ static void rip_if_rmap_update(struct if_rmap_ctx *ctx,
+                              struct if_rmap *if_rmap)
  {
-       struct interface *ifp;
+       struct interface *ifp = NULL;
        struct rip_interface *ri;
        struct route_map *rmap;
+       struct vrf *vrf = NULL;
  
-       ifp = if_lookup_by_name(if_rmap->ifname, VRF_DEFAULT);
+       if (ctx->name)
+               vrf = vrf_lookup_by_name(ctx->name);
+       if (vrf)
+               ifp = if_lookup_by_name(if_rmap->ifname, vrf->vrf_id);
        if (ifp == NULL)
                return;
  
  
  void rip_if_rmap_update_interface(struct interface *ifp)
  {
++      struct rip_interface *ri = ifp->info;
++      struct rip *rip = ri->rip;
        struct if_rmap *if_rmap;
+       struct if_rmap_ctx *ctx;
  
-       if_rmap = if_rmap_lookup(ifp->name);
+       if (!rip)
+               return;
 -      if (ifp->vrf_id != VRF_DEFAULT)
 -              return;
+       ctx = rip->if_rmap_ctx;
+       if (!ctx)
+               return;
+       if_rmap = if_rmap_lookup(ctx, ifp->name);
        if (if_rmap)
-               rip_if_rmap_update(if_rmap);
+               rip_if_rmap_update(ctx, if_rmap);
  }
  
 -static void rip_routemap_update_redistribute(void)
 +static void rip_routemap_update_redistribute(struct rip *rip)
  {
 -      int i;
 -
 -      if (rip) {
 -              for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
 -                      if (rip->route_map[i].name) {
 -                              rip->route_map[i].map =
 -                                      route_map_lookup_by_name(
 -                                              rip->route_map[i].name);
 -                              route_map_counter_increment(
 -                                      rip->route_map[i].map);
 -                      }
 +      for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
-               if (rip->redist[i].route_map.name)
++              if (rip->redist[i].route_map.name) {
 +                      rip->redist[i].route_map.map = route_map_lookup_by_name(
 +                              rip->redist[i].route_map.name);
++                      route_map_counter_increment(
++                              rip->redist[i].route_map.map);
+               }
        }
  }
  
@@@ -3669,6 -3518,7 +3689,4 @@@ void rip_init(void
        route_map_delete_hook(rip_routemap_update);
  
        if_rmap_init(RIP_NODE);
-       if_rmap_hook_add(rip_if_rmap_update);
-       if_rmap_hook_delete(rip_if_rmap_update);
 -
 -      /* Distance control. */
 -      rip_distance_table = route_table_init();
  }
diff --cc ripd/ripd.h
index f78dae7a8bff11170cf59dcf9f98cd3c10196fe0,383df3707ba9b6ecc4f911ff50ad6bb641c6d774..7b196a16be40e13a489b05918965b6e6efd35634
@@@ -184,17 -155,9 +184,20 @@@ struct rip 
        /* For distribute-list container */
        struct distribute_ctx *distribute_ctx;
  
+       /* For if_rmap container */
+       struct if_rmap_ctx *if_rmap_ctx;
++
 +      /* Counters for SNMP. */
 +      struct {
 +              /* RIP route changes. */
 +              long route_changes;
 +
 +              /* RIP queries. */
 +              long queries;
 +      } counters;
  };
 +RB_HEAD(rip_instance_head, rip);
 +RB_PROTOTYPE(rip_instance_head, rip, entry, rip_instance_compare)
  
  /* RIP routing table entry which belong to rip_packet. */
  struct rte {
@@@ -441,71 -396,58 +444,71 @@@ extern struct rip *rip_create(const cha
  
  extern int rip_request_send(struct sockaddr_in *, struct interface *, uint8_t,
                            struct connected *);
 -extern int rip_neighbor_lookup(struct sockaddr_in *);
 -extern int rip_neighbor_add(struct prefix_ipv4 *p);
 -extern int rip_neighbor_delete(struct prefix_ipv4 *p);
 -
 -extern int rip_enable_network_add(struct prefix *p);
 -extern int rip_enable_network_delete(struct prefix *p);
 -extern int rip_enable_if_add(const char *ifname);
 -extern int rip_enable_if_delete(const char *ifname);
 -
 -extern void rip_event(enum rip_event, int);
 -extern void rip_ecmp_disable(void);
 -
 -extern int rip_create_socket(void);
 -
 -extern int rip_redistribute_check(int);
 -extern void rip_redistribute_conf_update(int type);
 -extern void rip_redistribute_conf_delete(int type);
 -extern void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p,
 -                               struct nexthop *nh, unsigned int metric,
 -                               unsigned char distance, route_tag_t tag);
 -extern void rip_redistribute_delete(int, int, struct prefix_ipv4 *, ifindex_t);
 -extern void rip_redistribute_withdraw(int);
 -extern void rip_zebra_ipv4_add(struct route_node *);
 -extern void rip_zebra_ipv4_delete(struct route_node *);
 +extern int rip_neighbor_lookup(struct rip *rip, struct sockaddr_in *from);
 +extern int rip_neighbor_add(struct rip *rip, struct prefix_ipv4 *p);
 +extern int rip_neighbor_delete(struct rip *rip, struct prefix_ipv4 *p);
 +
 +extern int rip_enable_network_add(struct rip *rip, struct prefix *p);
 +extern int rip_enable_network_delete(struct rip *rip, struct prefix *p);
 +extern int rip_enable_if_add(struct rip *rip, const char *ifname);
 +extern int rip_enable_if_delete(struct rip *rip, const char *ifname);
 +
 +extern void rip_event(struct rip *rip, enum rip_event event, int sock);
 +extern void rip_ecmp_disable(struct rip *rip);
 +
 +extern int rip_create_socket(struct vrf *vrf);
 +
 +extern int rip_redistribute_check(struct rip *rip, int type);
 +extern void rip_redistribute_conf_update(struct rip *rip, int type);
 +extern void rip_redistribute_conf_delete(struct rip *rip, int type);
 +extern void rip_redistribute_add(struct rip *rip, int type, int sub_type,
 +                               struct prefix_ipv4 *p, struct nexthop *nh,
 +                               unsigned int metric, unsigned char distance,
 +                               route_tag_t tag);
 +extern void rip_redistribute_delete(struct rip *rip, int type, int sub_type,
 +                                  struct prefix_ipv4 *p, ifindex_t ifindex);
 +extern void rip_redistribute_withdraw(struct rip *rip, int type);
 +extern void rip_zebra_ipv4_add(struct rip *rip, struct route_node *rp);
 +extern void rip_zebra_ipv4_delete(struct rip *rip, struct route_node *rp);
  extern void rip_interface_multicast_set(int, struct connected *);
  extern void rip_distribute_update_interface(struct interface *);
- extern void rip_if_rmap_update_interface(struct interface *);
+ extern void rip_if_rmap_update_interface(struct interface *ifp);
 -extern int rip_show_network_config(struct vty *);
 -extern void rip_show_redistribute_config(struct vty *);
  
 -extern void rip_peer_init(void);
 -extern void rip_peer_update(struct sockaddr_in *, uint8_t);
 -extern void rip_peer_bad_route(struct sockaddr_in *);
 -extern void rip_peer_bad_packet(struct sockaddr_in *);
 -extern void rip_peer_display(struct vty *);
 -extern struct rip_peer *rip_peer_lookup(struct in_addr *);
 -extern struct rip_peer *rip_peer_lookup_next(struct in_addr *);
 +extern int rip_show_network_config(struct vty *vty, struct rip *rip);
 +extern void rip_show_redistribute_config(struct vty *vty, struct rip *rip);
 +
 +extern void rip_peer_update(struct rip *rip, struct sockaddr_in *from,
 +                          uint8_t version);
 +extern void rip_peer_bad_route(struct rip *rip, struct sockaddr_in *from);
 +extern void rip_peer_bad_packet(struct rip *rip, struct sockaddr_in *from);
 +extern void rip_peer_display(struct vty *vty, struct rip *rip);
 +extern struct rip_peer *rip_peer_lookup(struct rip *rip, struct in_addr *addr);
 +extern struct rip_peer *rip_peer_lookup_next(struct rip *rip,
 +                                           struct in_addr *addr);
 +extern int rip_peer_list_cmp(struct rip_peer *p1, struct rip_peer *p2);
 +extern void rip_peer_list_del(void *arg);
  
  extern void rip_info_free(struct rip_info *);
 +extern struct rip *rip_info_get_instance(const struct rip_info *rinfo);
  extern struct rip_distance *rip_distance_new(void);
  extern void rip_distance_free(struct rip_distance *rdistance);
 -extern uint8_t rip_distance_apply(struct rip_info *);
 -extern void rip_redistribute_clean(void);
 +extern uint8_t rip_distance_apply(struct rip *rip, struct rip_info *rinfo);
 +extern void rip_redistribute_enable(struct rip *rip);
 +extern void rip_redistribute_disable(struct rip *rip);
  
  extern int rip_route_rte(struct rip_info *rinfo);
 -extern struct rip_info *rip_ecmp_add(struct rip_info *);
 -extern struct rip_info *rip_ecmp_replace(struct rip_info *);
 -extern struct rip_info *rip_ecmp_delete(struct rip_info *);
 -
 -extern struct rip_offset_list *rip_offset_list_new(const char *ifname);
 +extern struct rip_info *rip_ecmp_add(struct rip *rip,
 +                                   struct rip_info *rinfo_new);
 +extern struct rip_info *rip_ecmp_replace(struct rip *rip,
 +                                       struct rip_info *rinfo_new);
 +extern struct rip_info *rip_ecmp_delete(struct rip *rip,
 +                                      struct rip_info *rinfo);
 +
 +extern struct rip_offset_list *rip_offset_list_new(struct rip *rip,
 +                                                 const char *ifname);
  extern void offset_list_del(struct rip_offset_list *offset);
 -extern struct rip_offset_list *rip_offset_list_lookup(const char *ifname);
 +extern struct rip_offset_list *rip_offset_list_lookup(struct rip *rip,
 +                                                    const char *ifname);
  extern int rip_offset_list_apply_in(struct prefix_ipv4 *, struct interface *,
                                    uint32_t *);
  extern int rip_offset_list_apply_out(struct prefix_ipv4 *, struct interface *,
index 804fa8dea670a441d88e1f57dde23120c4118935,23a48031704a45b8b48801814116146222647b12..e95c0e95d672395000498b75d535717e99260fe6
@@@ -64,21 -57,13 +64,21 @@@ DEFPY_NOSH (router_ripng
  
  DEFPY (no_router_ripng,
         no_router_ripng_cmd,
 -       "no router ripng",
 +       "no router ripng [vrf NAME]",
         NO_STR
         "Enable a routing process\n"
 -       "Make RIPng instance command\n")
 +       "Make RIPng instance command\n"
 +       VRF_CMD_HELP_STR)
  {
 -      nb_cli_enqueue_change(vty, "/frr-ripngd:ripngd/instance", NB_OP_DESTROY,
 -                            NULL);
 +      char xpath[XPATH_MAXLEN];
 +
 +      /* Build RIPng instance XPath. */
 +      if (!vrf)
 +              vrf = VRF_DEFAULT_NAME;
 +      snprintf(xpath, sizeof(xpath), "/frr-ripngd:ripngd/instance[vrf='%s']",
 +               vrf);
 +
-       nb_cli_enqueue_change(vty, xpath, NB_OP_DELETE, NULL);
++      nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
  
        return nb_cli_apply_changes(vty, NULL);
  }
Simple merge
index 37b163c5e41191935321852714b42a5736b1e9d4,10e19efe77f6962fc39cea79f2378adcb0a52f1c..c755bd83ce5c4d757e2bb80644f18c982375d13e
@@@ -35,6 -35,6 +35,7 @@@
  #include "privs.h"
  #include "sigevent.h"
  #include "vrf.h"
++#include "if_rmap.h"
  #include "libfrr.h"
  
  #include "ripngd/ripngd.h"
@@@ -82,7 -82,8 +83,8 @@@ static void sigint(void
  {
        zlog_notice("Terminating on signal");
  
 -      ripng_clean();
 -
 +      ripng_vrf_terminate();
++      if_rmap_terminate();
        ripng_zebra_stop();
        frr_fini();
        exit(0);
index dda57a31feddebf82ad8a85a0ba92b4b3ee50189,b6998b4ddbd20f20ffaf68b233e2b9b2ba151e1f..66b9e13d7f58a8eb5f21e9d7a119b821c874a9d9
@@@ -1013,10 -845,7 +1013,10 @@@ const struct frr_yang_module_info frr_r
                {
                        .xpath = "/frr-ripngd:ripngd/instance",
                        .cbs.create = ripngd_instance_create,
-                       .cbs.delete = ripngd_instance_delete,
+                       .cbs.destroy = ripngd_instance_delete,
 +                      .cbs.get_next = ripngd_instance_get_next,
 +                      .cbs.get_keys = ripngd_instance_get_keys,
 +                      .cbs.lookup_entry = ripngd_instance_lookup_entry,
                        .cbs.cli_show = cli_show_router_ripng,
                },
                {
diff --cc ripngd/ripngd.c
index c3aa9d8dbfafd4ae6a6bb874dbbb3ed33b26e96d,9faebcf0d0e54e8fa3f4f2d26be3407c4dcc1fcb..b36cee2c5d5a1f156b3c0654e72d577362e0d48f
@@@ -52,22 -57,12 +52,23 @@@ static void ripng_distribute_update(str
  
  /* Prototypes. */
  void ripng_output_process(struct interface *, struct sockaddr_in6 *, int);
 -
 +static void ripng_instance_enable(struct ripng *ripng, struct vrf *vrf,
 +                                int sock);
 +static void ripng_instance_disable(struct ripng *ripng);
  int ripng_triggered_update(struct thread *);
 -
+ static void ripng_if_rmap_update(struct if_rmap_ctx *ctx,
+                                struct if_rmap *if_rmap);
  
 +/* Generate rb-tree of RIPng instances. */
 +static inline int ripng_instance_compare(const struct ripng *a,
 +                                       const struct ripng *b)
 +{
 +      return strcmp(a->vrf_name, b->vrf_name);
 +}
 +RB_GENERATE(ripng_instance_head, ripng, entry, ripng_instance_compare)
 +
 +struct ripng_instance_head ripng_instances = RB_INITIALIZER(&ripng_instances);
 +
  /* RIPng next hop specification. */
  struct ripng_nexthop {
        enum ripng_nexthop_type {
@@@ -1895,18 -1820,19 +1896,22 @@@ struct ripng *ripng_create(const char *
        distribute_list_delete_hook(ripng->distribute_ctx,
                                    ripng_distribute_update);
  
 -      ripng->if_rmap_ctx = if_rmap_ctx_create(VRF_DEFAULT_NAME);
+       /* if rmap install. */
++      ripng->if_rmap_ctx = if_rmap_ctx_create(vrf_name);
+       if_rmap_hook_add(ripng->if_rmap_ctx, ripng_if_rmap_update);
+       if_rmap_hook_delete(ripng->if_rmap_ctx, ripng_if_rmap_update);
  
 -      /* Make socket. */
 -      ripng->sock = socket;
 +      /* Enable the routing instance if possible. */
 +      if (vrf && vrf_is_enabled(vrf))
 +              ripng_instance_enable(ripng, vrf, socket);
 +      else {
 +              ripng->vrf = NULL;
 +              ripng->sock = -1;
 +      }
  
 -      /* Threads. */
 -      ripng_event(RIPNG_READ, ripng->sock);
 -      ripng_event(RIPNG_UPDATE_EVENT, 1);
 +      RB_INSERT(ripng_instance_head, &ripng_instances, ripng);
  
 -      return 0;
 +      return ripng;
  }
  
  /* Send RIPng request to the interface. */
@@@ -2408,25 -2301,18 +2413,24 @@@ void ripng_ecmp_disable(struct ripng *r
  /* RIPng configuration write function. */
  static int ripng_config_write(struct vty *vty)
  {
 -      struct lyd_node *dnode;
 +      struct ripng *ripng;
        int write = 0;
  
 -      dnode = yang_dnode_get(running_config->dnode,
 -                             "/frr-ripngd:ripngd/instance");
 -      if (dnode) {
 -              nb_cli_show_dnode_cmds(vty, dnode, false);
 +      RB_FOREACH(ripng, ripng_instance_head, &ripng_instances) {
 +              char xpath[XPATH_MAXLEN];
 +              struct lyd_node *dnode;
  
 -              config_write_distribute(vty,
 -                                      ripng->distribute_ctx);
 +              snprintf(xpath, sizeof(xpath),
 +                       "/frr-ripngd:ripngd/instance[vrf='%s']",
 +                       ripng->vrf_name);
  
-               if (strmatch(ripng->vrf_name, VRF_DEFAULT_NAME))
-                       config_write_if_rmap(vty);
 +              dnode = yang_dnode_get(running_config->dnode, xpath);
 +              assert(dnode);
 +
 +              nb_cli_show_dnode_cmds(vty, dnode, false);
 +
 +              config_write_distribute(vty, ripng->distribute_ctx);
+               config_write_if_rmap(vty, ripng->if_rmap_ctx);
  
                write = 1;
        }
@@@ -2526,42 -2410,94 +2530,48 @@@ static void ripng_distribute_update_all
  }
  
  /* delete all the added ripng routes. */
 -void ripng_clean(void)
 +void ripng_clean(struct ripng *ripng)
  {
 -      int i;
 -      struct agg_node *rp;
 -      struct ripng_info *rinfo;
 -      struct ripng_aggregate *aggregate;
 -      struct list *list = NULL;
 -      struct listnode *listnode = NULL;
 -
 -      if (ripng) {
 -              /* Clear RIPng routes */
 -              for (rp = agg_route_top(ripng->table); rp;
 -                   rp = agg_route_next(rp)) {
 -                      if ((list = rp->info) != NULL) {
 -                              rinfo = listgetdata(listhead(list));
 -                              if (ripng_route_rte(rinfo))
 -                                      ripng_zebra_ipv6_delete(rp);
 -
 -                              for (ALL_LIST_ELEMENTS_RO(list, listnode,
 -                                                        rinfo)) {
 -                                      RIPNG_TIMER_OFF(rinfo->t_timeout);
 -                                      RIPNG_TIMER_OFF(
 -                                              rinfo->t_garbage_collect);
 -                                      ripng_info_free(rinfo);
 -                              }
 -                              list_delete(&list);
 -                              rp->info = NULL;
 -                              agg_unlock_node(rp);
 -                      }
 -
 -                      if ((aggregate = rp->aggregate) != NULL) {
 -                              ripng_aggregate_free(aggregate);
 -                              rp->aggregate = NULL;
 -                              agg_unlock_node(rp);
 -                      }
 -              }
 -
 -              /* Cancel the RIPng timers */
 -              RIPNG_TIMER_OFF(ripng->t_update);
 -              RIPNG_TIMER_OFF(ripng->t_triggered_update);
 -              RIPNG_TIMER_OFF(ripng->t_triggered_interval);
 -
 -              /* Cancel the read thread */
 -              if (ripng->t_read) {
 -                      thread_cancel(ripng->t_read);
 -                      ripng->t_read = NULL;
 -              }
 -
 -              /* Close the RIPng socket */
 -              if (ripng->sock >= 0) {
 -                      close(ripng->sock);
 -                      ripng->sock = -1;
 -              }
 -
 -              for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
 -                      if (ripng->route_map[i].name)
 -                              free(ripng->route_map[i].name);
 -
 -              agg_table_finish(ripng->table);
 -
 -              stream_free(ripng->ibuf);
 -              stream_free(ripng->obuf);
 -
 -              distribute_list_delete(&ripng->distribute_ctx);
 -              XFREE(MTYPE_RIPNG, ripng);
 -              ripng = NULL;
 -      } /* if (ripng) */
 -
 -      ripng_clean_network();
 -      ripng_passive_interface_clean();
 -      ripng_offset_clean();
 -      ripng_interface_clean();
 -      ripng_redistribute_clean();
 -      if_rmap_terminate();
 +      if (ripng->enabled)
 +              ripng_instance_disable(ripng);
 +
 +      for (int i = 0; i < ZEBRA_ROUTE_MAX; i++)
 +              if (ripng->redist[i].route_map.name)
 +                      free(ripng->redist[i].route_map.name);
 +
 +      agg_table_finish(ripng->table);
 +      list_delete(&ripng->peer_list);
 +      distribute_list_delete(&ripng->distribute_ctx);
++      if_rmap_ctx_delete(ripng->if_rmap_ctx);
 +
 +      stream_free(ripng->ibuf);
 +      stream_free(ripng->obuf);
 +
 +      ripng_clean_network(ripng);
 +      ripng_passive_interface_clean(ripng);
 +      vector_free(ripng->enable_if);
 +      agg_table_finish(ripng->enable_network);
 +      vector_free(ripng->passive_interface);
 +      list_delete(&ripng->offset_list_master);
 +      ripng_interface_clean(ripng);
 +
 +      RB_REMOVE(ripng_instance_head, &ripng_instances, ripng);
 +      XFREE(MTYPE_RIPNG_VRF_NAME, ripng->vrf_name);
 +      XFREE(MTYPE_RIPNG, ripng);
  }
  
- static void ripng_if_rmap_update(struct if_rmap *if_rmap)
+ static void ripng_if_rmap_update(struct if_rmap_ctx *ctx,
+                                struct if_rmap *if_rmap)
  {
-       struct interface *ifp;
+       struct interface *ifp = NULL;
        struct ripng_interface *ri;
        struct route_map *rmap;
+       struct vrf *vrf = NULL;
  
-       ifp = if_lookup_by_name(if_rmap->ifname, VRF_DEFAULT);
+       if (ctx->name)
+               vrf = vrf_lookup_by_name(ctx->name);
+       if (vrf)
+               ifp = if_lookup_by_name(if_rmap->ifname, vrf->vrf_id);
        if (ifp == NULL)
                return;
  
  
  void ripng_if_rmap_update_interface(struct interface *ifp)
  {
++      struct ripng_interface *ri = ifp->info;
++      struct ripng *ripng = ri->ripng;
        struct if_rmap *if_rmap;
+       struct if_rmap_ctx *ctx;
  
-       if_rmap = if_rmap_lookup(ifp->name);
 -      if (ifp->vrf_id != VRF_DEFAULT)
 -              return;
+       if (!ripng)
+               return;
+       ctx = ripng->if_rmap_ctx;
+       if (!ctx)
+               return;
+       if_rmap = if_rmap_lookup(ctx, ifp->name);
        if (if_rmap)
-               ripng_if_rmap_update(if_rmap);
+               ripng_if_rmap_update(ctx, if_rmap);
  }
  
 -static void ripng_routemap_update_redistribute(void)
 +static void ripng_routemap_update_redistribute(struct ripng *ripng)
  {
 -      int i;
 -
 -      if (ripng) {
 -              for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
 -                      if (ripng->route_map[i].name) {
 -                              ripng->route_map[i].map =
 -                                      route_map_lookup_by_name(
 -                                              ripng->route_map[i].name);
 -                              route_map_counter_increment(
 -                                      ripng->route_map[i].map);
 -                      }
 +      for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
-               if (ripng->redist[i].route_map.name)
++              if (ripng->redist[i].route_map.name) {
 +                      ripng->redist[i].route_map.map =
 +                              route_map_lookup_by_name(
 +                                      ripng->redist[i].route_map.name);
++                      route_map_counter_increment(
++                              ripng->redist[i].route_map.map);
+               }
        }
  }
  
diff --cc ripngd/ripngd.h
index b38e6b3a957e8c94a758092f44a379d30f9ed91c,3f0ef13a05b81cea53911422464d1e5298037c89..dcc61ae58a0e6249b2d98011179a962d6961c262
@@@ -162,9 -132,10 +162,12 @@@ struct ripng 
  
        /* For distribute-list container */
        struct distribute_ctx *distribute_ctx;
+       /* For if_rmap container */
+       struct if_rmap_ctx *if_rmap_ctx;
  };
 +RB_HEAD(ripng_instance_head, ripng);
 +RB_PROTOTYPE(ripng_instance_head, ripng, entry, ripng_instance_compare)
  
  /* Routing table entry. */
  struct rte {
diff --cc vtysh/vtysh.c
Simple merge