]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_vty.c
Merge pull request #3384 from donaldsharp/topotests
[mirror_frr.git] / zebra / zebra_vty.c
index 6d30372261dea8041aaaba9cb844136a9fe3b7a6..ad6bfe5751dff0c2948a979383a6fb257e90125d 100644 (file)
 #include "srcdest_table.h"
 #include "vxlan.h"
 
+#include "zebra/zebra_router.h"
 #include "zebra/zserv.h"
 #include "zebra/zebra_vrf.h"
 #include "zebra/zebra_mpls.h"
 #include "zebra/zebra_rnh.h"
 #include "zebra/redistribute.h"
 #include "zebra/zebra_routemap.h"
-#include "zebra/zebra_static.h"
 #include "lib/json.h"
 #include "zebra/zebra_vxlan.h"
 #ifndef VTYSH_EXTRACT_PL
@@ -56,7 +56,7 @@
 extern int allow_delete;
 
 static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
-                           safi_t safi, bool use_fib, uint8_t use_json,
+                           safi_t safi, bool use_fib, bool use_json,
                            route_tag_t tag,
                            const struct prefix *longer_prefix_p,
                            bool supernets_only, int type,
@@ -68,582 +68,6 @@ static void vty_show_ip_route_summary(struct vty *vty,
 static void vty_show_ip_route_summary_prefix(struct vty *vty,
                                             struct route_table *table);
 
-/*
- * special macro to allow us to get the correct zebra_vrf
- */
-#define ZEBRA_DECLVAR_CONTEXT(A, B)                                            \
-       struct vrf *A = VTY_GET_CONTEXT(vrf);                                  \
-       struct zebra_vrf *B = (vrf) ? vrf->info : NULL;
-
-/* VNI range as per RFC 7432 */
-#define CMD_VNI_RANGE "(1-16777215)"
-
-struct static_hold_route {
-       char *vrf_name;
-       char *nhvrf_name;
-       afi_t afi;
-       safi_t safi;
-       char *dest_str;
-       char *mask_str;
-       char *src_str;
-       char *gate_str;
-       char *ifname;
-       char *flag_str;
-       char *tag_str;
-       char *distance_str;
-       char *label_str;
-       char *table_str;
-
-       /* processed & masked destination, used for config display */
-       struct prefix dest;
-};
-
-static struct list *static_list;
-
-static int static_list_compare_helper(const char *s1, const char *s2)
-{
-       /* Are Both NULL */
-       if (s1 == s2)
-               return 0;
-
-       if (!s1 && s2)
-               return -1;
-
-       if (s1 && !s2)
-               return 1;
-
-       return strcmp(s1, s2);
-}
-
-static void static_list_delete(struct static_hold_route *shr)
-{
-       if (shr->vrf_name)
-               XFREE(MTYPE_STATIC_ROUTE, shr->vrf_name);
-       if (shr->nhvrf_name)
-               XFREE(MTYPE_STATIC_ROUTE, shr->nhvrf_name);
-       if (shr->dest_str)
-               XFREE(MTYPE_STATIC_ROUTE, shr->dest_str);
-       if (shr->mask_str)
-               XFREE(MTYPE_STATIC_ROUTE, shr->mask_str);
-       if (shr->src_str)
-               XFREE(MTYPE_STATIC_ROUTE, shr->src_str);
-       if (shr->gate_str)
-               XFREE(MTYPE_STATIC_ROUTE, shr->gate_str);
-       if (shr->ifname)
-               XFREE(MTYPE_STATIC_ROUTE, shr->ifname);
-       if (shr->flag_str)
-               XFREE(MTYPE_STATIC_ROUTE, shr->flag_str);
-       if (shr->tag_str)
-               XFREE(MTYPE_STATIC_ROUTE, shr->tag_str);
-       if (shr->distance_str)
-               XFREE(MTYPE_STATIC_ROUTE, shr->distance_str);
-       if (shr->label_str)
-               XFREE(MTYPE_STATIC_ROUTE, shr->label_str);
-
-       XFREE(MTYPE_STATIC_ROUTE, shr);
-}
-
-static int static_list_compare(void *arg1, void *arg2)
-{
-       struct static_hold_route *shr1 = arg1;
-       struct static_hold_route *shr2 = arg2;
-       int ret;
-
-       ret = strcmp(shr1->vrf_name, shr2->vrf_name);
-       if (ret)
-               return ret;
-
-       ret = strcmp(shr1->nhvrf_name, shr2->nhvrf_name);
-       if (ret)
-               return ret;
-
-       ret = shr1->afi - shr2->afi;
-       if (ret)
-               return ret;
-
-       ret = shr1->safi - shr2->safi;
-       if (ret)
-               return ret;
-
-       ret = prefix_cmp(&shr1->dest, &shr2->dest);
-       if (ret)
-               return ret;
-
-       ret = static_list_compare_helper(shr1->src_str, shr2->src_str);
-       if (ret)
-               return ret;
-
-       ret = static_list_compare_helper(shr1->gate_str, shr2->gate_str);
-       if (ret)
-               return ret;
-
-       ret = static_list_compare_helper(shr1->ifname, shr2->ifname);
-       if (ret)
-               return ret;
-
-       ret = static_list_compare_helper(shr1->flag_str, shr2->flag_str);
-       if (ret)
-               return ret;
-
-       ret = static_list_compare_helper(shr1->tag_str, shr2->tag_str);
-       if (ret)
-               return ret;
-
-       ret = static_list_compare_helper(shr1->distance_str,
-                                        shr2->distance_str);
-       if (ret)
-               return ret;
-
-       ret = static_list_compare_helper(shr1->table_str,
-                                        shr2->table_str);
-       if (ret)
-               return ret;
-
-       return static_list_compare_helper(shr1->label_str, shr2->label_str);
-}
-
-
-/* General function for static route. */
-static int zebra_static_route_holdem(
-       struct zebra_vrf *zvrf, struct zebra_vrf *nh_zvrf, afi_t afi,
-       safi_t safi, const char *negate, struct prefix *dest,
-       const char *dest_str, const char *mask_str, const char *src_str,
-       const char *gate_str, const char *ifname, const char *flag_str,
-       const char *tag_str, const char *distance_str, const char *label_str,
-       const char *table_str)
-{
-       struct static_hold_route *shr, *lookup;
-       struct listnode *node;
-
-       zlog_warn("Static Route to %s not installed currently because dependent config not fully available",
-                 dest_str);
-
-       shr = XCALLOC(MTYPE_STATIC_ROUTE, sizeof(*shr));
-       shr->vrf_name = XSTRDUP(MTYPE_STATIC_ROUTE, zvrf->vrf->name);
-       shr->nhvrf_name = XSTRDUP(MTYPE_STATIC_ROUTE, nh_zvrf->vrf->name);
-       shr->afi = afi;
-       shr->safi = safi;
-       if (dest)
-               prefix_copy(&shr->dest, dest);
-       if (dest_str)
-               shr->dest_str = XSTRDUP(MTYPE_STATIC_ROUTE, dest_str);
-       if (mask_str)
-               shr->mask_str = XSTRDUP(MTYPE_STATIC_ROUTE, mask_str);
-       if (src_str)
-               shr->src_str = XSTRDUP(MTYPE_STATIC_ROUTE, src_str);
-       if (gate_str)
-               shr->gate_str = XSTRDUP(MTYPE_STATIC_ROUTE, gate_str);
-       if (ifname)
-               shr->ifname = XSTRDUP(MTYPE_STATIC_ROUTE, ifname);
-       if (flag_str)
-               shr->flag_str = XSTRDUP(MTYPE_STATIC_ROUTE, flag_str);
-       if (tag_str)
-               shr->tag_str = XSTRDUP(MTYPE_STATIC_ROUTE, tag_str);
-       if (distance_str)
-               shr->distance_str = XSTRDUP(MTYPE_STATIC_ROUTE, distance_str);
-       if (label_str)
-               shr->label_str = XSTRDUP(MTYPE_STATIC_ROUTE, label_str);
-       if (table_str)
-               shr->table_str = XSTRDUP(MTYPE_STATIC_ROUTE, table_str);
-
-       for (ALL_LIST_ELEMENTS_RO(static_list, node, lookup)) {
-               if (static_list_compare(shr, lookup) == 0)
-                       break;
-       }
-
-       if (lookup) {
-               if (negate) {
-                       listnode_delete(static_list, lookup);
-                       static_list_delete(shr);
-                       static_list_delete(lookup);
-
-                       return CMD_SUCCESS;
-               }
-
-               /*
-                * If a person enters the same line again
-                * we need to silently accept it
-                */
-               goto shr_cleanup;
-       }
-
-       if (!negate) {
-               listnode_add_sort(static_list, shr);
-               return CMD_SUCCESS;
-       }
-
-shr_cleanup:
-       XFREE(MTYPE_STATIC_ROUTE, shr->nhvrf_name);
-       XFREE(MTYPE_STATIC_ROUTE, shr->vrf_name);
-       XFREE(MTYPE_STATIC_ROUTE, shr);
-
-       return CMD_SUCCESS;
-}
-
-static int zebra_static_route_leak(
-       struct vty *vty, struct zebra_vrf *zvrf, struct zebra_vrf *nh_zvrf,
-       afi_t afi, safi_t safi, const char *negate, const char *dest_str,
-       const char *mask_str, const char *src_str, const char *gate_str,
-       const char *ifname, const char *flag_str, const char *tag_str,
-       const char *distance_str, const char *label_str, const char *table_str)
-{
-       int ret;
-       uint8_t distance;
-       struct prefix p, src;
-       struct prefix_ipv6 *src_p = NULL;
-       union g_addr gate;
-       union g_addr *gatep = NULL;
-       struct in_addr mask;
-       enum static_blackhole_type bh_type = 0;
-       route_tag_t tag = 0;
-       uint8_t type;
-       struct static_nh_label snh_label;
-       uint32_t table_id = 0;
-
-       ret = str2prefix(dest_str, &p);
-       if (ret <= 0) {
-               if (vty)
-                       vty_out(vty, "%% Malformed address\n");
-               else
-                       zlog_warn("%s: Malformed address: %s",
-                                 __PRETTY_FUNCTION__, dest_str);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       switch (afi) {
-       case AFI_IP:
-               /* Cisco like mask notation. */
-               if (mask_str) {
-                       ret = inet_aton(mask_str, &mask);
-                       if (ret == 0) {
-                               if (vty)
-                                       vty_out(vty, "%% Malformed address\n");
-                               else
-                                       zlog_warn("%s: Malformed address: %s",
-                                                 __PRETTY_FUNCTION__,
-                                                 mask_str);
-                               return CMD_WARNING_CONFIG_FAILED;
-                       }
-                       p.prefixlen = ip_masklen(mask);
-               }
-               break;
-       case AFI_IP6:
-               /* srcdest routing */
-               if (src_str) {
-                       ret = str2prefix(src_str, &src);
-                       if (ret <= 0 || src.family != AF_INET6) {
-                               if (vty)
-                                       vty_out(vty,
-                                               "%% Malformed source address\n");
-                               else
-                                       zlog_warn(
-                                               "%s: Malformed Source address: %s",
-                                               __PRETTY_FUNCTION__, src_str);
-                               return CMD_WARNING_CONFIG_FAILED;
-                       }
-                       src_p = (struct prefix_ipv6 *)&src;
-               }
-               break;
-       default:
-               break;
-       }
-
-       /* Apply mask for given prefix. */
-       apply_mask(&p);
-
-       if (zvrf->vrf->vrf_id == VRF_UNKNOWN
-           || nh_zvrf->vrf->vrf_id == VRF_UNKNOWN) {
-               vrf_set_user_cfged(zvrf->vrf);
-               return zebra_static_route_holdem(
-                       zvrf, nh_zvrf, afi, safi, negate, &p, dest_str,
-                       mask_str, src_str, gate_str, ifname, flag_str, tag_str,
-                       distance_str, label_str, table_str);
-       }
-       if (table_str) {
-               /* table configured. check consistent with vrf config
-                */
-               if (zvrf->table_id != RT_TABLE_MAIN &&
-                   zvrf->table_id != zebrad.rtm_table_default) {
-                       if (vty)
-                               vty_out(vty,
-                                   "%% Table %s overlaps vrf table %u\n",
-                                   table_str, zvrf->table_id);
-                       else
-                               zlog_warn(
-                                   "%s: Table %s overlaps vrf table %u",
-                                   __PRETTY_FUNCTION__,
-                                   table_str, zvrf->table_id);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
-
-       /* Administrative distance. */
-       if (distance_str)
-               distance = atoi(distance_str);
-       else
-               distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
-
-       /* tag */
-       if (tag_str)
-               tag = strtoul(tag_str, NULL, 10);
-
-       /* Labels */
-       memset(&snh_label, 0, sizeof(struct static_nh_label));
-       if (label_str) {
-               if (!mpls_enabled) {
-                       if (vty)
-                               vty_out(vty,
-                                       "%% MPLS not turned on in kernel, ignoring command\n");
-                       else
-                               zlog_warn(
-                                       "%s: MPLS not turned on in kernel ignoring static route to %s",
-                                       __PRETTY_FUNCTION__, dest_str);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-               int rc = mpls_str2label(label_str, &snh_label.num_labels,
-                                       snh_label.label);
-               if (rc < 0) {
-                       switch (rc) {
-                       case -1:
-                               if (vty)
-                                       vty_out(vty, "%% Malformed label(s)\n");
-                               else
-                                       zlog_warn(
-                                               "%s: Malformed labels specified for route %s",
-                                               __PRETTY_FUNCTION__, dest_str);
-                               break;
-                       case -2:
-                               if (vty)
-                                       vty_out(vty,
-                                               "%% Cannot use reserved label(s) (%d-%d)\n",
-                                               MPLS_LABEL_RESERVED_MIN,
-                                               MPLS_LABEL_RESERVED_MAX);
-                               else
-                                       zlog_warn(
-                                               "%s: Cannot use reserved labels (%d-%d) for %s",
-                                               __PRETTY_FUNCTION__,
-                                               MPLS_LABEL_RESERVED_MIN,
-                                               MPLS_LABEL_RESERVED_MAX,
-                                               dest_str);
-                               break;
-                       case -3:
-                               if (vty)
-                                       vty_out(vty,
-                                               "%% Too many labels. Enter %d or fewer\n",
-                                               MPLS_MAX_LABELS);
-                               else
-                                       zlog_warn(
-                                               "%s: Too many labels, Enter %d or fewer for %s",
-                                               __PRETTY_FUNCTION__,
-                                               MPLS_MAX_LABELS, dest_str);
-                               break;
-                       }
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
-       /* TableID */
-       if (table_str)
-               table_id = atol(table_str);
-
-       /* Null0 static route.  */
-       if (ifname != NULL) {
-               if (strncasecmp(ifname, "Null0", strlen(ifname)) == 0
-                   || strncasecmp(ifname, "reject", strlen(ifname)) == 0
-                   || strncasecmp(ifname, "blackhole", strlen(ifname)) == 0) {
-                       if (vty)
-                               vty_out(vty,
-                                       "%% Nexthop interface cannot be Null0, reject or blackhole\n");
-                       else
-                               zlog_warn(
-                                       "%s: Nexthop interface cannot be Null0, reject or blackhole for %s",
-                                       __PRETTY_FUNCTION__, dest_str);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
-
-       /* Route flags */
-       if (flag_str) {
-               switch (flag_str[0]) {
-               case 'r':
-                       bh_type = STATIC_BLACKHOLE_REJECT;
-                       break;
-               case 'b':
-                       bh_type = STATIC_BLACKHOLE_DROP;
-                       break;
-               case 'N':
-                       bh_type = STATIC_BLACKHOLE_NULL;
-                       break;
-               default:
-                       if (vty)
-                               vty_out(vty, "%% Malformed flag %s \n",
-                                       flag_str);
-                       else
-                               zlog_warn("%s: Malformed flag %s for %s",
-                                         __PRETTY_FUNCTION__, flag_str,
-                                         dest_str);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
-
-       if (gate_str) {
-               if (inet_pton(afi2family(afi), gate_str, &gate) != 1) {
-                       if (vty)
-                               vty_out(vty,
-                                       "%% Malformed nexthop address %s\n",
-                                       gate_str);
-                       else
-                               zlog_warn(
-                                       "%s: Malformed nexthop address %s for %s",
-                                       __PRETTY_FUNCTION__, gate_str,
-                                       dest_str);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-               gatep = &gate;
-       }
-
-       if (gate_str == NULL && ifname == NULL)
-               type = STATIC_BLACKHOLE;
-       else if (gate_str && ifname) {
-               if (afi == AFI_IP)
-                       type = STATIC_IPV4_GATEWAY_IFNAME;
-               else
-                       type = STATIC_IPV6_GATEWAY_IFNAME;
-       } else if (ifname)
-               type = STATIC_IFNAME;
-       else {
-               if (afi == AFI_IP)
-                       type = STATIC_IPV4_GATEWAY;
-               else
-                       type = STATIC_IPV6_GATEWAY;
-       }
-
-       if (!negate) {
-               static_add_route(afi, safi, type, &p, src_p, gatep, ifname,
-                                bh_type, tag, distance, zvrf, nh_zvrf,
-                                &snh_label, table_id);
-               /* Mark as having FRR configuration */
-               vrf_set_user_cfged(zvrf->vrf);
-       } else {
-               static_delete_route(afi, safi, type, &p, src_p, gatep, ifname,
-                                   tag, distance, zvrf, &snh_label, table_id);
-               /* If no other FRR config for this VRF, mark accordingly. */
-               if (!zebra_vrf_has_config(zvrf))
-                       vrf_reset_user_cfged(zvrf->vrf);
-       }
-
-       return CMD_SUCCESS;
-}
-
-static struct zebra_vrf *zebra_vty_get_unknown_vrf(struct vty *vty,
-                                                  const char *vrf_name)
-{
-       struct zebra_vrf *zvrf;
-       struct vrf *vrf;
-
-       zvrf = zebra_vrf_lookup_by_name(vrf_name);
-
-       if (zvrf)
-               return zvrf;
-
-       vrf = vrf_get(VRF_UNKNOWN, vrf_name);
-       if (!vrf) {
-               vty_out(vty, "%% Could not create vrf %s\n", vrf_name);
-               return NULL;
-       }
-       zvrf = vrf->info;
-       if (!zvrf) {
-               vty_out(vty, "%% Could not create vrf-info %s\n",
-                       vrf_name);
-               return NULL;
-       }
-       /* Mark as having FRR configuration */
-       vrf_set_user_cfged(vrf);
-
-       return zvrf;
-}
-
-static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
-                             const char *negate, const char *dest_str,
-                             const char *mask_str, const char *src_str,
-                             const char *gate_str, const char *ifname,
-                             const char *flag_str, const char *tag_str,
-                             const char *distance_str, const char *vrf_name,
-                             const char *label_str, const char *table_str)
-{
-       struct zebra_vrf *zvrf;
-
-       /* VRF id */
-       zvrf = zebra_vrf_lookup_by_name(vrf_name);
-
-       /* When trying to delete, the VRF must exist. */
-       if (negate && !zvrf) {
-               vty_out(vty, "%% vrf %s is not defined\n", vrf_name);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* When trying to create, create the VRF if it doesn't exist.
-        * Note: The VRF isn't active until we hear about it from the kernel.
-        */
-       if (!zvrf) {
-               zvrf = zebra_vty_get_unknown_vrf(vty, vrf_name);
-               if (!zvrf)
-                       return CMD_WARNING_CONFIG_FAILED;
-       }
-       return zebra_static_route_leak(
-               vty, zvrf, zvrf, afi, safi, negate, dest_str, mask_str, src_str,
-               gate_str, ifname, flag_str, tag_str, distance_str, label_str,
-               table_str);
-}
-
-void static_config_install_delayed_routes(struct zebra_vrf *zvrf)
-{
-       struct listnode *node, *nnode;
-       struct static_hold_route *shr;
-       struct zebra_vrf *ozvrf, *nh_zvrf;
-       int installed;
-
-       for (ALL_LIST_ELEMENTS(static_list, node, nnode, shr)) {
-               ozvrf = zebra_vrf_lookup_by_name(shr->vrf_name);
-               nh_zvrf = zebra_vrf_lookup_by_name(shr->nhvrf_name);
-
-               if (ozvrf != zvrf && nh_zvrf != zvrf)
-                       continue;
-
-               if (ozvrf->vrf->vrf_id == VRF_UNKNOWN
-                   || nh_zvrf->vrf->vrf_id == VRF_UNKNOWN)
-                       continue;
-
-               installed = zebra_static_route_leak(
-                       NULL, ozvrf, nh_zvrf, shr->afi, shr->safi, NULL,
-                       shr->dest_str, shr->mask_str, shr->src_str,
-                       shr->gate_str, shr->ifname, shr->flag_str, shr->tag_str,
-                       shr->distance_str, shr->label_str, shr->table_str);
-
-               if (installed != CMD_SUCCESS)
-                       zlog_debug(
-                               "%s: Attempt to install %s as a route and it was rejected",
-                               __PRETTY_FUNCTION__, shr->dest_str);
-               listnode_delete(static_list, shr);
-               static_list_delete(shr);
-       }
-}
-/* Static unicast routes for multicast RPF lookup. */
-DEFPY (ip_mroute_dist,
-       ip_mroute_dist_cmd,
-       "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [(1-255)$distance]",
-       NO_STR
-       IP_STR
-       "Configure static unicast route into MRIB for multicast RPF lookup\n"
-       "IP destination prefix (e.g. 10.0.0.0/8)\n"
-       "Nexthop address\n"
-       "Nexthop interface name\n"
-       "Distance\n")
-{
-       return zebra_static_route(vty, AFI_IP, SAFI_MULTICAST, no, prefix_str,
-                                 NULL, NULL, gate_str, ifname, NULL, NULL,
-                                 distance_str, NULL, NULL, NULL);
-}
-
 DEFUN (ip_multicast_mode,
        ip_multicast_mode_cmd,
        "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
@@ -702,7 +126,7 @@ DEFUN (show_ip_rpf,
        "Display RPF information for multicast source\n"
        JSON_STR)
 {
-       int uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST,
                                false, uj, 0, NULL, false, 0, 0);
 }
@@ -737,343 +161,6 @@ DEFUN (show_ip_rpf_addr,
        return CMD_SUCCESS;
 }
 
-/* Static route configuration.  */
-DEFPY(ip_route_blackhole,
-      ip_route_blackhole_cmd,
-      "[no] ip route\
-       <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask>                        \
-       <reject|blackhole>$flag                                               \
-       [{                                                                    \
-         tag (1-4294967295)                                                  \
-         |(1-255)$distance                                                   \
-         |vrf NAME                                                           \
-         |label WORD                                                         \
-         |table (1-4294967295)                                               \
-          }]",
-      NO_STR IP_STR
-      "Establish static routes\n"
-      "IP destination prefix (e.g. 10.0.0.0/8)\n"
-      "IP destination prefix\n"
-      "IP destination prefix mask\n"
-      "Emit an ICMP unreachable when matched\n"
-      "Silently discard pkts when matched\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this route\n"
-      VRF_CMD_HELP_STR
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n")
-{
-       if (table_str && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
-                                 mask_str, NULL, NULL, NULL, flag, tag_str,
-                                 distance_str, vrf, label, table_str);
-}
-
-DEFPY(ip_route_blackhole_vrf,
-      ip_route_blackhole_vrf_cmd,
-      "[no] ip route\
-       <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask>                        \
-       <reject|blackhole>$flag                                               \
-       [{                                                                    \
-         tag (1-4294967295)                                                  \
-         |(1-255)$distance                                                   \
-         |label WORD                                                         \
-         |table (1-4294967295)                                               \
-          }]",
-      NO_STR IP_STR
-      "Establish static routes\n"
-      "IP destination prefix (e.g. 10.0.0.0/8)\n"
-      "IP destination prefix\n"
-      "IP destination prefix mask\n"
-      "Emit an ICMP unreachable when matched\n"
-      "Silently discard pkts when matched\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this route\n"
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n")
-{
-       VTY_DECLVAR_CONTEXT(vrf, vrf);
-       struct zebra_vrf *zvrf = vrf->info;
-
-       if (table_str && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       /*
-        * Coverity is complaining that prefix could
-        * be dereferenced, but we know that prefix will
-        * valid.  Add an assert to make it happy
-        */
-       assert(prefix);
-       return zebra_static_route_leak(vty, zvrf, zvrf, AFI_IP, SAFI_UNICAST,
-                                      no, prefix, mask_str, NULL, NULL, NULL,
-                                      flag, tag_str, distance_str, label, table_str);
-}
-
-DEFPY(ip_route_address_interface,
-      ip_route_address_interface_cmd,
-      "[no] ip route\
-       <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
-       A.B.C.D$gate                                   \
-       INTERFACE$ifname                               \
-       [{                                             \
-         tag (1-4294967295)                           \
-         |(1-255)$distance                            \
-         |vrf NAME                                    \
-         |label WORD                                  \
-         |table (1-4294967295)                        \
-         |nexthop-vrf NAME                            \
-          }]",
-      NO_STR IP_STR
-      "Establish static routes\n"
-      "IP destination prefix (e.g. 10.0.0.0/8)\n"
-      "IP destination prefix\n"
-      "IP destination prefix mask\n"
-      "IP gateway address\n"
-      "IP gateway interface name. Specify 'Null0' (case-insensitive) for a \
-      null route.\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this route\n"
-      VRF_CMD_HELP_STR
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n"
-      VRF_CMD_HELP_STR)
-{
-       struct zebra_vrf *zvrf;
-       struct zebra_vrf *nh_zvrf;
-
-       const char *flag = NULL;
-       if (ifname && !strncasecmp(ifname, "Null0", 5)) {
-               flag = "Null0";
-               ifname = NULL;
-       }
-
-       zvrf = zebra_vty_get_unknown_vrf(vty, vrf);
-       if (!zvrf) {
-               vty_out(vty, "%% vrf %s is not defined\n", vrf);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (table_str && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (nexthop_vrf)
-               nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
-       else
-               nh_zvrf = zvrf;
-
-       if (!nh_zvrf) {
-               vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return zebra_static_route_leak(
-               vty, zvrf, nh_zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
-               NULL, gate_str, ifname, flag, tag_str, distance_str, label,
-               table_str);
-}
-
-DEFPY(ip_route_address_interface_vrf,
-      ip_route_address_interface_vrf_cmd,
-      "[no] ip route\
-       <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
-       A.B.C.D$gate                                   \
-       INTERFACE$ifname                               \
-       [{                                             \
-         tag (1-4294967295)                           \
-         |(1-255)$distance                            \
-         |label WORD                                  \
-         |table (1-4294967295)                        \
-         |nexthop-vrf NAME                            \
-          }]",
-      NO_STR IP_STR
-      "Establish static routes\n"
-      "IP destination prefix (e.g. 10.0.0.0/8)\n"
-      "IP destination prefix\n"
-      "IP destination prefix mask\n"
-      "IP gateway address\n"
-      "IP gateway interface name. Specify 'Null0' (case-insensitive) for a \
-      null route.\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this route\n"
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n"
-      VRF_CMD_HELP_STR)
-{
-       VTY_DECLVAR_CONTEXT(vrf, vrf);
-       const char *flag = NULL;
-       struct zebra_vrf *zvrf = vrf->info;
-       struct zebra_vrf *nh_zvrf;
-
-       if (table_str && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (ifname && !strncasecmp(ifname, "Null0", 5)) {
-               flag = "Null0";
-               ifname = NULL;
-       }
-
-       if (nexthop_vrf)
-               nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
-       else
-               nh_zvrf = zvrf;
-
-       if (!nh_zvrf) {
-               vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return zebra_static_route_leak(
-               vty, zvrf, nh_zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
-               NULL, gate_str, ifname, flag, tag_str, distance_str, label,
-               table_str);
-}
-
-DEFPY(ip_route,
-      ip_route_cmd,
-      "[no] ip route\
-       <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
-       <A.B.C.D$gate|INTERFACE$ifname>                \
-       [{                                             \
-         tag (1-4294967295)                           \
-         |(1-255)$distance                            \
-         |vrf NAME                                    \
-         |label WORD                                  \
-         |table (1-4294967295)                        \
-         |nexthop-vrf NAME                            \
-          }]",
-      NO_STR IP_STR
-      "Establish static routes\n"
-      "IP destination prefix (e.g. 10.0.0.0/8)\n"
-      "IP destination prefix\n"
-      "IP destination prefix mask\n"
-      "IP gateway address\n"
-      "IP gateway interface name\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this route\n"
-      VRF_CMD_HELP_STR
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n"
-      VRF_CMD_HELP_STR)
-{
-       struct zebra_vrf *zvrf;
-       struct zebra_vrf *nh_zvrf;
-       const char *flag = NULL;
-
-       if (table_str && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (ifname && !strncasecmp(ifname, "Null0", 5)) {
-               flag = "Null0";
-               ifname = NULL;
-       }
-
-       zvrf = zebra_vty_get_unknown_vrf(vty, vrf);
-       if (!zvrf) {
-               vty_out(vty, "%% vrf %s is not defined\n", vrf);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (nexthop_vrf)
-               nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
-       else
-               nh_zvrf = zvrf;
-
-       if (!nh_zvrf) {
-               vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-
-       return zebra_static_route_leak(
-               vty, zvrf, nh_zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
-               NULL, gate_str, ifname, flag, tag_str, distance_str, label,
-               table_str);
-}
-
-DEFPY(ip_route_vrf,
-      ip_route_vrf_cmd,
-      "[no] ip route\
-       <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
-       <A.B.C.D$gate|INTERFACE$ifname>                \
-       [{                                             \
-         tag (1-4294967295)                           \
-         |(1-255)$distance                            \
-         |label WORD                                  \
-         |table (1-4294967295)                        \
-         |nexthop-vrf NAME                            \
-          }]",
-      NO_STR IP_STR
-      "Establish static routes\n"
-      "IP destination prefix (e.g. 10.0.0.0/8)\n"
-      "IP destination prefix\n"
-      "IP destination prefix mask\n"
-      "IP gateway address\n"
-      "IP gateway interface name\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this route\n"
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n"
-      VRF_CMD_HELP_STR)
-{
-       VTY_DECLVAR_CONTEXT(vrf, vrf);
-       struct zebra_vrf *zvrf = vrf->info;
-       struct zebra_vrf *nh_zvrf;
-       const char *flag = NULL;
-
-       if (table_str && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (ifname && !strncasecmp(ifname, "Null0", 5)) {
-               flag = "Null0";
-               ifname = NULL;
-       }
-
-       if (nexthop_vrf)
-               nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
-       else
-               nh_zvrf = zvrf;
-
-       if (!nh_zvrf) {
-               vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return zebra_static_route_leak(
-               vty, zvrf, nh_zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
-               NULL, gate_str, ifname, flag, tag_str, distance_str, label,
-               NULL);
-}
-
 /* New RIB.  Detailed information for IPv4 route. */
 static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
                                     int mcast)
@@ -1198,14 +285,15 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
                                break;
                        }
 
-                       if (re->vrf_id != nexthop->vrf_id) {
+                       if ((re->vrf_id != nexthop->vrf_id)
+                            && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
                                struct vrf *vrf =
                                        vrf_lookup_by_id(nexthop->vrf_id);
 
                                if (vrf)
                                        vty_out(vty, "(vrf %s)", vrf->name);
                                else
-                                       vty_out(vty, "(vrf UKNOWN)");
+                                       vty_out(vty, "(vrf UNKNOWN)");
                        }
 
                        if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
@@ -1418,7 +506,8 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
                                break;
                        }
 
-                       if (nexthop->vrf_id != re->vrf_id) {
+                       if ((nexthop->vrf_id != re->vrf_id)
+                            && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
                                struct vrf *vrf =
                                        vrf_lookup_by_id(nexthop->vrf_id);
 
@@ -1572,13 +661,14 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
                        break;
                }
 
-               if (nexthop->vrf_id != re->vrf_id) {
+               if ((nexthop->vrf_id != re->vrf_id)
+                    && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
                        struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
 
                        if (vrf)
                                vty_out(vty, "(vrf %s)", vrf->name);
                        else
-                               vty_out(vty, "(vrf UKNOWN)");
+                               vty_out(vty, "(vrf UNKNOWN)");
                }
 
                if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
@@ -1661,8 +751,7 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
                                 bool use_fib, route_tag_t tag,
                                 const struct prefix *longer_prefix_p,
                                 bool supernets_only, int type,
-                                unsigned short ospf_instance_id,
-                                uint8_t use_json)
+                                unsigned short ospf_instance_id, bool use_json)
 {
        struct route_node *rn;
        struct route_entry *re;
@@ -1677,7 +766,7 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
                json = json_object_new_object();
 
        /* Show all routes. */
-       for (rn = route_top(table); rn; rn = route_next(rn)) {
+       for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
                dest = rib_dest_from_rnode(rn);
 
                RNODE_FOREACH_RE (rn, re) {
@@ -1751,7 +840,7 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
 }
 
 static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
-                           safi_t safi, bool use_fib, uint8_t use_json,
+                           safi_t safi, bool use_fib, bool use_json,
                            route_tag_t tag,
                            const struct prefix *longer_prefix_p,
                            bool supernets_only, int type,
@@ -1805,7 +894,7 @@ DEFPY (show_route_table,
        struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
        struct route_table *t;
 
-       t = zebra_ns_find_table(zvrf->zns, table, afi);
+       t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
        if (t)
                do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
                                     0, 0, !!json);
@@ -1831,10 +920,10 @@ DEFPY (show_route_table_vrf,
        vrf_id_t vrf_id = VRF_DEFAULT;
 
        if (vrf_name)
-               VRF_GET_ID(vrf_id, vrf_name);
+               VRF_GET_ID(vrf_id, vrf_name, !!json);
        zvrf = zebra_vrf_lookup_by_id(vrf_id);
 
-       t = zebra_ns_find_table(zvrf->zns, table, afi);
+       t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
        if (t)
                do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
                                     0, 0, !!json);
@@ -1854,7 +943,7 @@ DEFUN (show_ip_nht,
        vrf_id_t vrf_id = VRF_DEFAULT;
 
        if (argc == 5)
-               VRF_GET_ID(vrf_id, argv[idx_vrf]->arg);
+               VRF_GET_ID(vrf_id, argv[idx_vrf]->arg, false);
 
        zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
        return CMD_SUCCESS;
@@ -1894,7 +983,7 @@ DEFUN (show_ipv6_nht,
        vrf_id_t vrf_id = VRF_DEFAULT;
 
        if (argc == 5)
-               VRF_GET_ID(vrf_id, argv[idx_vrf]->arg);
+               VRF_GET_ID(vrf_id, argv[idx_vrf]->arg, false);
 
        zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
        return CMD_SUCCESS;
@@ -1929,11 +1018,17 @@ DEFUN (ip_nht_default_route,
        "Filter Next Hop tracking route resolution\n"
        "Resolve via default route\n")
 {
+       ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
+
+       if (!zvrf)
+               return CMD_WARNING;
+
        if (zebra_rnh_ip_default_route)
                return CMD_SUCCESS;
 
        zebra_rnh_ip_default_route = 1;
-       zebra_evaluate_rnh(VRF_DEFAULT, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
+
+       zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
        return CMD_SUCCESS;
 }
 
@@ -1945,11 +1040,16 @@ DEFUN (no_ip_nht_default_route,
        "Filter Next Hop tracking route resolution\n"
        "Resolve via default route\n")
 {
+       ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
+
+       if (!zvrf)
+               return CMD_WARNING;
+
        if (!zebra_rnh_ip_default_route)
                return CMD_SUCCESS;
 
        zebra_rnh_ip_default_route = 0;
-       zebra_evaluate_rnh(VRF_DEFAULT, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
+       zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
        return CMD_SUCCESS;
 }
 
@@ -1960,11 +1060,16 @@ DEFUN (ipv6_nht_default_route,
        "Filter Next Hop tracking route resolution\n"
        "Resolve via default route\n")
 {
+       ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
+
+       if (!zvrf)
+               return CMD_WARNING;
+
        if (zebra_rnh_ipv6_default_route)
                return CMD_SUCCESS;
 
        zebra_rnh_ipv6_default_route = 1;
-       zebra_evaluate_rnh(VRF_DEFAULT, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
+       zebra_evaluate_rnh(zvrf, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
        return CMD_SUCCESS;
 }
 
@@ -1976,11 +1081,17 @@ DEFUN (no_ipv6_nht_default_route,
        "Filter Next Hop tracking route resolution\n"
        "Resolve via default route\n")
 {
+
+       ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
+
+       if (!zvrf)
+               return CMD_WARNING;
+
        if (!zebra_rnh_ipv6_default_route)
                return CMD_SUCCESS;
 
        zebra_rnh_ipv6_default_route = 0;
-       zebra_evaluate_rnh(VRF_DEFAULT, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
+       zebra_evaluate_rnh(zvrf, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
        return CMD_SUCCESS;
 }
 
@@ -2060,7 +1171,7 @@ DEFPY (show_route,
                vrf_id_t vrf_id = VRF_DEFAULT;
 
                if (vrf_name)
-                       VRF_GET_ID(vrf_id, vrf_name);
+                       VRF_GET_ID(vrf_id, vrf_name, !!json);
                vrf = vrf_lookup_by_id(vrf_id);
                do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
                                 !!json, tag, prefix_str ? prefix : NULL,
@@ -2139,7 +1250,7 @@ DEFPY (show_route_detail,
                vrf_id_t vrf_id = VRF_DEFAULT;
 
                if (vrf_name)
-                       VRF_GET_ID(vrf_id, vrf_name);
+                       VRF_GET_ID(vrf_id, vrf_name, false);
 
                table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
                if (!table)
@@ -2209,7 +1320,7 @@ DEFPY (show_route_summary,
                vrf_id_t vrf_id = VRF_DEFAULT;
 
                if (vrf_name)
-                       VRF_GET_ID(vrf_id, vrf_name);
+                       VRF_GET_ID(vrf_id, vrf_name, false);
 
                table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
                if (!table)
@@ -2260,7 +1371,7 @@ static void vty_show_ip_route_summary(struct vty *vty,
                }
 
        vty_out(vty, "%-20s %-20s %s  (vrf %s)\n", "Route Source", "Routes",
-               "FIB", zvrf_name(((rib_table_info_t *)table->info)->zvrf));
+               "FIB", zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
 
        for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
                if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
@@ -2336,7 +1447,7 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty,
 
        vty_out(vty, "%-20s %-20s %s  (vrf %s)\n", "Route Source",
                "Prefix Routes", "FIB",
-               zvrf_name(((rib_table_info_t *)table->info)->zvrf));
+               zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
 
        for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
                if (rib_cnt[i] > 0) {
@@ -2362,449 +1473,6 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty,
        vty_out(vty, "\n");
 }
 
-/* Write static route configuration. */
-int static_config(struct vty *vty, struct zebra_vrf *zvrf, afi_t afi,
-                 safi_t safi, const char *cmd)
-{
-       struct static_hold_route *shr;
-       struct listnode *node;
-       char spacing[100];
-       struct route_node *rn;
-       struct static_route *si;
-       struct route_table *stable;
-       char buf[SRCDEST2STR_BUFFER];
-       int write = 0;
-
-       if ((stable = zvrf->stable[afi][safi]) == NULL)
-               return write;
-
-       sprintf(spacing, "%s%s", (zvrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ",
-               cmd);
-
-       /*
-        * Static routes for vrfs not fully inited
-        */
-       for (ALL_LIST_ELEMENTS_RO(static_list, node, shr)) {
-               if (shr->afi != afi || shr->safi != safi)
-                       continue;
-
-               if (strcmp(zvrf->vrf->name, shr->vrf_name) != 0)
-                       continue;
-
-               char dest_str[PREFIX_STRLEN];
-
-               prefix2str(&shr->dest, dest_str, sizeof(dest_str));
-
-               vty_out(vty, "%s ", spacing);
-               if (shr->dest_str)
-                       vty_out(vty, "%s ", dest_str);
-               if (shr->src_str)
-                       vty_out(vty, "from %s ", shr->src_str);
-               if (shr->gate_str)
-                       vty_out(vty, "%s ", shr->gate_str);
-               if (shr->ifname)
-                       vty_out(vty, "%s ", shr->ifname);
-               if (shr->flag_str)
-                       vty_out(vty, "%s ", shr->flag_str);
-               if (shr->tag_str)
-                       vty_out(vty, "tag %s ", shr->tag_str);
-               if (shr->distance_str)
-                       vty_out(vty, "%s ", shr->distance_str);
-               if (shr->label_str)
-                       vty_out(vty, "label %s ", shr->label_str);
-               if (shr->table_str)
-                       vty_out(vty, "table %s ", shr->table_str);
-               if (strcmp(shr->vrf_name, shr->nhvrf_name) != 0)
-                       vty_out(vty, "nexthop-vrf %s", shr->nhvrf_name);
-               vty_out(vty, "\n");
-       }
-
-       for (rn = route_top(stable); rn; rn = srcdest_route_next(rn))
-               for (si = rn->info; si; si = si->next) {
-                       vty_out(vty, "%s %s", spacing,
-                               srcdest_rnode2str(rn, buf, sizeof buf));
-
-                       switch (si->type) {
-                       case STATIC_IPV4_GATEWAY:
-                               vty_out(vty, " %s", inet_ntoa(si->addr.ipv4));
-                               break;
-                       case STATIC_IPV6_GATEWAY:
-                               vty_out(vty, " %s",
-                                       inet_ntop(AF_INET6, &si->addr.ipv6, buf,
-                                                 sizeof buf));
-                               break;
-                       case STATIC_IFNAME:
-                               vty_out(vty, " %s", si->ifname);
-                               break;
-                       case STATIC_BLACKHOLE:
-                               switch (si->bh_type) {
-                               case STATIC_BLACKHOLE_DROP:
-                                       vty_out(vty, " blackhole");
-                                       break;
-                               case STATIC_BLACKHOLE_NULL:
-                                       vty_out(vty, " Null0");
-                                       break;
-                               case STATIC_BLACKHOLE_REJECT:
-                                       vty_out(vty, " reject");
-                                       break;
-                               }
-                               break;
-                       case STATIC_IPV4_GATEWAY_IFNAME:
-                               vty_out(vty, " %s %s",
-                                       inet_ntop(AF_INET, &si->addr.ipv4, buf,
-                                                 sizeof buf),
-                                       si->ifname);
-                               break;
-                       case STATIC_IPV6_GATEWAY_IFNAME:
-                               vty_out(vty, " %s %s",
-                                       inet_ntop(AF_INET6, &si->addr.ipv6, buf,
-                                                 sizeof buf),
-                                       si->ifname);
-                               break;
-                       }
-
-                       if (si->tag)
-                               vty_out(vty, " tag %" ROUTE_TAG_PRI, si->tag);
-
-                       if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
-                               vty_out(vty, " %d", si->distance);
-
-                       /* Label information */
-                       if (si->snh_label.num_labels)
-                               vty_out(vty, " label %s",
-                                       mpls_label2str(si->snh_label.num_labels,
-                                                      si->snh_label.label, buf,
-                                                      sizeof buf, 0));
-
-                       if (si->nh_vrf_id != si->vrf_id) {
-                               vty_out(vty, " nexthop-vrf %s", si->nh_vrfname);
-                       }
-
-                       /* table ID from VRF overrides configured
-                        */
-                       if (si->table_id && zvrf->table_id == RT_TABLE_MAIN)
-                               vty_out(vty, " table %u", si->table_id);
-
-                       vty_out(vty, "\n");
-
-                       write = 1;
-               }
-       return write;
-}
-
-DEFPY(ipv6_route_blackhole,
-      ipv6_route_blackhole_cmd,
-      "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
-          <Null0|reject|blackhole>$flag                    \
-          [{                                               \
-            tag (1-4294967295)                             \
-            |(1-255)$distance                              \
-            |vrf NAME                                      \
-            |label WORD                                    \
-            |table (1-4294967295)                          \
-          }]",
-      NO_STR
-      IPV6_STR
-      "Establish static routes\n"
-      "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
-      "IPv6 source-dest route\n"
-      "IPv6 source prefix\n"
-      "Null interface\n"
-      "Emit an ICMP unreachable when matched\n"
-      "Silently discard pkts when matched\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this prefix\n"
-      VRF_CMD_HELP_STR
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n")
-{
-       if (table_str && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
-                                 NULL, from_str, NULL, NULL, flag, tag_str,
-                                 distance_str, vrf, label, table_str);
-}
-
-DEFPY(ipv6_route_blackhole_vrf,
-      ipv6_route_blackhole_vrf_cmd,
-      "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
-          <Null0|reject|blackhole>$flag                    \
-          [{                                               \
-            tag (1-4294967295)                             \
-            |(1-255)$distance                              \
-            |label WORD                                    \
-            |table (1-4294967295)                          \
-          }]",
-      NO_STR
-      IPV6_STR
-      "Establish static routes\n"
-      "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
-      "IPv6 source-dest route\n"
-      "IPv6 source prefix\n"
-      "Null interface\n"
-      "Emit an ICMP unreachable when matched\n"
-      "Silently discard pkts when matched\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this prefix\n"
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n")
-{
-       VTY_DECLVAR_CONTEXT(vrf, vrf);
-       struct zebra_vrf *zvrf = vrf->info;
-
-       if (table_str && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       /*
-        * Coverity is complaining that prefix could
-        * be dereferenced, but we know that prefix will
-        * valid.  Add an assert to make it happy
-        */
-       assert(prefix);
-       return zebra_static_route_leak(
-               vty, zvrf, zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
-               from_str, NULL, NULL, flag, tag_str, distance_str, label,
-               table_str);
-}
-
-DEFPY(ipv6_route_address_interface,
-      ipv6_route_address_interface_cmd,
-      "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
-          X:X::X:X$gate                                    \
-          INTERFACE$ifname                                 \
-          [{                                               \
-            tag (1-4294967295)                             \
-            |(1-255)$distance                              \
-            |vrf NAME                                      \
-            |label WORD                                    \
-           |table (1-4294967295)                          \
-            |nexthop-vrf NAME                              \
-          }]",
-      NO_STR
-      IPV6_STR
-      "Establish static routes\n"
-      "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
-      "IPv6 source-dest route\n"
-      "IPv6 source prefix\n"
-      "IPv6 gateway address\n"
-      "IPv6 gateway interface name\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this prefix\n"
-      VRF_CMD_HELP_STR
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n"
-      VRF_CMD_HELP_STR)
-{
-       struct zebra_vrf *zvrf;
-       struct zebra_vrf *nh_zvrf;
-
-       if (table_str && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       zvrf = zebra_vty_get_unknown_vrf(vty, vrf);
-       if (!zvrf) {
-               vty_out(vty, "%% vrf %s is not defined\n", vrf);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (nexthop_vrf)
-               nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
-       else
-               nh_zvrf = zvrf;
-
-       if (!nh_zvrf) {
-               vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return zebra_static_route_leak(
-               vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
-               from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
-               table_str);
-}
-
-DEFPY(ipv6_route_address_interface_vrf,
-      ipv6_route_address_interface_vrf_cmd,
-      "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
-          X:X::X:X$gate                                    \
-          INTERFACE$ifname                                 \
-          [{                                               \
-            tag (1-4294967295)                             \
-            |(1-255)$distance                              \
-            |label WORD                                    \
-           |table (1-4294967295)                          \
-            |nexthop-vrf NAME                              \
-          }]",
-      NO_STR
-      IPV6_STR
-      "Establish static routes\n"
-      "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
-      "IPv6 source-dest route\n"
-      "IPv6 source prefix\n"
-      "IPv6 gateway address\n"
-      "IPv6 gateway interface name\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this prefix\n"
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n"
-      VRF_CMD_HELP_STR)
-{
-       VTY_DECLVAR_CONTEXT(vrf, vrf);
-       struct zebra_vrf *zvrf = vrf->info;
-       struct zebra_vrf *nh_zvrf;
-
-       if (table_str && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (nexthop_vrf)
-               nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
-       else
-               nh_zvrf = zvrf;
-
-       if (!nh_zvrf) {
-               vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return zebra_static_route_leak(
-               vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
-               from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
-               table_str);
-}
-
-DEFPY(ipv6_route,
-      ipv6_route_cmd,
-      "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
-          <X:X::X:X$gate|INTERFACE$ifname>                 \
-          [{                                               \
-            tag (1-4294967295)                             \
-            |(1-255)$distance                              \
-            |vrf NAME                                      \
-            |label WORD                                    \
-           |table (1-4294967295)                          \
-            |nexthop-vrf NAME                              \
-          }]",
-      NO_STR
-      IPV6_STR
-      "Establish static routes\n"
-      "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
-      "IPv6 source-dest route\n"
-      "IPv6 source prefix\n"
-      "IPv6 gateway address\n"
-      "IPv6 gateway interface name\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this prefix\n"
-      VRF_CMD_HELP_STR
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n"
-      VRF_CMD_HELP_STR)
-{
-       struct zebra_vrf *zvrf;
-       struct zebra_vrf *nh_zvrf;
-
-       if (table_str && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       zvrf = zebra_vty_get_unknown_vrf(vty, vrf);
-       if (!zvrf) {
-               vty_out(vty, "%% vrf %s is not defined\n", vrf);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (nexthop_vrf)
-               nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
-       else
-               nh_zvrf = zvrf;
-
-       if (!nh_zvrf) {
-               vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return zebra_static_route_leak(
-               vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
-               from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
-               table_str);
-}
-
-DEFPY(ipv6_route_vrf,
-      ipv6_route_vrf_cmd,
-      "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
-          <X:X::X:X$gate|INTERFACE$ifname>                 \
-          [{                                               \
-            tag (1-4294967295)                             \
-            |(1-255)$distance                              \
-            |label WORD                                    \
-           |table (1-4294967295)                          \
-            |nexthop-vrf NAME                              \
-          }]",
-      NO_STR
-      IPV6_STR
-      "Establish static routes\n"
-      "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
-      "IPv6 source-dest route\n"
-      "IPv6 source prefix\n"
-      "IPv6 gateway address\n"
-      "IPv6 gateway interface name\n"
-      "Set tag for this route\n"
-      "Tag value\n"
-      "Distance value for this prefix\n"
-      MPLS_LABEL_HELPSTR
-      "Table to configure\n"
-      "The table number to configure\n"
-      VRF_CMD_HELP_STR)
-{
-       VTY_DECLVAR_CONTEXT(vrf, vrf);
-       struct zebra_vrf *zvrf = vrf->info;
-       struct zebra_vrf *nh_zvrf;
-
-       if (table_str && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (nexthop_vrf)
-               nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
-       else
-               nh_zvrf = zvrf;
-
-       if (!nh_zvrf) {
-               vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return zebra_static_route_leak(
-               vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
-               from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
-               table_str);
-}
-
 /*
  * Show IPv6 mroute command.Used to dump
  * the Multicast routing table.
@@ -2824,7 +1492,7 @@ DEFUN (show_ipv6_mroute,
        vrf_id_t vrf_id = VRF_DEFAULT;
 
        if (argc == 5)
-               VRF_GET_ID(vrf_id, argv[4]->arg);
+               VRF_GET_ID(vrf_id, argv[4]->arg, false);
 
        table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
        if (!table)
@@ -3067,7 +1735,7 @@ DEFUN (show_vrf_vni,
        struct zebra_vrf *zvrf;
        json_object *json = NULL;
        json_object *json_vrfs = NULL;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (uj) {
                json = json_object_new_object();
@@ -3103,7 +1771,7 @@ DEFUN (show_evpn_global,
        "EVPN\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zebra_vxlan_print_evpn(vty, uj);
        return CMD_SUCCESS;
@@ -3118,7 +1786,7 @@ DEFUN (show_evpn_vni,
        JSON_STR)
 {
        struct zebra_vrf *zvrf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
        zebra_vxlan_print_vnis(vty, zvrf, uj);
@@ -3136,7 +1804,7 @@ DEFUN (show_evpn_vni_vni,
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[3]->arg, NULL, 10);
        zvrf = vrf_info_lookup(VRF_DEFAULT);
@@ -3158,7 +1826,7 @@ DEFUN (show_evpn_rmac_vni_mac,
 {
        vni_t l3vni = 0;
        struct ethaddr mac;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        l3vni = strtoul(argv[4]->arg, NULL, 10);
        if (!prefix_str2mac(argv[6]->arg, &mac)) {
@@ -3180,7 +1848,7 @@ DEFUN (show_evpn_rmac_vni,
        JSON_STR)
 {
        vni_t l3vni = 0;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        l3vni = strtoul(argv[4]->arg, NULL, 10);
        zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
@@ -3198,7 +1866,7 @@ DEFUN (show_evpn_rmac_vni_all,
        "All VNIs\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
 
@@ -3219,7 +1887,7 @@ DEFUN (show_evpn_nh_vni_ip,
 {
        vni_t l3vni;
        struct ipaddr ip;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        l3vni = strtoul(argv[4]->arg, NULL, 10);
        if (str2ipaddr(argv[6]->arg, &ip) != 0) {
@@ -3243,7 +1911,7 @@ DEFUN (show_evpn_nh_vni,
        JSON_STR)
 {
        vni_t l3vni;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        l3vni = strtoul(argv[4]->arg, NULL, 10);
        zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
@@ -3261,7 +1929,7 @@ DEFUN (show_evpn_nh_vni_all,
        "All VNIs\n"
        JSON_STR)
 {
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zebra_vxlan_print_nh_all_l3vni(vty, uj);
 
@@ -3280,7 +1948,7 @@ DEFUN (show_evpn_mac_vni,
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        zvrf = vrf_info_lookup(VRF_DEFAULT);
@@ -3299,10 +1967,10 @@ DEFUN (show_evpn_mac_vni_all,
        JSON_STR)
 {
        struct zebra_vrf *zvrf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_macs_all_vni(vty, zvrf, uj);
+       zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
        return CMD_SUCCESS;
 }
 
@@ -3320,7 +1988,7 @@ DEFUN (show_evpn_mac_vni_all_vtep,
 {
        struct zebra_vrf *zvrf;
        struct in_addr vtep_ip;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        if (!inet_aton(argv[6]->arg, &vtep_ip)) {
                if (!uj)
@@ -3336,18 +2004,21 @@ DEFUN (show_evpn_mac_vni_all_vtep,
 
 DEFUN (show_evpn_mac_vni_mac,
        show_evpn_mac_vni_mac_cmd,
-       "show evpn mac vni " CMD_VNI_RANGE " mac WORD",
+       "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
        SHOW_STR
        "EVPN\n"
        "MAC addresses\n"
        "VxLAN Network Identifier\n"
        "VNI number\n"
        "MAC\n"
-       "MAC address (e.g., 00:e0:ec:20:12:62)\n")
+       "MAC address (e.g., 00:e0:ec:20:12:62)\n"
+       JSON_STR)
+
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
        struct ethaddr mac;
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        if (!prefix_str2mac(argv[6]->arg, &mac)) {
@@ -3355,7 +2026,7 @@ DEFUN (show_evpn_mac_vni_mac,
                return CMD_WARNING;
        }
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac);
+       zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
        return CMD_SUCCESS;
 }
 
@@ -3374,7 +2045,7 @@ DEFUN (show_evpn_mac_vni_vtep,
        struct zebra_vrf *zvrf;
        vni_t vni;
        struct in_addr vtep_ip;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        if (!inet_aton(argv[6]->arg, &vtep_ip)) {
@@ -3388,6 +2059,90 @@ DEFUN (show_evpn_mac_vni_vtep,
        return CMD_SUCCESS;
 }
 
+DEFPY (show_evpn_mac_vni_all_dad,
+       show_evpn_mac_vni_all_dad_cmd,
+       "show evpn mac vni all duplicate [json]",
+       SHOW_STR
+       "EVPN\n"
+       "MAC addresses\n"
+       "VxLAN Network Identifier\n"
+       "All VNIs\n"
+       "Duplicate address list\n"
+       JSON_STR)
+{
+       struct zebra_vrf *zvrf;
+       bool uj = use_json(argc, argv);
+
+       zvrf = vrf_info_lookup(VRF_DEFAULT);
+       zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
+       return CMD_SUCCESS;
+}
+
+
+DEFPY (show_evpn_mac_vni_dad,
+       show_evpn_mac_vni_dad_cmd,
+       "show evpn mac vni " CMD_VNI_RANGE " duplicate" "[json]",
+       SHOW_STR
+       "EVPN\n"
+       "MAC addresses\n"
+       "VxLAN Network Identifier\n"
+       "VNI number\n"
+       "Duplicate address list\n"
+       JSON_STR)
+{
+       struct zebra_vrf *zvrf;
+       vni_t vni;
+       bool uj = use_json(argc, argv);
+
+       vni = strtoul(argv[4]->arg, NULL, 10);
+       zvrf = vrf_info_lookup(VRF_DEFAULT);
+
+       zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
+
+       return CMD_SUCCESS;
+}
+
+DEFPY (show_evpn_neigh_vni_dad,
+       show_evpn_neigh_vni_dad_cmd,
+       "show evpn arp-cache vni " CMD_VNI_RANGE "duplicate" "[json]",
+       SHOW_STR
+       "EVPN\n"
+       "ARP and ND cache\n"
+       "VxLAN Network Identifier\n"
+       "VNI number\n"
+       "Duplicate address list\n"
+       JSON_STR)
+{
+       struct zebra_vrf *zvrf;
+       vni_t vni;
+       bool uj = use_json(argc, argv);
+
+       vni = strtoul(argv[4]->arg, NULL, 10);
+       zvrf = vrf_info_lookup(VRF_DEFAULT);
+       zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
+       return CMD_SUCCESS;
+}
+
+DEFPY (show_evpn_neigh_vni_all_dad,
+       show_evpn_neigh_vni_all_dad_cmd,
+       "show evpn arp-cache vni all duplicate [json]",
+       SHOW_STR
+       "EVPN\n"
+       "ARP and ND cache\n"
+       "VxLAN Network Identifier\n"
+       "All VNIs\n"
+       "Duplicate address list\n"
+       JSON_STR)
+{
+       struct zebra_vrf *zvrf;
+       bool uj = use_json(argc, argv);
+
+       zvrf = vrf_info_lookup(VRF_DEFAULT);
+       zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
+       return CMD_SUCCESS;
+}
+
+
 DEFUN (show_evpn_neigh_vni,
        show_evpn_neigh_vni_cmd,
        "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
@@ -3400,7 +2155,7 @@ DEFUN (show_evpn_neigh_vni,
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        zvrf = vrf_info_lookup(VRF_DEFAULT);
@@ -3419,10 +2174,27 @@ DEFUN (show_evpn_neigh_vni_all,
        JSON_STR)
 {
        struct zebra_vrf *zvrf;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
+
+       zvrf = vrf_info_lookup(VRF_DEFAULT);
+       zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
+       return CMD_SUCCESS;
+}
+
+DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd,
+       "show evpn arp-cache vni all detail [json]",
+       SHOW_STR
+       "EVPN\n"
+       "ARP and ND cache\n"
+       "VxLAN Network Identifier\n"
+       "All VNIs\n"
+       "Neighbor details for all vnis in detail\n" JSON_STR)
+{
+       struct zebra_vrf *zvrf;
+       bool uj = use_json(argc, argv);
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_neigh_all_vni(vty, zvrf, uj);
+       zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, uj);
        return CMD_SUCCESS;
 }
 
@@ -3441,7 +2213,7 @@ DEFUN (show_evpn_neigh_vni_neigh,
        struct zebra_vrf *zvrf;
        vni_t vni;
        struct ipaddr ip;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        if (str2ipaddr(argv[6]->arg, &ip) != 0) {
@@ -3469,7 +2241,7 @@ DEFUN (show_evpn_neigh_vni_vtep,
        struct zebra_vrf *zvrf;
        vni_t vni;
        struct in_addr vtep_ip;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        if (!inet_aton(argv[6]->arg, &vtep_ip)) {
@@ -3505,12 +2277,69 @@ DEFUN (show_pbr_ipset,
 /* policy routing contexts */
 DEFUN (show_pbr_iptable,
        show_pbr_iptable_cmd,
-       "show pbr iptable",
+       "show pbr iptable [WORD]",
        SHOW_STR
        "Policy-Based Routing\n"
-       "IPtable Context information\n")
+       "IPtable Context information\n"
+       "IPtable Name information\n")
+{
+       int idx = 0;
+       int found = 0;
+
+       found = argv_find(argv, argc, "WORD", &idx);
+       if (!found)
+               zebra_pbr_show_iptable(vty, NULL);
+       else
+               zebra_pbr_show_iptable(vty, argv[idx]->arg);
+       return CMD_SUCCESS;
+}
+
+DEFPY (clear_evpn_dup_addr,
+       clear_evpn_dup_addr_cmd,
+       "clear evpn dup-addr vni <all$vni_all |" CMD_VNI_RANGE"$vni_val [mac M:A:C$mac_val | ip <A.B.C.D|X:X::X:X>]>",
+       CLEAR_STR
+       "EVPN\n"
+       "Duplicate address \n"
+       "VxLAN Network Identifier\n"
+       "VNI number\n"
+       "All VNIs\n"
+       "MAC\n"
+       "MAC address (e.g., 00:e0:ec:20:12:62)\n"
+       "IP\n"
+       "IPv4 address\n"
+       "IPv6 address\n")
 {
-       zebra_pbr_show_iptable(vty);
+       struct zebra_vrf *zvrf;
+       vni_t vni = 0;
+       struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
+       struct ethaddr mac_addr;
+
+       zvrf = vrf_info_lookup(VRF_DEFAULT);
+       if (vni_val) {
+               vni = strtoul(vni_val, NULL, 10);
+
+               if (mac_val) {
+                       prefix_str2mac(mac_val, &mac_addr);
+                       zebra_vxlan_clear_dup_detect_vni_mac(vty, zvrf, vni,
+                                                       &mac_addr);
+               } else if (ip) {
+                       if (sockunion_family(ip) == AF_INET) {
+                               host_ip.ipa_type = IPADDR_V4;
+                               host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
+                       } else {
+                               host_ip.ipa_type = IPADDR_V6;
+                               memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
+                                      sizeof(struct in6_addr));
+                       }
+                       zebra_vxlan_clear_dup_detect_vni_ip(vty, zvrf, vni,
+                                                           &host_ip);
+               } else
+                       zebra_vxlan_clear_dup_detect_vni(vty, zvrf, vni);
+
+       } else {
+               zebra_vxlan_clear_dup_detect_vni_all(vty, zvrf);
+       }
+
        return CMD_SUCCESS;
 }
 
@@ -3696,9 +2525,6 @@ static int config_write_protocol(struct vty *vty)
                                                                      == MCAST_MIX_DISTANCE
                                                              ? "lower-distance"
                                                              : "longer-prefix");
-
-       zebra_routemap_config_write_protocol(vty);
-
        return 1;
 }
 
@@ -3892,6 +2718,76 @@ DEFUN (no_ipv6_forwarding,
        return CMD_SUCCESS;
 }
 
+/* Display dataplane info */
+DEFUN (show_dataplane,
+       show_dataplane_cmd,
+       "show zebra dplane [detailed]",
+       SHOW_STR
+       ZEBRA_STR
+       "Zebra dataplane information\n"
+       "Detailed output\n")
+{
+       int idx = 0;
+       bool detailed = false;
+
+       if (argv_find(argv, argc, "detailed", &idx))
+               detailed = true;
+
+       return dplane_show_helper(vty, detailed);
+}
+
+/* Display dataplane providers info */
+DEFUN (show_dataplane_providers,
+       show_dataplane_providers_cmd,
+       "show zebra dplane providers [detailed]",
+       SHOW_STR
+       ZEBRA_STR
+       "Zebra dataplane information\n"
+       "Zebra dataplane provider information\n"
+       "Detailed output\n")
+{
+       int idx = 0;
+       bool detailed = false;
+
+       if (argv_find(argv, argc, "detailed", &idx))
+               detailed = true;
+
+       return dplane_show_provs_helper(vty, detailed);
+}
+
+/* Configure dataplane incoming queue limit */
+DEFUN (zebra_dplane_queue_limit,
+       zebra_dplane_queue_limit_cmd,
+       "zebra dplane limit (0-10000)",
+       ZEBRA_STR
+       "Zebra dataplane\n"
+       "Limit incoming queued updates\n"
+       "Number of queued updates\n")
+{
+       uint32_t limit = 0;
+
+       limit = strtoul(argv[3]->arg, NULL, 10);
+
+       dplane_set_in_queue_limit(limit, true);
+
+       return CMD_SUCCESS;
+}
+
+/* Reset dataplane queue limit to default value */
+DEFUN (no_zebra_dplane_queue_limit,
+       no_zebra_dplane_queue_limit_cmd,
+       "no zebra dplane limit [(0-10000)]",
+       NO_STR
+       ZEBRA_STR
+       "Zebra dataplane\n"
+       "Limit incoming queued updates\n"
+       "Number of queued updates\n")
+{
+       dplane_set_in_queue_limit(0, false);
+
+       return CMD_SUCCESS;
+}
+
 /* Table configuration write function. */
 static int config_write_table(struct vty *vty)
 {
@@ -3955,16 +2851,9 @@ void zebra_vty_init(void)
 
        install_element(CONFIG_NODE, &allow_external_route_update_cmd);
        install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
-       install_element(CONFIG_NODE, &ip_mroute_dist_cmd);
+
        install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
        install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
-       install_element(CONFIG_NODE, &ip_route_blackhole_cmd);
-       install_element(CONFIG_NODE,
-                       &ip_route_address_interface_cmd);
-       install_element(CONFIG_NODE, &ip_route_cmd);
-       install_element(VRF_NODE, &ip_route_blackhole_vrf_cmd);
-       install_element(VRF_NODE, &ip_route_address_interface_vrf_cmd);
-       install_element(VRF_NODE, &ip_route_vrf_cmd);
 
        install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
        install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
@@ -3989,19 +2878,14 @@ void zebra_vty_init(void)
        install_element(VIEW_NODE, &show_ip_rpf_cmd);
        install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
 
-       install_element(CONFIG_NODE,
-                       &ipv6_route_blackhole_cmd);
-       install_element(CONFIG_NODE,
-                       &ipv6_route_address_interface_cmd);
-       install_element(CONFIG_NODE, &ipv6_route_cmd);
-       install_element(VRF_NODE, &ipv6_route_blackhole_vrf_cmd);
-       install_element(VRF_NODE,
-                       &ipv6_route_address_interface_vrf_cmd);
-       install_element(VRF_NODE, &ipv6_route_vrf_cmd);
        install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
        install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
        install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
        install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
+       install_element(VRF_NODE, &ip_nht_default_route_cmd);
+       install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
+       install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
+       install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
        install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
 
        /* Commands for VRF */
@@ -4021,10 +2905,16 @@ void zebra_vty_init(void)
        install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
        install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
        install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
+       install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
+       install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
        install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
        install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
+       install_element(VIEW_NODE, &show_evpn_neigh_vni_all_detail_cmd);
        install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
        install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
+       install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
+       install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
+       install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd);
 
        install_element(VIEW_NODE, &show_pbr_ipset_cmd);
        install_element(VIEW_NODE, &show_pbr_iptable_cmd);
@@ -4034,7 +2924,8 @@ void zebra_vty_init(void)
        install_element(VRF_NODE, &vrf_vni_mapping_cmd);
        install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
 
-       static_list = list_new();
-       static_list->cmp = (int (*)(void *, void *))static_list_compare;
-       static_list->del = (void (*)(void *))static_list_delete;
+       install_element(VIEW_NODE, &show_dataplane_cmd);
+       install_element(VIEW_NODE, &show_dataplane_providers_cmd);
+       install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
+       install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
 }