]> git.puffer.fish Git - mirror/frr.git/commitdiff
Merge branch 'cmaster' of ssh://stash.cumulusnetworks.com:7999/quag/quagga into cmaster
authorDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 30 Oct 2015 12:52:29 +0000 (05:52 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 30 Oct 2015 12:52:29 +0000 (05:52 -0700)
Conflicts:
zebra/rib.h
zebra/zebra_rib.c
zebra/zebra_vty.c

1  2 
lib/memtypes.c
zebra/rib.h
zebra/zebra_rib.c
zebra/zebra_vty.c

diff --cc lib/memtypes.c
Simple merge
diff --cc zebra/rib.h
index e361365582a3beee7fe795cd458685af639c748d,25ab68df131110564a9c363b719f405a9efe4efa..cd77db4df104de42c01c5b230e5cf43c8c963d9b
@@@ -165,12 -169,15 +169,15 @@@ typedef struct rib_dest_t
    RIB_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode (rn), rib, next)
  
  /* Static route information. */
 -struct static_ipv4
 +struct static_route
  {
    /* For linked list. */
 -  struct static_ipv4 *prev;
 -  struct static_ipv4 *next;
 +  struct static_route *prev;
 +  struct static_route *next;
  
+   /* VRF identifier. */
+   vrf_id_t vrf_id;
    /* Administrative distance. */
    u_char distance;
  
  
    /* Flag for this static route's type. */
    u_char type;
 -#define STATIC_IPV4_GATEWAY     1
 -#define STATIC_IPV4_IFNAME      2
 -#define STATIC_IPV4_BLACKHOLE   3
 +#define STATIC_IPV4_GATEWAY          1
 +#define STATIC_IPV4_IFNAME           2
 +#define STATIC_IPV4_BLACKHOLE        3
 +#define STATIC_IPV6_GATEWAY          4
 +#define STATIC_IPV6_GATEWAY_IFNAME   5
 +#define STATIC_IPV6_IFNAME           6
  
 -  /* Nexthop value. */
 -  union 
 -  {
 -    struct in_addr ipv4;
 -    char *ifname;
 -  } gate;
 -
 -  /* bit flags */
 -  u_char flags;
 -/*
 - see ZEBRA_FLAG_REJECT
 -     ZEBRA_FLAG_BLACKHOLE
 - */
 -};
 -
 -#ifdef HAVE_IPV6
 -/* Static route information. */
 -struct static_ipv6
 -{
 -  /* For linked list. */
 -  struct static_ipv6 *prev;
 -  struct static_ipv6 *next;
 -
 -  /* VRF identifier. */
 -  vrf_id_t vrf_id;
 -
 -  /* Administrative distance. */
 -  u_char distance;
 -
 -  /* Tag */
 -  u_short tag;
 -
 -  /* Flag for this static route's type. */
 -  u_char type;
 -#define STATIC_IPV6_GATEWAY          1
 -#define STATIC_IPV6_GATEWAY_IFNAME   2
 -#define STATIC_IPV6_IFNAME           3
 -
 -  /* Nexthop value. */
 -  struct in6_addr ipv6;
 +  /*
-    * Nexthop value. 
++   * Nexthop value.
 +   *
 +   * Under IPv4 addr and ifname are
 +   * used independentyly.
 +   * STATIC_IPV4_GATEWAY uses addr
 +   * STATIC_IPV4_IFNAME uses ifname
 +   */
 +  union g_addr addr;
    char *ifname;
  
    /* bit flags */
       ZEBRA_FLAG_BLACKHOLE
   */
  };
 -#endif /* HAVE_IPV6 */
 +
  /* The following for loop allows to iterate over the nexthop
   * structure of routes.
   *
                                        : ((tnexthop) = (nexthop)->next)) \
                         : (((recursing) = 0),((tnexthop) = (tnexthop)->next)))
  
 -#if defined (HAVE_IPV6) && defined (RTADV)
+ /* Router advertisement feature. */
+ #ifndef RTADV
+ #if (defined(LINUX_IPV6) && (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1)) || defined(KAME)
+   #ifdef HAVE_RTADV
+     #define RTADV
+   #endif
+ #endif
+ #endif
 -#endif /* RTADV && HAVE_IPV6 */
++#if defined (RTADV)
+ /* Structure which hold status of router advertisement. */
+ struct rtadv
+ {
+   int sock;
+   int adv_if_count;
+   int adv_msec_if_count;
+   struct thread *ra_read;
+   struct thread *ra_timer;
+ };
++#endif /* RTADV */
+ #ifdef HAVE_NETLINK
+ /* Socket interface to kernel */
+ struct nlsock
+ {
+   int sock;
+   int seq;
+   struct sockaddr_nl snl;
+   const char *name;
+ };
+ #endif
  /* Routing table instance.  */
- struct vrf
+ struct zebra_vrf
  {
-   /* Identifier.  This is same as routing table vector index.  */
-   u_int32_t id;
+   /* Identifier. */
+   vrf_id_t vrf_id;
  
    /* Routing table name.  */
    char *name;
  
    /* Routing tables off of main table for redistribute table */
    struct route_table *other_table[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
 -#if defined (HAVE_IPV6) && defined (RTADV)
+ #ifdef HAVE_NETLINK
+   struct nlsock netlink;     /* kernel messages */
+   struct nlsock netlink_cmd; /* command channel */
+   struct thread *t_netlink;
+ #endif
+   /* 2nd pointer type used primarily to quell a warning on
+    * ALL_LIST_ELEMENTS_RO
+    */
+   struct list _rid_all_sorted_list;
+   struct list _rid_lo_sorted_list;
+   struct list *rid_all_sorted_list;
+   struct list *rid_lo_sorted_list;
+   struct prefix rid_user_assigned;
 -#endif /* RTADV && HAVE_IPV6 */
++#if defined (RTADV)
+   struct rtadv rtadv;
++#endif /* RTADV */
  };
  
  /*
@@@ -357,12 -448,14 +419,13 @@@ extern struct nexthop *nexthop_ipv6_ifn
  extern int
  rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
                  struct in6_addr *gate, unsigned int ifindex, int table);
 -#endif /* HAVE_IPV6 */
  
- extern struct vrf *vrf_lookup (u_int32_t);
- extern struct route_table *vrf_table (afi_t afi, safi_t safi, u_int32_t id);
- extern struct route_table *vrf_static_table (afi_t afi, safi_t safi, u_int32_t id);
- extern struct route_table *vrf_other_route_table (afi_t afi, u_int32_t table_id,
-                                                 u_int32_t vrf_id);
+ extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id);
+ extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t);
+ extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t);
+ extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, vrf_id_t);
+ extern struct route_table *zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id,
+                                                       vrf_id_t vrf_id);
  extern int is_zebra_valid_kernel_table(u_int32_t table_id);
  extern int is_zebra_main_routing_table(u_int32_t table_id);
  extern int zebra_check_addr (struct prefix *p);
@@@ -402,12 -496,13 +466,12 @@@ static_add_ipv4 (struct prefix *p, stru
  
  extern int
  static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
-                   u_short tag, u_char distance, u_int32_t vrf_id);
+                   u_short tag, u_char distance, vrf_id_t vrf_id);
  
 -#ifdef HAVE_IPV6
  extern int
  rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
-             struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
-             u_int32_t metric, u_char distance, safi_t safi);
+             struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
+               u_int32_t table_id, u_int32_t metric, u_char distance, safi_t safi);
  
  extern int
  rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
@@@ -431,8 -527,10 +496,8 @@@ rib_add_ipv6_multipath (struct prefix *
  extern int
  static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
                    const char *ifname, u_short tag, u_char distance,
-                     u_int32_t vrf_id);
+                     vrf_id_t vrf_id);
  
 -#endif /* HAVE_IPV6 */
 -
  extern int rib_gc_dest (struct route_node *rn);
  extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter);
  
index 94a63152929b0e1658fcff7559e470106dc2ab68,ffa3161f2b5e57c850a19a146049243bf11d6176..0bb9b581187d808a8f50e992dcd127aba9f4c1a2
@@@ -942,9 -840,10 +835,9 @@@ nexthop_active_ipv6 (struct rib *rib, s
      }
    return 0;
  }
 -#endif /* HAVE_IPV6 */
  
  struct rib *
- rib_match_ipv4 (struct in_addr addr)
+ rib_match_ipv4 (struct in_addr addr, vrf_id_t vrf_id)
  {
    struct prefix_ipv4 p;
    struct route_table *table;
@@@ -1126,8 -1026,9 +1020,8 @@@ rib_lookup_ipv4_route (struct prefix_ip
    return ZEBRA_RIB_NOTFOUND;
  }
  
 -#ifdef HAVE_IPV6
  struct rib *
- rib_match_ipv6 (struct in6_addr *addr)
+ rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id)
  {
    struct prefix_ipv6 p;
    struct route_table *table;
@@@ -2779,7 -2686,7 +2670,7 @@@ static_install_route (afi_t afi, safi_
    struct prefix nh_p;
  
    /* Lookup table.  */
-   table = vrf_table (afi, safi, 0);
 -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, si->vrf_id);
++  table = zebra_vrf_table (afi, safi, si->vrf_id);
    if (! table)
      return;
  
@@@ -2926,7 -2795,7 +2818,7 @@@ static_uninstall_route (afi_t afi, safi
    struct prefix nh_p;
  
    /* Lookup table.  */
-   table = vrf_table (afi, safi, 0);
 -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, si->vrf_id);
++  table = zebra_vrf_table (afi, safi, si->vrf_id);
    if (! table)
      return;
    
@@@ -3030,14 -2876,13 +2922,13 @@@ static_add_ipv4 (struct prefix *p, stru
  {
    u_char type = 0;
    struct route_node *rn;
 -  struct static_ipv4 *si;
 -  struct static_ipv4 *pp;
 -  struct static_ipv4 *cp;
 -  struct static_ipv4 *update = NULL;
 +  struct static_route *si;
 +  struct static_route *pp;
 +  struct static_route *cp;
 +  struct static_route *update = NULL;
-   struct route_table *stable;
+   struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
+   struct route_table *stable = zvrf->stable[AFI_IP][SAFI_UNICAST];
  
-   /* Lookup table.  */
-   stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
    if (! stable)
      return -1;
    
    si->distance = distance;
    si->flags = flags;
    si->tag = tag;
+   si->vrf_id = vrf_id;
  
    if (gate)
 -    si->gate.ipv4 = *gate;
 +    si->addr.ipv4 = *gate;
    if (ifname)
 -    si->gate.ifname = XSTRDUP (0, ifname);
 +    si->ifname = XSTRDUP (0, ifname);
  
    /* Add new static route information to the tree with sort by
       distance value and gateway address. */
@@@ -3600,17 -3640,15 +3491,16 @@@ rib_delete_ipv6 (int type, u_short inst
  int
  static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
                 const char *ifname, u_char flags, u_short tag,
-                  u_char distance, u_int32_t vrf_id)
+                  u_char distance, vrf_id_t vrf_id)
  {
    struct route_node *rn;
 -  struct static_ipv6 *si;
 -  struct static_ipv6 *pp;
 -  struct static_ipv6 *cp;
 +  struct static_route *si;
 +  struct static_route *pp;
 +  struct static_route *cp;
 +  struct static_route *update = NULL;
-   struct route_table *stable;
+   struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
+   struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
  
-   /* Lookup table.  */
-   stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
    if (! stable)
      return -1;
      
  int
  static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
                    const char *ifname, u_short tag, u_char distance,
-                     u_int32_t vrf_id)
+                     vrf_id_t vrf_id)
  {
    struct route_node *rn;
 -  struct static_ipv6 *si;
 +  struct static_route *si;
    struct route_table *stable;
  
    /* Lookup table.  */
index 89fb933aa68902b5d3b092ff4e901c811ebccb5b,4341152e0953ffdd8584518e3030f9641fa809e5..57c0e8265eafa5567f8e3ab0900d37d58e22ad7f
@@@ -881,818 -929,2308 +929,2308 @@@ DEFUN (no_ip_route_mask_flags_tag_dista
         "Tag value\n"
         "Distance value for this route\n")
  {
-   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], argv[4]);
+   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3],
+                             argv[4], NULL);
  }
  
- /* New RIB.  Detailed information for IPv4 route. */
- static void
- vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
+ /* Static route configuration.  */
+ DEFUN (ip_route_vrf, 
+        ip_route_vrf_cmd,
+        "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        VRF_CMD_HELP_STR)
  {
-   struct rib *rib;
-   struct nexthop *nexthop, *tnexthop;
-   int recursing;
-   char buf[BUFSIZ];
-   RNODE_FOREACH_RIB (rn, rib)
-     {
-       vty_out (vty, "Routing entry for %s/%d%s", 
-              inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
-              VTY_NEWLINE);
-       vty_out (vty, "  Known via \"%s", zebra_route_string (rib->type));
-       if (rib->instance)
-         vty_out (vty, "[%d]", rib->instance);
-       vty_out (vty, "\"");
-       vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
-       if (rib->tag)
-       vty_out (vty, ", tag %d", rib->tag);
-       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
-       vty_out (vty, ", best");
-       if (rib->refcnt)
-       vty_out (vty, ", refcnt %ld", rib->refcnt);
-       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
-        vty_out (vty, ", blackhole");
-       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
-        vty_out (vty, ", reject");
-       vty_out (vty, "%s", VTY_NEWLINE);
+   return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL, NULL, argv[2]);
+ }
  
- #define ONE_DAY_SECOND 60*60*24
- #define ONE_WEEK_SECOND 60*60*24*7
-       if (rib->type == ZEBRA_ROUTE_RIP
-         || rib->type == ZEBRA_ROUTE_OSPF
-         || rib->type == ZEBRA_ROUTE_BABEL
-         || rib->type == ZEBRA_ROUTE_ISIS
-         || rib->type == ZEBRA_ROUTE_TABLE
-         || rib->type == ZEBRA_ROUTE_BGP)
-       {
-         time_t uptime;
-         struct tm *tm;
+ DEFUN (ip_route_tag_vrf,
+        ip_route_tag_vrf_cmd,
+        "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-65535>" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2], NULL, argv[3]);
+ }
  
-         uptime = time (NULL);
-         uptime -= rib->uptime;
-         tm = gmtime (&uptime);
+ DEFUN (ip_route_flags_vrf,
+        ip_route_flags_vrf_cmd,
+        "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL, NULL, argv[3]);
+ }
  
-         vty_out (vty, "  Last update ");
+ DEFUN (ip_route_flags_tag_vrf,
+        ip_route_flags_tag_vrf_cmd,
+        "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-65535>" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        VRF_CMD_HELP_STR)
  
-         if (uptime < ONE_DAY_SECOND)
-           vty_out (vty,  "%02d:%02d:%02d", 
-                    tm->tm_hour, tm->tm_min, tm->tm_sec);
-         else if (uptime < ONE_WEEK_SECOND)
-           vty_out (vty, "%dd%02dh%02dm", 
-                    tm->tm_yday, tm->tm_hour, tm->tm_min);
-         else
-           vty_out (vty, "%02dw%dd%02dh", 
-                    tm->tm_yday/7,
-                    tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
-         vty_out (vty, " ago%s", VTY_NEWLINE);
-       }
+ {
+   return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3], NULL, argv[4]);
+ }
  
-       for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
-       {
-           char addrstr[32];
+ DEFUN (ip_route_flags2_vrf,
+        ip_route_flags2_vrf_cmd,
+        "ip route A.B.C.D/M (reject|blackhole)" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL, NULL, argv[2]);
+ }
  
-         vty_out (vty, "  %c%s",
-                  CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
-                  recursing ? "  " : "");
+ DEFUN (ip_route_flags2_tag_vrf,
+        ip_route_flags2_tag_vrf_cmd,
+        "ip route A.B.C.D/M (reject|blackhole) tag <1-65535>" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        VRF_CMD_HELP_STR)
  
-         switch (nexthop->type)
-           {
-           case NEXTHOP_TYPE_IPV4:
-           case NEXTHOP_TYPE_IPV4_IFINDEX:
-             vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
-             if (nexthop->ifindex)
-               vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
-             break;
- #ifdef HAVE_IPV6
-           case NEXTHOP_TYPE_IPV6:
-           case NEXTHOP_TYPE_IPV6_IFINDEX:
-           case NEXTHOP_TYPE_IPV6_IFNAME:
-             vty_out (vty, " %s",
-                      inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
-             if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
-               vty_out (vty, ", %s", nexthop->ifname);
-             else if (nexthop->ifindex)
-               vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
-             break;
- #endif /* HAVE_IPV6 */
-           case NEXTHOP_TYPE_IFINDEX:
-             vty_out (vty, " directly connected, %s",
-                      ifindex2ifname (nexthop->ifindex));
-             break;
-           case NEXTHOP_TYPE_IFNAME:
-             vty_out (vty, " directly connected, %s", nexthop->ifname);
-             break;
-       case NEXTHOP_TYPE_BLACKHOLE:
-         vty_out (vty, " directly connected, Null0");
-         break;
-       default:
-             break;
-           }
-         if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
-           vty_out (vty, " inactive");
+ {
+   return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2], NULL, argv[3]);
+ }
  
-         if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
-           vty_out (vty, " onlink");
+ /* Mask as A.B.C.D format.  */
+ DEFUN (ip_route_mask_vrf,
+        ip_route_mask_vrf_cmd,
+        "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL, argv[3]);
+ }
  
-         if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
-           vty_out (vty, " (recursive)");
+ DEFUN (ip_route_mask_tag_vrf,
+        ip_route_mask_tag_vrf_cmd,
+        "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535>" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        VRF_CMD_HELP_STR)
  
-         switch (nexthop->type)
-             {
-             case NEXTHOP_TYPE_IPV4:
-             case NEXTHOP_TYPE_IPV4_IFINDEX:
-             case NEXTHOP_TYPE_IPV4_IFNAME:
-               if (nexthop->src.ipv4.s_addr)
-                 {
-                 if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
-                     sizeof addrstr))
-                     vty_out (vty, ", src %s", addrstr);
-                 }
-               break;
- #ifdef HAVE_IPV6
-             case NEXTHOP_TYPE_IPV6:
-             case NEXTHOP_TYPE_IPV6_IFINDEX:
-             case NEXTHOP_TYPE_IPV6_IFNAME:
-               if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
-                 {
-                 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
-                     sizeof addrstr))
-                     vty_out (vty, ", src %s", addrstr);
-                 }
-               break;
- #endif /* HAVE_IPV6 */
-             default:
-              break;
-             }
-         vty_out (vty, "%s", VTY_NEWLINE);
-       }
-       vty_out (vty, "%s", VTY_NEWLINE);
-     }
+ {
+   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL, argv[4]);
  }
  
- static void
- vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
+ DEFUN (ip_route_mask_flags_vrf,
+        ip_route_mask_flags_vrf_cmd,
+        "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        VRF_CMD_HELP_STR)
  {
-   struct nexthop *nexthop, *tnexthop;
-   int recursing;
-   int len = 0;
-   char buf[BUFSIZ];
+   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, NULL, argv[4]);
+ }
  
-   /* Nexthop information. */
-   for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
-     {
-       if (nexthop == rib->nexthop)
-       {
-         /* Prefix information. */
-         len = vty_out (vty, "%c", zebra_route_char (rib->type));
-           if (rib->instance)
-           len += vty_out (vty, "[%d]", rib->instance);
-           len += vty_out (vty, "%c%c %s/%d",
-                        CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
-                        ? '>' : ' ',
-                        CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
-                        ? '*' : ' ',
-                        inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
-                        rn->p.prefixlen);
+ DEFUN (ip_route_mask_flags_tag_vrf,
+        ip_route_mask_flags_tag_vrf_cmd,
+        "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-65535>" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        VRF_CMD_HELP_STR)
  
-         /* Distance and metric display. */
-         if (rib->type != ZEBRA_ROUTE_CONNECT 
-             && rib->type != ZEBRA_ROUTE_KERNEL)
-           len += vty_out (vty, " [%d/%d]", rib->distance,
-                           rib->metric);
-       }
-       else
-       vty_out (vty, "  %c%*c",
-                CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
-                ? '*' : ' ',
-                len - 3 + (2 * recursing), ' ');
-       switch (nexthop->type)
-       {
-       case NEXTHOP_TYPE_IPV4:
-       case NEXTHOP_TYPE_IPV4_IFINDEX:
-         vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
-         if (nexthop->ifindex)
-           vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
-         break;
- #ifdef HAVE_IPV6
-         case NEXTHOP_TYPE_IPV6:
-       case NEXTHOP_TYPE_IPV6_IFINDEX:
-       case NEXTHOP_TYPE_IPV6_IFNAME:
-         vty_out (vty, " via %s",
-                  inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
-         if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
-           vty_out (vty, ", %s", nexthop->ifname);
-         else if (nexthop->ifindex)
-           vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
-         break;
- #endif /* HAVE_IPV6 */
-       case NEXTHOP_TYPE_IFINDEX:
-         vty_out (vty, " is directly connected, %s",
-                  ifindex2ifname (nexthop->ifindex));
-         break;
-       case NEXTHOP_TYPE_IFNAME:
-         vty_out (vty, " is directly connected, %s", nexthop->ifname);
-         break;
-   case NEXTHOP_TYPE_BLACKHOLE:
-     vty_out (vty, " is directly connected, Null0");
-     break;
-   default:
-         break;
-       }
-       if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
-       vty_out (vty, " inactive");
-       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
-       vty_out (vty, " onlink");
-       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
-       vty_out (vty, " (recursive)");
-       switch (nexthop->type)
-         {
-           case NEXTHOP_TYPE_IPV4:
-           case NEXTHOP_TYPE_IPV4_IFINDEX:
-           case NEXTHOP_TYPE_IPV4_IFNAME:
-             if (nexthop->src.ipv4.s_addr)
-               {
-               if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
-                   vty_out (vty, ", src %s", buf);
-               }
-             break;
- #ifdef HAVE_IPV6
-           case NEXTHOP_TYPE_IPV6:
-           case NEXTHOP_TYPE_IPV6_IFINDEX:
-           case NEXTHOP_TYPE_IPV6_IFNAME:
-             if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
-               {
-               if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
-                   vty_out (vty, ", src %s", buf);
-               }
-             break;
- #endif /* HAVE_IPV6 */
-           default:
-           break;
-         }
-       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
-                vty_out (vty, ", bh");
-       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
-                vty_out (vty, ", rej");
-       if (rib->type == ZEBRA_ROUTE_RIP
-         || rib->type == ZEBRA_ROUTE_OSPF
-         || rib->type == ZEBRA_ROUTE_BABEL
-         || rib->type == ZEBRA_ROUTE_ISIS
-         || rib->type == ZEBRA_ROUTE_TABLE
-         || rib->type == ZEBRA_ROUTE_BGP)
-       {
-         time_t uptime;
-         struct tm *tm;
-         uptime = time (NULL);
-         uptime -= rib->uptime;
-         tm = gmtime (&uptime);
- #define ONE_DAY_SECOND 60*60*24
- #define ONE_WEEK_SECOND 60*60*24*7
-         if (uptime < ONE_DAY_SECOND)
-           vty_out (vty,  ", %02d:%02d:%02d", 
-                    tm->tm_hour, tm->tm_min, tm->tm_sec);
-         else if (uptime < ONE_WEEK_SECOND)
-           vty_out (vty, ", %dd%02dh%02dm", 
-                    tm->tm_yday, tm->tm_hour, tm->tm_min);
-         else
-           vty_out (vty, ", %02dw%dd%02dh", 
-                    tm->tm_yday/7,
-                    tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
-       }
-       vty_out (vty, "%s", VTY_NEWLINE);
-     }
+ {
+   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, argv[5]);
  }
  
- DEFUN (show_ip_route,
-        show_ip_route_cmd,
-        "show ip route",
-        SHOW_STR
+ DEFUN (ip_route_mask_flags2_vrf,
+        ip_route_mask_flags2_vrf_cmd,
+        "ip route A.B.C.D A.B.C.D (reject|blackhole)" VRF_CMD_STR,
         IP_STR
-        "IP routing table\n")
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        VRF_CMD_HELP_STR)
  {
-   struct route_table *table;
-   struct route_node *rn;
-   struct rib *rib;
-   int first = 1;
-   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
-   if (! table)
-     return CMD_SUCCESS;
-   /* Show all IPv4 routes. */
-   for (rn = route_top (table); rn; rn = route_next (rn))
-     RNODE_FOREACH_RIB (rn, rib)
-       {
-       if (first)
-         {
-           vty_out (vty, SHOW_ROUTE_V4_HEADER);
-           first = 0;
-         }
-         vty_show_ip_route (vty, rn, rib);
-       }
-   return CMD_SUCCESS;
+   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, NULL, argv[3]);
  }
  
- DEFUN (show_ip_nht,
-        show_ip_nht_cmd,
-        "show ip nht",
-        SHOW_STR
+ DEFUN (ip_route_mask_flags2_tag_vrf,
+        ip_route_mask_flags2_tag_vrf_cmd,
+        "ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-65535>" VRF_CMD_STR,
         IP_STR
-        "IP nexthop tracking table\n")
+        "Establish static routes\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"
+        VRF_CMD_HELP_STR)
  {
-   zebra_print_rnh_table(0, AF_INET, vty, RNH_NEXTHOP_TYPE);
-   return CMD_SUCCESS;
+   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], NULL, argv[4]);
  }
  
- DEFUN (show_ipv6_nht,
       show_ipv6_nht_cmd,
-        "show ipv6 nht",
-        SHOW_STR
+ /* Distance option value.  */
DEFUN (ip_route_distance_vrf,
+        ip_route_distance_vrf_cmd,
+        "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>" VRF_CMD_STR,
         IP_STR
-        "IPv6 nexthop tracking table\n")
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
  {
-   zebra_print_rnh_table(0, AF_INET6, vty, RNH_NEXTHOP_TYPE);
-   return CMD_SUCCESS;
+   return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL, argv[2], argv[3]);
  }
  
- DEFUN (ip_nht_default_route,
-        ip_nht_default_route_cmd,
-        "ip nht resolve-via-default",
+ DEFUN (ip_route_tag_distance_vrf,
+        ip_route_tag_distance_vrf_cmd,
+        "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255>" VRF_CMD_STR,
         IP_STR
-        "Filter Next Hop tracking route resolution\n"
-        "Resolve via default route\n")
- {
-   if (zebra_rnh_ip_default_route)
-     return CMD_SUCCESS;
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
  
-   zebra_rnh_ip_default_route = 1;
-   zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
-   return CMD_SUCCESS;
+ {
+   return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2], argv[3], argv[4]);
  }
  
- DEFUN (no_ip_nht_default_route,
-        no_ip_nht_default_route_cmd,
-        "no ip nht resolve-via-default",
-        NO_STR
+ DEFUN (ip_route_flags_distance_vrf,
+        ip_route_flags_distance_vrf_cmd,
+        "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>" VRF_CMD_STR,
         IP_STR
-        "Filter Next Hop tracking route resolution\n"
-        "Resolve via default route\n")
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
  {
-   if (!zebra_rnh_ip_default_route)
-     return CMD_SUCCESS;
-   zebra_rnh_ip_default_route = 0;
-   zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
-   return CMD_SUCCESS;
+   return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL, argv[3], argv[4]);
  }
  
- DEFUN (ipv6_nht_default_route,
-        ipv6_nht_default_route_cmd,
-        "ipv6 nht resolve-via-default",
-        IP6_STR
-        "Filter Next Hop tracking route resolution\n"
-        "Resolve via default route\n")
+ DEFUN (ip_route_flags_tag_distance_vrf,
+        ip_route_flags_tag_distance_vrf_cmd,
+        "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-65535> <1-255>" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\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)
  {
-   if (zebra_rnh_ipv6_default_route)
-     return CMD_SUCCESS;
-   zebra_rnh_ipv6_default_route = 1;
-   zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
-   return CMD_SUCCESS;
+   return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3], argv[4],argv[5]);
  }
  
- DEFUN (no_ipv6_nht_default_route,
-        no_ipv6_nht_default_route_cmd,
-        "no ipv6 nht resolve-via-default",
-        NO_STR
-        IP6_STR
-        "Filter Next Hop tracking route resolution\n"
-        "Resolve via default route\n")
+ DEFUN (ip_route_flags_distance2_vrf,
+        ip_route_flags_distance2_vrf_cmd,
+        "ip route A.B.C.D/M (reject|blackhole) <1-255>" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
  {
-   if (!zebra_rnh_ipv6_default_route)
-     return CMD_SUCCESS;
-   zebra_rnh_ipv6_default_route = 0;
-   zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
-   return CMD_SUCCESS;
+   return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL, argv[2], argv[3]);
  }
  
- DEFUN (show_ip_route_tag,
-        show_ip_route_tag_cmd,
-        "show ip route tag <1-65535>",
-        SHOW_STR
+ DEFUN (ip_route_flags_tag_distance2_vrf,
+        ip_route_flags_tag_distance2_vrf_cmd,
+        "ip route A.B.C.D/M (reject|blackhole) tag <1-65535> <1-255>" VRF_CMD_STR,
         IP_STR
-        "IP routing table\n"
-        "Show only routes with tag\n"
-        "Tag value\n")
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\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)
  {
-   struct route_table *table;
-   struct route_node *rn;
-   struct rib *rib;
-   int first = 1;
-   u_short tag = 0;
-   if (argv[0])
-     tag = atoi(argv[0]);
-   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
-   if (! table)
-     return CMD_SUCCESS;
-   /* Show all IPv4 routes with matching tag value. */
-   for (rn = route_top (table); rn; rn = route_next (rn))
-     RNODE_FOREACH_RIB (rn, rib)
-       {
-         if (rib->tag != tag)
-           continue;
-         if (first)
-           {
-             vty_out (vty, SHOW_ROUTE_V4_HEADER);
-             first = 0;
-           }
-         vty_show_ip_route (vty, rn, rib);
-       }
-   return CMD_SUCCESS;
+   return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2], argv[3], argv[4]);
  }
  
- DEFUN (show_ip_route_prefix_longer,
-        show_ip_route_prefix_longer_cmd,
-        "show ip route A.B.C.D/M longer-prefixes",
-        SHOW_STR
+ DEFUN (ip_route_mask_distance_vrf,
+        ip_route_mask_distance_vrf_cmd,
+        "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>" VRF_CMD_STR,
         IP_STR
-        "IP routing table\n"
-        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
-        "Show route matching the specified Network/Mask pair only\n")
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
  {
-   struct route_table *table;
-   struct route_node *rn;
-   struct rib *rib;
-   struct prefix p;
-   int ret;
-   int first = 1;
-   ret = str2prefix (argv[0], &p);
-   if (! ret)
-     {
-       vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
-       return CMD_WARNING;
-     }
-   
-   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
-   if (! table)
-     return CMD_SUCCESS;
-   /* Show matched type IPv4 routes. */
-   for (rn = route_top (table); rn; rn = route_next (rn))
-     RNODE_FOREACH_RIB (rn, rib)
-       if (prefix_match (&p, &rn->p))
-       {
-         if (first)
-           {
-             vty_out (vty, SHOW_ROUTE_V4_HEADER);
-             first = 0;
-           }
-         vty_show_ip_route (vty, rn, rib);
-       }
-   return CMD_SUCCESS;
+   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3], argv[4]);
  }
  
- DEFUN (show_ip_route_supernets,
-        show_ip_route_supernets_cmd,
-        "show ip route supernets-only",
-        SHOW_STR
+ DEFUN (ip_route_mask_tag_distance_vrf,
+        ip_route_mask_tag_distance_vrf_cmd,
+        "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255>" VRF_CMD_STR,
         IP_STR
-        "IP routing table\n"
-        "Show supernet entries only\n")
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
  {
-   struct route_table *table;
-   struct route_node *rn;
-   struct rib *rib;
-   u_int32_t addr; 
-   int first = 1;
-   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
-   if (! table)
-     return CMD_SUCCESS;
-   /* Show matched type IPv4 routes. */
-   for (rn = route_top (table); rn; rn = route_next (rn))
-     RNODE_FOREACH_RIB (rn, rib)
-       {
-       addr = ntohl (rn->p.u.prefix4.s_addr);
-       if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
-          || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
-          || (IN_CLASSA (addr) && rn->p.prefixlen < 8)) 
-         {
-           if (first)
-             {
-               vty_out (vty, SHOW_ROUTE_V4_HEADER);
-               first = 0;
-             }
-           vty_show_ip_route (vty, rn, rib);
-         }
-       }
-   return CMD_SUCCESS;
+   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], argv[5]);
  }
  
- DEFUN (show_ip_route_protocol,
-        show_ip_route_protocol_cmd,
-        "show ip route " QUAGGA_IP_REDIST_STR_ZEBRA,
-        SHOW_STR
+ DEFUN (ip_route_mask_flags_tag_distance_vrf,
+        ip_route_mask_flags_tag_distance_vrf_cmd,
+        "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)  tag <1-65535> <1-255>" VRF_CMD_STR,
         IP_STR
-        "IP routing table\n"
-        QUAGGA_IP_REDIST_HELP_STR_ZEBRA)
+        "Establish static routes\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"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        VRF_CMD_HELP_STR)
  {
-   int type;
-   struct route_table *table;
-   struct route_node *rn;
-   struct rib *rib;
-   int first = 1;
+   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
+ }
  
-   type = proto_redistnum (AFI_IP, argv[0]);
-   if (type < 0)
-     {
-       vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
-       return CMD_WARNING;
-     }
-   
-   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
-   if (! table)
-     return CMD_SUCCESS;
  
-   /* Show matched type IPv4 routes. */
-   for (rn = route_top (table); rn; rn = route_next (rn))
-     RNODE_FOREACH_RIB (rn, rib)
-       if (rib->type == type)
-       {
-         if (first)
-           {
-             vty_out (vty, SHOW_ROUTE_V4_HEADER);
-             first = 0;
-           }
-         vty_show_ip_route (vty, rn, rib);
-       }
-   return CMD_SUCCESS;
+ DEFUN (ip_route_mask_flags_distance_vrf,
+        ip_route_mask_flags_distance_vrf_cmd,
+        "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>" VRF_CMD_STR,
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], argv[5]);
  }
  
- DEFUN (show_ip_route_ospf_instance,
-        show_ip_route_ospf_instance_cmd,
-        "show ip route ospf <1-65535>",
-        SHOW_STR
+ DEFUN (ip_route_mask_flags_distance2_vrf,
+        ip_route_mask_flags_distance2_vrf_cmd,
+        "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>" VRF_CMD_STR,
         IP_STR
-        "IP routing table\n"
-        "Open Shortest Path First (OSPFv2)\n"
-        "Instance ID\n")
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
  {
-   struct route_table *table;
-   struct route_node *rn;
-   struct rib *rib;
-   int first = 1;
-   u_short instance = 0;
-   VTY_GET_INTEGER ("Instance", instance, argv[0]);
-   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
-   if (! table)
-     return CMD_SUCCESS;
-   /* Show matched type IPv4 routes. */
-   for (rn = route_top (table); rn; rn = route_next (rn))
-     RNODE_FOREACH_RIB (rn, rib)
-       if (rib->type == ZEBRA_ROUTE_OSPF && rib->instance == instance)
-       {
-         if (first)
-           {
-             vty_out (vty, SHOW_ROUTE_V4_HEADER);
-             first = 0;
-           }
-         vty_show_ip_route (vty, rn, rib);
-       }
-   return CMD_SUCCESS;
+   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, argv[3], argv[4]);
  }
  
- DEFUN (show_ip_route_addr,
-        show_ip_route_addr_cmd,
-        "show ip route A.B.C.D",
-        SHOW_STR
+ DEFUN (ip_route_mask_flags_tag_distance2_vrf,
+        ip_route_mask_flags_tag_distance2_vrf_cmd,
+        "ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-65535> <1-255>" VRF_CMD_STR,
         IP_STR
-        "IP routing table\n"
-        "Network in the IP routing table to display\n")
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        "Distance value for this route\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        VRF_CMD_HELP_STR)
  {
-   int ret;
-   struct prefix_ipv4 p;
-   struct route_table *table;
-   struct route_node *rn;
-   ret = str2prefix_ipv4 (argv[0], &p);
-   if (ret <= 0)
-     {
-       vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
-       return CMD_WARNING;
-     }
-   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
-   if (! table)
-     return CMD_SUCCESS;
-   rn = route_node_match (table, (struct prefix *) &p);
-   if (! rn)
-     {
-       vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
-       return CMD_WARNING;
-     }
-   vty_show_ip_route_detail (vty, rn);
-   route_unlock_node (rn);
-   return CMD_SUCCESS;
+   return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], argv[5]);
  }
  
- DEFUN (show_ip_route_prefix,
-        show_ip_route_prefix_cmd,
-        "show ip route A.B.C.D/M",
-        SHOW_STR
+ DEFUN (no_ip_route_vrf, 
+        no_ip_route_vrf_cmd,
+        "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)" VRF_CMD_STR,
+        NO_STR
         IP_STR
-        "IP routing table\n"
-        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        VRF_CMD_HELP_STR)
  {
-   int ret;
-   struct prefix_ipv4 p;
-   struct route_table *table;
-   struct route_node *rn;
-   ret = str2prefix_ipv4 (argv[0], &p);
-   if (ret <= 0)
-     {
-       vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
-       return CMD_WARNING;
-     }
+   return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL, NULL, argv[2]);
+ }
  
-   table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
-   if (! table)
-     return CMD_SUCCESS;
+ DEFUN (no_ip_route_tag_vrf,
+        no_ip_route_tag_vrf_cmd,
+        "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-65535>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        "Tag of this route\n"
+        "Tag value\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2], NULL, argv[3]);
+ }
  
-   rn = route_node_match (table, (struct prefix *) &p);
-   if (! rn || rn->p.prefixlen != p.prefixlen)
-     {
-       vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
-       return CMD_WARNING;
-     }
+ ALIAS (no_ip_route_vrf,
+        no_ip_route_flags_vrf_cmd,
+        "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        VRF_CMD_HELP_STR)
  
-   vty_show_ip_route_detail (vty, rn);
+ ALIAS (no_ip_route_tag_vrf,
+        no_ip_route_flags_tag_vrf_cmd,
+        "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-65535>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Tag of this route\n"
+        "Tag value\n"
+        VRF_CMD_HELP_STR)
  
-   route_unlock_node (rn);
+ DEFUN (no_ip_route_flags2_vrf,
+        no_ip_route_flags2_vrf_cmd,
+        "no ip route A.B.C.D/M (reject|blackhole)" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, NULL, NULL, argv[1]);
+ }
  
-   return CMD_SUCCESS;
+ DEFUN (no_ip_route_flags2_tag_vrf,
+        no_ip_route_flags2_tag_vrf_cmd,
+        "no ip route A.B.C.D/M (reject|blackhole) tag <1-65535>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Tag of this route\n"
+        "Tag value\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, argv[1], NULL, argv[1]);
  }
  
- static void
- vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
+ DEFUN (no_ip_route_mask_vrf,
+        no_ip_route_mask_vrf_cmd,
+        "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        VRF_CMD_HELP_STR)
  {
-   struct route_node *rn;
-   struct rib *rib;
-   struct nexthop *nexthop;
- #define ZEBRA_ROUTE_IBGP  ZEBRA_ROUTE_MAX
- #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
-   u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
-   u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
-   u_int32_t i;
+   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL, argv[3]);
+ }
  
-   memset (&rib_cnt, 0, sizeof(rib_cnt));
-   memset (&fib_cnt, 0, sizeof(fib_cnt));
-   for (rn = route_top (table); rn; rn = route_next (rn))
-     RNODE_FOREACH_RIB (rn, rib)
-       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
-         {
-         rib_cnt[ZEBRA_ROUTE_TOTAL]++;
-         rib_cnt[rib->type]++;
-         if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
-             || nexthop_has_fib_child(nexthop))
-           {
-             fib_cnt[ZEBRA_ROUTE_TOTAL]++;
-             fib_cnt[rib->type]++;
-           }
-         if (rib->type == ZEBRA_ROUTE_BGP && 
-             CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP)) 
-           {
-             rib_cnt[ZEBRA_ROUTE_IBGP]++;
-             if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
-                 || nexthop_has_fib_child(nexthop))
-               fib_cnt[ZEBRA_ROUTE_IBGP]++;
-           }
-       }
+ DEFUN (no_ip_route_mask_tag_vrf,
+        no_ip_route_mask_tag_vrf_cmd,
+        "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        "Tag of this route\n"
+        "Tag value\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL, argv[4]);
+ }
  
-   vty_out (vty, "%-20s %-20s %-20s %s", 
-          "Route Source", "Routes", "FIB", VTY_NEWLINE);
+ ALIAS (no_ip_route_mask_vrf,
+        no_ip_route_mask_flags_vrf_cmd,
+        "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        VRF_CMD_HELP_STR)
  
-   for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 
-     {
-       if (rib_cnt[i] > 0)
-       {
-         if (i == ZEBRA_ROUTE_BGP)
-           {
-             vty_out (vty, "%-20s %-20d %-20d %s", "ebgp", 
-                      rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
-                      fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
-                      VTY_NEWLINE);
-             vty_out (vty, "%-20s %-20d %-20d %s", "ibgp", 
-                      rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
-                      VTY_NEWLINE);
-           }
-         else 
-           vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i), 
-                    rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
-       }
-     }
+ ALIAS (no_ip_route_mask_tag_vrf,
+        no_ip_route_mask_flags_tag_vrf_cmd,
+        "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-65535>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Tag of this route\n"
+        "Tag value\n"
+        VRF_CMD_HELP_STR)
  
-   vty_out (vty, "------%s", VTY_NEWLINE);
-   vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL], 
-          fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);  
+ DEFUN (no_ip_route_mask_flags2_vrf,
+        no_ip_route_mask_flags2_vrf_cmd,
+        "no ip route A.B.C.D A.B.C.D (reject|blackhole)" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, NULL, NULL, argv[2]);
  }
  
- /*
-  * Implementation of the ip route summary prefix command.
-  *
-  * This command prints the primary prefixes that have been installed by various
-  * protocols on the box.
-  *
-  */
- static void
- vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
+ DEFUN (no_ip_route_mask_flags2_tag_vrf,
+        no_ip_route_mask_flags2_tag_vrf_cmd,
+        "no ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-65535>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Tag of this route\n"
+        "Tag value\n"
+        VRF_CMD_HELP_STR)
  {
-   struct route_node *rn;
-   struct rib *rib;
-   struct nexthop *nexthop;
- #define ZEBRA_ROUTE_IBGP  ZEBRA_ROUTE_MAX
- #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
-   u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
-   u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
-   u_int32_t i;
-   int       cnt;
-   memset (&rib_cnt, 0, sizeof(rib_cnt));
-   memset (&fib_cnt, 0, sizeof(fib_cnt));
-   for (rn = route_top (table); rn; rn = route_next (rn))
-     RNODE_FOREACH_RIB (rn, rib)
-       {
+   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], NULL, argv[3]);
+ }
  
-        /*
-         * In case of ECMP, count only once.
-         */
-        cnt = 0;
-        for (nexthop = rib->nexthop; (!cnt && nexthop); nexthop = nexthop->next)
-          {
-           cnt++;
-           rib_cnt[ZEBRA_ROUTE_TOTAL]++;
-           rib_cnt[rib->type]++;
-           if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
-               {
-                fib_cnt[ZEBRA_ROUTE_TOTAL]++;
-              fib_cnt[rib->type]++;
-             }
-             if (rib->type == ZEBRA_ROUTE_BGP &&
-                 CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
-             {
-                rib_cnt[ZEBRA_ROUTE_IBGP]++;
-                    if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
-                       fib_cnt[ZEBRA_ROUTE_IBGP]++;
-             }
-            }
-       }
  
-   vty_out (vty, "%-20s %-20s %-20s %s",
-          "Route Source", "Prefix Routes", "FIB", VTY_NEWLINE);
+ DEFUN (no_ip_route_distance_vrf,
+        no_ip_route_distance_vrf_cmd,
+        "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL, argv[2], argv[3]);
+ }
  
-   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
-     {
-       if (rib_cnt[i] > 0)
-       {
-         if (i == ZEBRA_ROUTE_BGP)
-           {
-             vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
-                      rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
-                      fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
-                      VTY_NEWLINE);
-             vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
-                      rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
-                      VTY_NEWLINE);
-           }
+ DEFUN (no_ip_route_tag_distance_vrf,
+        no_ip_route_tag_distance_vrf_cmd,
+        "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        "Tag of this route\n"
+        "Tag value\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2], argv[3], argv[4]);
+ }
+ DEFUN (no_ip_route_flags_distance_vrf,
+        no_ip_route_flags_distance_vrf_cmd,
+        "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], NULL, argv[3], argv[4]);
+ }
+ DEFUN (no_ip_route_flags_tag_distance_vrf,
+        no_ip_route_flags_tag_distance_vrf_cmd,
+        "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-65535> <1-255>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Tag of this route\n"
+        "Tag value\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3], argv[4],argv[5]);
+ }
+ DEFUN (no_ip_route_flags_distance2_vrf,
+        no_ip_route_flags_distance2_vrf_cmd,
+        "no ip route A.B.C.D/M (reject|blackhole) <1-255>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], NULL, argv[2], argv[3]);
+ }
+ DEFUN (no_ip_route_flags_tag_distance2_vrf,
+        no_ip_route_flags_tag_distance2_vrf_cmd,
+        "no ip route A.B.C.D/M (reject|blackhole) tag <1-65535> <1-255>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix (e.g. 10.0.0.0/8)\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Tag of this route\n"
+        "Tag value\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], argv[2] , argv[3], argv[4]);
+ }
+ DEFUN (no_ip_route_mask_distance_vrf,
+        no_ip_route_mask_distance_vrf_cmd,
+        "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, argv[3], argv[4]);
+ }
+ DEFUN (no_ip_route_mask_tag_distance_vrf,
+        no_ip_route_mask_tag_distance_vrf_cmd,
+        "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-65535> <1-255>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Null interface\n"
+        "Tag of this route\n"
+        "Tag value\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], argv[5]);
+ }
+ DEFUN (no_ip_route_mask_flags_distance_vrf,
+        no_ip_route_mask_flags_distance_vrf_cmd,
+        "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], argv[5]);
+ }
+ DEFUN (no_ip_route_mask_flags_tag_distance_vrf,
+        no_ip_route_mask_flags_tag_distance_vrf_cmd,
+        "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-65535> <1-255>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "IP gateway address\n"
+        "IP gateway interface name\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Tag of this route\n"
+        "Tag value\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
+ }
+ DEFUN (no_ip_route_mask_flags_distance2_vrf,
+        no_ip_route_mask_flags_distance2_vrf_cmd,
+        "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, argv[3], argv[4]);
+ }
+ DEFUN (no_ip_route_mask_flags_tag_distance2_vrf,
+        no_ip_route_mask_flags_tag_distance2_vrf_cmd,
+        "no ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-65535> <1-255>" VRF_CMD_STR,
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IP destination prefix\n"
+        "IP destination prefix mask\n"
+        "Emit an ICMP unreachable when matched\n"
+        "Silently discard pkts when matched\n"
+        "Tag of this route\n"
+        "Tag value\n"
+        "Distance value for this route\n"
+        VRF_CMD_HELP_STR)
+ {
+   return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], argv[5]);
+ }
+ /* New RIB.  Detailed information for IPv4 route. */
+ static void
+ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
+ {
+   struct rib *rib;
+   struct nexthop *nexthop, *tnexthop;
+   int recursing;
+   char buf[BUFSIZ];
+   RNODE_FOREACH_RIB (rn, rib)
+     {
+       vty_out (vty, "Routing entry for %s/%d%s", 
+              inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
+              VTY_NEWLINE);
+       vty_out (vty, "  Known via \"%s", zebra_route_string (rib->type));
+       if (rib->instance)
+         vty_out (vty, "[%d]", rib->instance);
+       vty_out (vty, "\"");
+       vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
+       if (rib->tag)
+       vty_out (vty, ", tag %d", rib->tag);
+       vty_out (vty, ", vrf %u", rib->vrf_id);
+       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
+       vty_out (vty, ", best");
+       if (rib->refcnt)
+       vty_out (vty, ", refcnt %ld", rib->refcnt);
+       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
+        vty_out (vty, ", blackhole");
+       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
+        vty_out (vty, ", reject");
+       vty_out (vty, "%s", VTY_NEWLINE);
+ #define ONE_DAY_SECOND 60*60*24
+ #define ONE_WEEK_SECOND 60*60*24*7
+       if (rib->type == ZEBRA_ROUTE_RIP
+         || rib->type == ZEBRA_ROUTE_OSPF
+         || rib->type == ZEBRA_ROUTE_BABEL
+         || rib->type == ZEBRA_ROUTE_ISIS
+         || rib->type == ZEBRA_ROUTE_TABLE
+         || rib->type == ZEBRA_ROUTE_BGP)
+       {
+         time_t uptime;
+         struct tm *tm;
+         uptime = time (NULL);
+         uptime -= rib->uptime;
+         tm = gmtime (&uptime);
+         vty_out (vty, "  Last update ");
+         if (uptime < ONE_DAY_SECOND)
+           vty_out (vty,  "%02d:%02d:%02d", 
+                    tm->tm_hour, tm->tm_min, tm->tm_sec);
+         else if (uptime < ONE_WEEK_SECOND)
+           vty_out (vty, "%dd%02dh%02dm", 
+                    tm->tm_yday, tm->tm_hour, tm->tm_min);
          else
-           vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
-                    rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
+           vty_out (vty, "%02dw%dd%02dh", 
+                    tm->tm_yday/7,
+                    tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
+         vty_out (vty, " ago%s", VTY_NEWLINE);
+       }
+       for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
+       {
+           char addrstr[32];
+         vty_out (vty, "  %c%s",
+                  CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
+                  recursing ? "  " : "");
+         switch (nexthop->type)
+           {
+           case NEXTHOP_TYPE_IPV4:
+           case NEXTHOP_TYPE_IPV4_IFINDEX:
+             vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
+             if (nexthop->ifindex)
+               vty_out (vty, ", via %s",
+                          ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
+             break;
+ #ifdef HAVE_IPV6
+           case NEXTHOP_TYPE_IPV6:
+           case NEXTHOP_TYPE_IPV6_IFINDEX:
+           case NEXTHOP_TYPE_IPV6_IFNAME:
+             vty_out (vty, " %s",
+                      inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
+             if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
+               vty_out (vty, ", %s", nexthop->ifname);
+             else if (nexthop->ifindex)
+               vty_out (vty, ", via %s",
+                          ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
+             break;
+ #endif /* HAVE_IPV6 */
+           case NEXTHOP_TYPE_IFINDEX:
+             vty_out (vty, " directly connected, %s",
+                      ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
+             break;
+           case NEXTHOP_TYPE_IFNAME:
+             vty_out (vty, " directly connected, %s", nexthop->ifname);
+             break;
+       case NEXTHOP_TYPE_BLACKHOLE:
+         vty_out (vty, " directly connected, Null0");
+         break;
+       default:
+             break;
+           }
+         if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+           vty_out (vty, " inactive");
+         if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
+           vty_out (vty, " onlink");
+         if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+           vty_out (vty, " (recursive)");
+         switch (nexthop->type)
+             {
+             case NEXTHOP_TYPE_IPV4:
+             case NEXTHOP_TYPE_IPV4_IFINDEX:
+             case NEXTHOP_TYPE_IPV4_IFNAME:
+               if (nexthop->src.ipv4.s_addr)
+                 {
+                 if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
+                     sizeof addrstr))
+                     vty_out (vty, ", src %s", addrstr);
+                 }
+               break;
+ #ifdef HAVE_IPV6
+             case NEXTHOP_TYPE_IPV6:
+             case NEXTHOP_TYPE_IPV6_IFINDEX:
+             case NEXTHOP_TYPE_IPV6_IFNAME:
+               if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
+                 {
+                 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
+                     sizeof addrstr))
+                     vty_out (vty, ", src %s", addrstr);
+                 }
+               break;
+ #endif /* HAVE_IPV6 */
+             default:
+              break;
+             }
+         vty_out (vty, "%s", VTY_NEWLINE);
+       }
+       vty_out (vty, "%s", VTY_NEWLINE);
+     }
+ }
+ static void
+ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
+ {
+   struct nexthop *nexthop, *tnexthop;
+   int recursing;
+   int len = 0;
+   char buf[BUFSIZ];
+   /* Nexthop information. */
+   for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
+     {
+       if (nexthop == rib->nexthop)
+       {
+         /* Prefix information. */
+         len = vty_out (vty, "%c", zebra_route_char (rib->type));
+           if (rib->instance)
+           len += vty_out (vty, "[%d]", rib->instance);
+           len += vty_out (vty, "%c%c %s/%d",
+                        CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
+                        ? '>' : ' ',
+                        CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
+                        ? '*' : ' ',
+                        inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
+                        rn->p.prefixlen);
+         /* Distance and metric display. */
+         if (rib->type != ZEBRA_ROUTE_CONNECT 
+             && rib->type != ZEBRA_ROUTE_KERNEL)
+           len += vty_out (vty, " [%d/%d]", rib->distance,
+                           rib->metric);
+           if (rib->vrf_id != VRF_DEFAULT)
+             len += vty_out (vty, " [vrf %u]", rib->vrf_id);
+       }
+       else
+       vty_out (vty, "  %c%*c",
+                CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
+                ? '*' : ' ',
+                len - 3 + (2 * recursing), ' ');
+       switch (nexthop->type)
+       {
+       case NEXTHOP_TYPE_IPV4:
+       case NEXTHOP_TYPE_IPV4_IFINDEX:
+         vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
+         if (nexthop->ifindex)
+           vty_out (vty, ", %s",
+                      ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
+         break;
+ #ifdef HAVE_IPV6
+         case NEXTHOP_TYPE_IPV6:
+       case NEXTHOP_TYPE_IPV6_IFINDEX:
+       case NEXTHOP_TYPE_IPV6_IFNAME:
+         vty_out (vty, " via %s",
+                  inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
+         if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
+           vty_out (vty, ", %s", nexthop->ifname);
+         else if (nexthop->ifindex)
+           vty_out (vty, ", %s",
+                      ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
+         break;
+ #endif /* HAVE_IPV6 */
+       case NEXTHOP_TYPE_IFINDEX:
+         vty_out (vty, " is directly connected, %s",
+                  ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
+         break;
+       case NEXTHOP_TYPE_IFNAME:
+         vty_out (vty, " is directly connected, %s", nexthop->ifname);
+         break;
+   case NEXTHOP_TYPE_BLACKHOLE:
+     vty_out (vty, " is directly connected, Null0");
+     break;
+   default:
+         break;
+       }
+       if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+       vty_out (vty, " inactive");
+       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
+       vty_out (vty, " onlink");
+       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+       vty_out (vty, " (recursive)");
+       switch (nexthop->type)
+         {
+           case NEXTHOP_TYPE_IPV4:
+           case NEXTHOP_TYPE_IPV4_IFINDEX:
+           case NEXTHOP_TYPE_IPV4_IFNAME:
+             if (nexthop->src.ipv4.s_addr)
+               {
+               if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
+                   vty_out (vty, ", src %s", buf);
+               }
+             break;
+ #ifdef HAVE_IPV6
+           case NEXTHOP_TYPE_IPV6:
+           case NEXTHOP_TYPE_IPV6_IFINDEX:
+           case NEXTHOP_TYPE_IPV6_IFNAME:
+             if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
+               {
+               if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
+                   vty_out (vty, ", src %s", buf);
+               }
+             break;
+ #endif /* HAVE_IPV6 */
+           default:
+           break;
+         }
+       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
+                vty_out (vty, ", bh");
+       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
+                vty_out (vty, ", rej");
+       if (rib->type == ZEBRA_ROUTE_RIP
+         || rib->type == ZEBRA_ROUTE_OSPF
+         || rib->type == ZEBRA_ROUTE_BABEL
+         || rib->type == ZEBRA_ROUTE_ISIS
+         || rib->type == ZEBRA_ROUTE_TABLE
+         || rib->type == ZEBRA_ROUTE_BGP)
+       {
+         time_t uptime;
+         struct tm *tm;
+         uptime = time (NULL);
+         uptime -= rib->uptime;
+         tm = gmtime (&uptime);
+ #define ONE_DAY_SECOND 60*60*24
+ #define ONE_WEEK_SECOND 60*60*24*7
+         if (uptime < ONE_DAY_SECOND)
+           vty_out (vty,  ", %02d:%02d:%02d", 
+                    tm->tm_hour, tm->tm_min, tm->tm_sec);
+         else if (uptime < ONE_WEEK_SECOND)
+           vty_out (vty, ", %dd%02dh%02dm", 
+                    tm->tm_yday, tm->tm_hour, tm->tm_min);
+         else
+           vty_out (vty, ", %02dw%dd%02dh", 
+                    tm->tm_yday/7,
+                    tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
+       }
+       vty_out (vty, "%s", VTY_NEWLINE);
+     }
+ }
+ DEFUN (show_ip_route,
+        show_ip_route_cmd,
+        "show ip route",
+        SHOW_STR
+        IP_STR
+        "IP routing table\n")
+ {
+   struct route_table *table;
+   struct route_node *rn;
+   struct rib *rib;
+   int first = 1;
+   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
+   if (! table)
+     return CMD_SUCCESS;
+   /* Show all IPv4 routes. */
+   for (rn = route_top (table); rn; rn = route_next (rn))
+     RNODE_FOREACH_RIB (rn, rib)
+       {
+       if (first)
+         {
+           vty_out (vty, SHOW_ROUTE_V4_HEADER);
+           first = 0;
+         }
+         vty_show_ip_route (vty, rn, rib);
+       }
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_ip_nht,
+        show_ip_nht_cmd,
+        "show ip nht",
+        SHOW_STR
+        IP_STR
+        "IP nexthop tracking table\n")
+ {
+   zebra_print_rnh_table(0, AF_INET, vty, RNH_NEXTHOP_TYPE);
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_ipv6_nht,
+        show_ipv6_nht_cmd,
+        "show ipv6 nht",
+        SHOW_STR
+        IP_STR
+        "IPv6 nexthop tracking table\n")
+ {
+   zebra_print_rnh_table(0, AF_INET6, vty, RNH_NEXTHOP_TYPE);
+   return CMD_SUCCESS;
+ }
+ DEFUN (ip_nht_default_route,
+        ip_nht_default_route_cmd,
+        "ip nht resolve-via-default",
+        IP_STR
+        "Filter Next Hop tracking route resolution\n"
+        "Resolve via default route\n")
+ {
+   if (zebra_rnh_ip_default_route)
+     return CMD_SUCCESS;
+   zebra_rnh_ip_default_route = 1;
+   zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
+   return CMD_SUCCESS;
+ }
+ DEFUN (no_ip_nht_default_route,
+        no_ip_nht_default_route_cmd,
+        "no ip nht resolve-via-default",
+        NO_STR
+        IP_STR
+        "Filter Next Hop tracking route resolution\n"
+        "Resolve via default route\n")
+ {
+   if (!zebra_rnh_ip_default_route)
+     return CMD_SUCCESS;
+   zebra_rnh_ip_default_route = 0;
+   zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
+   return CMD_SUCCESS;
+ }
+ DEFUN (ipv6_nht_default_route,
+        ipv6_nht_default_route_cmd,
+        "ipv6 nht resolve-via-default",
+        IP6_STR
+        "Filter Next Hop tracking route resolution\n"
+        "Resolve via default route\n")
+ {
+   if (zebra_rnh_ipv6_default_route)
+     return CMD_SUCCESS;
+   zebra_rnh_ipv6_default_route = 1;
+   zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
+   return CMD_SUCCESS;
+ }
+ DEFUN (no_ipv6_nht_default_route,
+        no_ipv6_nht_default_route_cmd,
+        "no ipv6 nht resolve-via-default",
+        NO_STR
+        IP6_STR
+        "Filter Next Hop tracking route resolution\n"
+        "Resolve via default route\n")
+ {
+   if (!zebra_rnh_ipv6_default_route)
+     return CMD_SUCCESS;
+   zebra_rnh_ipv6_default_route = 0;
+   zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_ip_route_tag,
+        show_ip_route_tag_cmd,
+        "show ip route tag <1-65535>",
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Show only routes with tag\n"
+        "Tag value\n")
+ {
+   struct route_table *table;
+   struct route_node *rn;
+   struct rib *rib;
+   int first = 1;
+   u_short tag = 0;
+   if (argv[0])
+     tag = atoi(argv[0]);
+   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
+   if (! table)
+     return CMD_SUCCESS;
+   /* Show all IPv4 routes with matching tag value. */
+   for (rn = route_top (table); rn; rn = route_next (rn))
+     RNODE_FOREACH_RIB (rn, rib)
+       {
+         if (rib->tag != tag)
+           continue;
+         if (first)
+           {
+             vty_out (vty, SHOW_ROUTE_V4_HEADER);
+             first = 0;
+           }
+         vty_show_ip_route (vty, rn, rib);
+       }
+   return CMD_SUCCESS;
+ }
+ ALIAS (show_ip_route,
+        show_ip_route_vrf_cmd,
+        "show ip route " VRF_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        VRF_CMD_HELP_STR)
+ DEFUN (show_ip_route_prefix_longer,
+        show_ip_route_prefix_longer_cmd,
+        "show ip route A.B.C.D/M longer-prefixes",
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+        "Show route matching the specified Network/Mask pair only\n")
+ {
+   struct route_table *table;
+   struct route_node *rn;
+   struct rib *rib;
+   struct prefix p;
+   int ret;
+   int first = 1;
+   vrf_id_t vrf_id = VRF_DEFAULT;
+   ret = str2prefix (argv[0], &p);
+   if (! ret)
+     {
+       vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   if (argc > 1)
+     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
+   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+   if (! table)
+     return CMD_SUCCESS;
+   /* Show matched type IPv4 routes. */
+   for (rn = route_top (table); rn; rn = route_next (rn))
+     RNODE_FOREACH_RIB (rn, rib)
+       if (prefix_match (&p, &rn->p))
+       {
+         if (first)
+           {
+             vty_out (vty, SHOW_ROUTE_V4_HEADER);
+             first = 0;
+           }
+         vty_show_ip_route (vty, rn, rib);
+       }
+   return CMD_SUCCESS;
+ }
+ ALIAS (show_ip_route_prefix_longer,
+        show_ip_route_prefix_longer_vrf_cmd,
+        "show ip route A.B.C.D/M longer-prefixes " VRF_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+        "Show route matching the specified Network/Mask pair only\n"
+        VRF_CMD_HELP_STR)
+ DEFUN (show_ip_route_supernets,
+        show_ip_route_supernets_cmd,
+        "show ip route supernets-only",
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Show supernet entries only\n")
+ {
+   struct route_table *table;
+   struct route_node *rn;
+   struct rib *rib;
+   u_int32_t addr;
+   int first = 1;
+   vrf_id_t vrf_id = VRF_DEFAULT;
+   if (argc > 0)
+     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
+   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+   if (! table)
+     return CMD_SUCCESS;
+   /* Show matched type IPv4 routes. */
+   for (rn = route_top (table); rn; rn = route_next (rn))
+     RNODE_FOREACH_RIB (rn, rib)
+       {
+       addr = ntohl (rn->p.u.prefix4.s_addr);
+       if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
+          || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
+          || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
+         {
+           if (first)
+             {
+               vty_out (vty, SHOW_ROUTE_V4_HEADER);
+               first = 0;
+             }
+           vty_show_ip_route (vty, rn, rib);
+         }
+       }
+   return CMD_SUCCESS;
+ }
+ ALIAS (show_ip_route_supernets,
+        show_ip_route_supernets_vrf_cmd,
+        "show ip route supernets-only " VRF_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Show supernet entries only\n"
+        VRF_CMD_HELP_STR)
+ DEFUN (show_ip_route_protocol,
+        show_ip_route_protocol_cmd,
+        "show ip route " QUAGGA_IP_REDIST_STR_ZEBRA,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        QUAGGA_IP_REDIST_HELP_STR_ZEBRA)
+ {
+   int type;
+   struct route_table *table;
+   struct route_node *rn;
+   struct rib *rib;
+   int first = 1;
+   vrf_id_t vrf_id = VRF_DEFAULT;
+   type = proto_redistnum (AFI_IP, argv[0]);
+   if (type < 0)
+     {
+       vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   if (argc > 1)
+     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
+   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+   if (! table)
+     return CMD_SUCCESS;
+   /* Show matched type IPv4 routes. */
+   for (rn = route_top (table); rn; rn = route_next (rn))
+     RNODE_FOREACH_RIB (rn, rib)
+       if (rib->type == type)
+       {
+         if (first)
+           {
+             vty_out (vty, SHOW_ROUTE_V4_HEADER);
+             first = 0;
+           }
+         vty_show_ip_route (vty, rn, rib);
+       }
+   return CMD_SUCCESS;
+ }
+ ALIAS (show_ip_route_protocol,
+        show_ip_route_protocol_vrf_cmd,
+        "show ip route " QUAGGA_IP_REDIST_STR_ZEBRA " " VRF_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        QUAGGA_IP_REDIST_HELP_STR_ZEBRA
+        VRF_CMD_HELP_STR)
+ DEFUN (show_ip_route_ospf_instance,
+        show_ip_route_ospf_instance_cmd,
+        "show ip route ospf <1-65535>",
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Open Shortest Path First (OSPFv2)\n"
+        "Instance ID\n")
+ {
+   struct route_table *table;
+   struct route_node *rn;
+   struct rib *rib;
+   int first = 1;
+   u_short instance = 0;
+   VTY_GET_INTEGER ("Instance", instance, argv[0]);
+   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
+   if (! table)
+     return CMD_SUCCESS;
+   /* Show matched type IPv4 routes. */
+   for (rn = route_top (table); rn; rn = route_next (rn))
+     RNODE_FOREACH_RIB (rn, rib)
+       if (rib->type == ZEBRA_ROUTE_OSPF && rib->instance == instance)
+       {
+         if (first)
+           {
+             vty_out (vty, SHOW_ROUTE_V4_HEADER);
+             first = 0;
+           }
+         vty_show_ip_route (vty, rn, rib);
+       }
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_ip_route_addr,
+        show_ip_route_addr_cmd,
+        "show ip route A.B.C.D",
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Network in the IP routing table to display\n")
+ {
+   int ret;
+   struct prefix_ipv4 p;
+   struct route_table *table;
+   struct route_node *rn;
+   vrf_id_t vrf_id = VRF_DEFAULT;
+   ret = str2prefix_ipv4 (argv[0], &p);
+   if (ret <= 0)
+     {
+       vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   if (argc > 1)
+     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
+   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+   if (! table)
+     return CMD_SUCCESS;
+   rn = route_node_match (table, (struct prefix *) &p);
+   if (! rn)
+     {
+       vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   vty_show_ip_route_detail (vty, rn);
+   route_unlock_node (rn);
+   return CMD_SUCCESS;
+ }
+ ALIAS (show_ip_route_addr,
+        show_ip_route_addr_vrf_cmd,
+        "show ip route A.B.C.D " VRF_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Network in the IP routing table to display\n"
+        VRF_CMD_HELP_STR)
+ DEFUN (show_ip_route_prefix,
+        show_ip_route_prefix_cmd,
+        "show ip route A.B.C.D/M",
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+ {
+   int ret;
+   struct prefix_ipv4 p;
+   struct route_table *table;
+   struct route_node *rn;
+   vrf_id_t vrf_id = VRF_DEFAULT;
+   ret = str2prefix_ipv4 (argv[0], &p);
+   if (ret <= 0)
+     {
+       vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   if (argc > 1)
+     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
+   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+   if (! table)
+     return CMD_SUCCESS;
+   rn = route_node_match (table, (struct prefix *) &p);
+   if (! rn || rn->p.prefixlen != p.prefixlen)
+     {
+       vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   vty_show_ip_route_detail (vty, rn);
+   route_unlock_node (rn);
+   return CMD_SUCCESS;
+ }
+ ALIAS (show_ip_route_prefix,
+        show_ip_route_prefix_vrf_cmd,
+        "show ip route A.B.C.D/M " VRF_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+        VRF_CMD_HELP_STR)
+ static void
+ vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
+ {
+   struct route_node *rn;
+   struct rib *rib;
+   struct nexthop *nexthop;
+ #define ZEBRA_ROUTE_IBGP  ZEBRA_ROUTE_MAX
+ #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
+   u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
+   u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
+   u_int32_t i;
+   memset (&rib_cnt, 0, sizeof(rib_cnt));
+   memset (&fib_cnt, 0, sizeof(fib_cnt));
+   for (rn = route_top (table); rn; rn = route_next (rn))
+     RNODE_FOREACH_RIB (rn, rib)
+       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
+         {
+         rib_cnt[ZEBRA_ROUTE_TOTAL]++;
+         rib_cnt[rib->type]++;
+         if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
+             || nexthop_has_fib_child(nexthop))
+           {
+             fib_cnt[ZEBRA_ROUTE_TOTAL]++;
+             fib_cnt[rib->type]++;
+           }
+         if (rib->type == ZEBRA_ROUTE_BGP && 
+             CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP)) 
+           {
+             rib_cnt[ZEBRA_ROUTE_IBGP]++;
+             if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
+                 || nexthop_has_fib_child(nexthop))
+               fib_cnt[ZEBRA_ROUTE_IBGP]++;
+           }
+       }
+   vty_out (vty, "%-20s %-20s %s  (vrf %u)%s",
+            "Route Source", "Routes", "FIB",
+            ((rib_table_info_t *)table->info)->zvrf->vrf_id,
+            VTY_NEWLINE);
+   for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 
+     {
+       if (rib_cnt[i] > 0)
+       {
+         if (i == ZEBRA_ROUTE_BGP)
+           {
+             vty_out (vty, "%-20s %-20d %-20d %s", "ebgp", 
+                      rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
+                      fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
+                      VTY_NEWLINE);
+             vty_out (vty, "%-20s %-20d %-20d %s", "ibgp", 
+                      rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
+                      VTY_NEWLINE);
+           }
+         else 
+           vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i), 
+                    rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
+       }
+     }
+   vty_out (vty, "------%s", VTY_NEWLINE);
+   vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL], 
+          fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);  
+   vty_out (vty, "%s", VTY_NEWLINE);
+ }
+ /*
+  * Implementation of the ip route summary prefix command.
+  *
+  * This command prints the primary prefixes that have been installed by various
+  * protocols on the box.
+  *
+  */
+ static void
+ vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
+ {
+   struct route_node *rn;
+   struct rib *rib;
+   struct nexthop *nexthop;
+ #define ZEBRA_ROUTE_IBGP  ZEBRA_ROUTE_MAX
+ #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
+   u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
+   u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
+   u_int32_t i;
+   int       cnt;
+   memset (&rib_cnt, 0, sizeof(rib_cnt));
+   memset (&fib_cnt, 0, sizeof(fib_cnt));
+   for (rn = route_top (table); rn; rn = route_next (rn))
+     RNODE_FOREACH_RIB (rn, rib)
+       {
+        /*
+         * In case of ECMP, count only once.
+         */
+        cnt = 0;
+        for (nexthop = rib->nexthop; (!cnt && nexthop); nexthop = nexthop->next)
+          {
+           cnt++;
+           rib_cnt[ZEBRA_ROUTE_TOTAL]++;
+           rib_cnt[rib->type]++;
+           if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
+               {
+                fib_cnt[ZEBRA_ROUTE_TOTAL]++;
+              fib_cnt[rib->type]++;
+             }
+             if (rib->type == ZEBRA_ROUTE_BGP &&
+                 CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
+             {
+                rib_cnt[ZEBRA_ROUTE_IBGP]++;
+                    if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
+                       fib_cnt[ZEBRA_ROUTE_IBGP]++;
+             }
+            }
+       }
+   vty_out (vty, "%-20s %-20s %s  (vrf %u)%s",
+            "Route Source", "Prefix Routes", "FIB",
+            ((rib_table_info_t *)table->info)->zvrf->vrf_id,
+            VTY_NEWLINE);
+   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
+     {
+       if (rib_cnt[i] > 0)
+       {
+         if (i == ZEBRA_ROUTE_BGP)
+           {
+             vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
+                      rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
+                      fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP],
+                      VTY_NEWLINE);
+             vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
+                      rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
+                      VTY_NEWLINE);
+           }
+         else
+           vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
+                    rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
+       }
+     }
+   vty_out (vty, "------%s", VTY_NEWLINE);
+   vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
+          fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE);
+   vty_out (vty, "%s", VTY_NEWLINE);
+ }
+ /* Show route summary.  */
+ DEFUN (show_ip_route_summary,
+        show_ip_route_summary_cmd,
+        "show ip route summary",
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Summary of all routes\n")
+ {
+   struct route_table *table;
+   vrf_id_t vrf_id = VRF_DEFAULT;
+   if (argc > 0)
+     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
+   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+   if (! table)
+     return CMD_SUCCESS;
+   vty_show_ip_route_summary (vty, table);
+   return CMD_SUCCESS;
+ }
+ ALIAS (show_ip_route_summary,
+        show_ip_route_summary_vrf_cmd,
+        "show ip route summary " VRF_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Summary of all routes\n"
+        VRF_CMD_HELP_STR)
+ /* Show route summary prefix.  */
+ DEFUN (show_ip_route_summary_prefix,
+        show_ip_route_summary_prefix_cmd,
+        "show ip route summary prefix",
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Summary of all routes\n"
+        "Prefix routes\n")
+ {
+   struct route_table *table;
+   vrf_id_t vrf_id = VRF_DEFAULT;
+   if (argc > 0)
+     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
+   table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
+   if (! table)
+     return CMD_SUCCESS;
+   vty_show_ip_route_summary_prefix (vty, table);
+   return CMD_SUCCESS;
+ }
+ ALIAS (show_ip_route_summary_prefix,
+        show_ip_route_summary_prefix_vrf_cmd,
+        "show ip route summary prefix " VRF_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Summary of all routes\n"
+        "Prefix routes\n"
+        VRF_CMD_HELP_STR)
+ DEFUN (show_ip_route_vrf_all,
+        show_ip_route_vrf_all_cmd,
+        "show ip route " VRF_ALL_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        VRF_ALL_CMD_HELP_STR)
+ {
+   struct route_table *table;
+   struct route_node *rn;
+   struct rib *rib;
+   struct zebra_vrf *zvrf;
+   vrf_iter_t iter;
+   int first = 1;
+   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+     {
+       if ((zvrf = vrf_iter2info (iter)) == NULL ||
+           (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+         continue;
+       /* Show all IPv4 routes. */
+       for (rn = route_top (table); rn; rn = route_next (rn))
+         RNODE_FOREACH_RIB (rn, rib)
+           {
+             if (first)
+               {
+                 vty_out (vty, SHOW_ROUTE_V4_HEADER);
+                 first = 0;
+               }
+             vty_show_ip_route (vty, rn, rib);
+           }
+     }
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_ip_route_prefix_longer_vrf_all,
+        show_ip_route_prefix_longer_vrf_all_cmd,
+        "show ip route A.B.C.D/M longer-prefixes " VRF_ALL_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+        "Show route matching the specified Network/Mask pair only\n"
+        VRF_ALL_CMD_HELP_STR)
+ {
+   struct route_table *table;
+   struct route_node *rn;
+   struct rib *rib;
+   struct prefix p;
+   struct zebra_vrf *zvrf;
+   vrf_iter_t iter;
+   int ret;
+   int first = 1;
+   ret = str2prefix (argv[0], &p);
+   if (! ret)
+     {
+       vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+     {
+       if ((zvrf = vrf_iter2info (iter)) == NULL ||
+           (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+         continue;
+       /* Show matched type IPv4 routes. */
+       for (rn = route_top (table); rn; rn = route_next (rn))
+         RNODE_FOREACH_RIB (rn, rib)
+           if (prefix_match (&p, &rn->p))
+             {
+               if (first)
+                 {
+                   vty_out (vty, SHOW_ROUTE_V4_HEADER);
+                   first = 0;
+                 }
+               vty_show_ip_route (vty, rn, rib);
+             }
+     }
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_ip_route_supernets_vrf_all,
+        show_ip_route_supernets_vrf_all_cmd,
+        "show ip route supernets-only " VRF_ALL_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Show supernet entries only\n"
+        VRF_ALL_CMD_HELP_STR)
+ {
+   struct route_table *table;
+   struct route_node *rn;
+   struct rib *rib;
+   struct zebra_vrf *zvrf;
+   vrf_iter_t iter;
+   u_int32_t addr;
+   int first = 1;
+   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+     {
+       if ((zvrf = vrf_iter2info (iter)) == NULL ||
+           (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+         continue;
+       /* Show matched type IPv4 routes. */
+       for (rn = route_top (table); rn; rn = route_next (rn))
+         RNODE_FOREACH_RIB (rn, rib)
+           {
+             addr = ntohl (rn->p.u.prefix4.s_addr);
+             if ((IN_CLASSC (addr) && rn->p.prefixlen < 24)
+                || (IN_CLASSB (addr) && rn->p.prefixlen < 16)
+                || (IN_CLASSA (addr) && rn->p.prefixlen < 8))
+               {
+                 if (first)
+                   {
+                     vty_out (vty, SHOW_ROUTE_V4_HEADER);
+                     first = 0;
+                   }
+                 vty_show_ip_route (vty, rn, rib);
+               }
+           }
+     }
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_ip_route_protocol_vrf_all,
+        show_ip_route_protocol_vrf_all_cmd,
+        "show ip route " QUAGGA_IP_REDIST_STR_ZEBRA " " VRF_ALL_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        QUAGGA_IP_REDIST_HELP_STR_ZEBRA
+        VRF_ALL_CMD_HELP_STR)
+ {
+   int type;
+   struct route_table *table;
+   struct route_node *rn;
+   struct rib *rib;
+   struct zebra_vrf *zvrf;
+   vrf_iter_t iter;
+   int first = 1;
+   type = proto_redistnum (AFI_IP, argv[0]);
+   if (type < 0)
+     {
+       vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+     {
+       if ((zvrf = vrf_iter2info (iter)) == NULL ||
+           (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+         continue;
+       /* Show matched type IPv4 routes. */
+       for (rn = route_top (table); rn; rn = route_next (rn))
+         RNODE_FOREACH_RIB (rn, rib)
+           if (rib->type == type)
+             {
+               if (first)
+                 {
+                   vty_out (vty, SHOW_ROUTE_V4_HEADER);
+                   first = 0;
+                 }
+               vty_show_ip_route (vty, rn, rib);
+             }
+     }
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_ip_route_addr_vrf_all,
+        show_ip_route_addr_vrf_all_cmd,
+        "show ip route A.B.C.D " VRF_ALL_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Network in the IP routing table to display\n"
+        VRF_ALL_CMD_HELP_STR)
+ {
+   int ret;
+   struct prefix_ipv4 p;
+   struct route_table *table;
+   struct route_node *rn;
+   struct zebra_vrf *zvrf;
+   vrf_iter_t iter;
+   ret = str2prefix_ipv4 (argv[0], &p);
+   if (ret <= 0)
+     {
+       vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+     {
+       if ((zvrf = vrf_iter2info (iter)) == NULL ||
+           (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+         continue;
+       rn = route_node_match (table, (struct prefix *) &p);
+       if (! rn)
+         continue;
+       vty_show_ip_route_detail (vty, rn);
+       route_unlock_node (rn);
+     }
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_ip_route_prefix_vrf_all,
+        show_ip_route_prefix_vrf_all_cmd,
+        "show ip route A.B.C.D/M " VRF_ALL_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+        VRF_ALL_CMD_HELP_STR)
+ {
+   int ret;
+   struct prefix_ipv4 p;
+   struct route_table *table;
+   struct route_node *rn;
+   struct zebra_vrf *zvrf;
+   vrf_iter_t iter;
+   ret = str2prefix_ipv4 (argv[0], &p);
+   if (ret <= 0)
+     {
+       vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+     {
+       if ((zvrf = vrf_iter2info (iter)) == NULL ||
+           (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+         continue;
+       rn = route_node_match (table, (struct prefix *) &p);
+       if (! rn)
+         continue;
+       if (rn->p.prefixlen != p.prefixlen)
+         {
+           route_unlock_node (rn);
+           continue;
+         }
+       vty_show_ip_route_detail (vty, rn);
+       route_unlock_node (rn);
+     }
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_ip_route_summary_vrf_all,
+        show_ip_route_summary_vrf_all_cmd,
+        "show ip route summary " VRF_ALL_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Summary of all routes\n"
+        VRF_ALL_CMD_HELP_STR)
+ {
+   struct zebra_vrf *zvrf;
+   vrf_iter_t iter;
+   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+     if ((zvrf = vrf_iter2info (iter)) != NULL)
+       vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_ip_route_summary_prefix_vrf_all,
+        show_ip_route_summary_prefix_vrf_all_cmd,
+        "show ip route summary prefix " VRF_ALL_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP routing table\n"
+        "Summary of all routes\n"
+        "Prefix routes\n"
+        VRF_ALL_CMD_HELP_STR)
+ {
+   struct zebra_vrf *zvrf;
+   vrf_iter_t iter;
+   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+     if ((zvrf = vrf_iter2info (iter)) != NULL)
+       vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
+   return CMD_SUCCESS;
+ }
+ /* Write IPv4 static route configuration. */
+ static int
+ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
+ {
+   struct route_node *rn;
 -  struct static_ipv4 *si;  
++  struct static_route *si;
+   struct route_table *stable;
+   struct zebra_vrf *zvrf;
+   vrf_iter_t iter;
+   int write;
+   write = 0;
+   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+     {
+       if ((zvrf = vrf_iter2info (iter)) == NULL ||
+           (stable = zvrf->stable[AFI_IP][safi]) == NULL)
+         continue;
+       for (rn = route_top (stable); rn; rn = route_next (rn))
+         for (si = rn->info; si; si = si->next)
+           {
+             vty_out (vty, "%s %s/%d", cmd, inet_ntoa (rn->p.u.prefix4),
+                      rn->p.prefixlen);
+             switch (si->type)
+               {
+               case STATIC_IPV4_GATEWAY:
 -                vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
++                vty_out (vty, " %s", inet_ntoa (si->addr.ipv4));
+                 break;
+               case STATIC_IPV4_IFNAME:
 -                vty_out (vty, " %s", si->gate.ifname);
++                vty_out (vty, " %s", si->ifname);
+                 break;
+               case STATIC_IPV4_BLACKHOLE:
+                 vty_out (vty, " Null0");
+                 break;
+               }
+             /* flags are incompatible with STATIC_IPV4_BLACKHOLE */
+             if (si->type != STATIC_IPV4_BLACKHOLE)
+               {
+                 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
+                   vty_out (vty, " %s", "reject");
+                 if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
+                   vty_out (vty, " %s", "blackhole");
+               }
+             if (si->tag)
+               vty_out (vty, " tag %d", si->tag);
+             if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
+               vty_out (vty, " %d", si->distance);
+             if (si->vrf_id != VRF_DEFAULT)
+               vty_out (vty, " vrf %u", si->vrf_id);
+             vty_out (vty, "%s", VTY_NEWLINE);
+             write = 1;
+           }
+     }
+   return write;
+ }
+ /*
+  * Show IP mroute command to dump the BGP Multicast
+  * routing table
+  */
+ DEFUN (show_ip_mroute,
+        show_ip_mroute_cmd,
+        "show ip mroute",
+        SHOW_STR
+        IP_STR
+        "IP Multicast routing table\n")
+ {
+   struct route_table *table;
+   struct route_node *rn;
+   struct rib *rib;
+   int first = 1;
+   vrf_id_t vrf_id = VRF_DEFAULT;
+   if (argc > 0)
+     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
+   table = zebra_vrf_table (AFI_IP, SAFI_MULTICAST, vrf_id);
+   if (! table)
+     return CMD_SUCCESS;
+   /* Show all IPv4 routes. */
+   for (rn = route_top (table); rn; rn = route_next (rn))
+     RNODE_FOREACH_RIB (rn, rib)
+       {
+        if (first)
+          {
+          vty_out (vty, SHOW_ROUTE_V4_HEADER);
+            first = 0;
+          }
+        vty_show_ip_route (vty, rn, rib);
+       }
+   return CMD_SUCCESS;
+ }
+ ALIAS (show_ip_mroute,
+        show_ip_mroute_vrf_cmd,
+        "show ip mroute " VRF_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP Multicast routing table\n"
+        VRF_CMD_HELP_STR)
+ DEFUN (show_ip_mroute_vrf_all,
+        show_ip_mroute_vrf_all_cmd,
+        "show ip mroute " VRF_ALL_CMD_STR,
+        SHOW_STR
+        IP_STR
+        "IP Multicast routing table\n"
+        VRF_ALL_CMD_HELP_STR)
+ {
+   struct route_table *table;
+   struct route_node *rn;
+   struct rib *rib;
+   struct zebra_vrf *zvrf;
+   vrf_iter_t iter;
+   int first = 1;
+   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+     {
+       if ((zvrf = vrf_iter2info (iter)) == NULL ||
+           (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
+         continue;
+       /* Show all IPv4 routes. */
+       for (rn = route_top (table); rn; rn = route_next (rn))
+         RNODE_FOREACH_RIB (rn, rib)
+           {
+            if (first)
+              {
+                vty_out (vty, SHOW_ROUTE_V4_HEADER);
+                first = 0;
+              }
+            vty_show_ip_route (vty, rn, rib);
+           }
+     }
+   return CMD_SUCCESS;
+ }
+ #ifdef HAVE_IPV6
+ /* General fucntion for IPv6 static route. */
+ static int
+ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
+                 const char *gate_str, const char *ifname,
+                 const char *flag_str, const char *tag_str,
+                   const char *distance_str, const char *vrf_id_str)
+ {
+   int ret;
+   u_char distance;
+   struct prefix p;
+   struct in6_addr *gate = NULL;
+   struct in6_addr gate_addr;
+   u_char type = 0;
+   vrf_id_t vrf_id = VRF_DEFAULT;
+   u_char flag = 0;
+   u_short tag = 0;
+   
+   ret = str2prefix (dest_str, &p);
+   if (ret <= 0)
+     {
+       vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   /* Apply mask for given prefix. */
+   apply_mask (&p);
+   /* Route flags */
+   if (flag_str) {
+     switch(flag_str[0]) {
+       case 'r':
+       case 'R': /* XXX */
+         SET_FLAG (flag, ZEBRA_FLAG_REJECT);
+         break;
+       case 'b':
+       case 'B': /* XXX */
+         SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
+         break;
+       default:
+         vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
+         return CMD_WARNING;
+     }
+   }
+   /* Administrative distance. */
+   if (distance_str)
+     distance = atoi (distance_str);
+   else
+     distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
+   /* tag */
+   if (tag_str)
+     tag = atoi(tag_str);
+   /* When gateway is valid IPv6 addrees, then gate is treated as
+      nexthop address other case gate is treated as interface name. */
+   ret = inet_pton (AF_INET6, gate_str, &gate_addr);
+   if (ifname)
+     {
+       /* When ifname is specified.  It must be come with gateway
+          address. */
+       if (ret != 1)
+       {
+         vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
+         return CMD_WARNING;
+       }
+       type = STATIC_IPV6_GATEWAY_IFNAME;
+       gate = &gate_addr;
+     }
+   else
+     {
+       if (ret == 1)
+       {
+         type = STATIC_IPV6_GATEWAY;
+         gate = &gate_addr;
+       }
+       else
+       {
+         type = STATIC_IPV6_IFNAME;
+         ifname = gate_str;
        }
      }
  
@@@ -2916,47 -5137,53 +5137,51 @@@ static_config_ipv6 (struct vty *vty
  
    write = 0;
  
-   /* Lookup table.  */
-   stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, 0);
-   if (! stable)
-     return -1;
+   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+     {
+       if ((zvrf = vrf_iter2info (iter)) == NULL ||
+           (stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL)
+         continue;
  
-   for (rn = route_top (stable); rn; rn = route_next (rn))
-     for (si = rn->info; si; si = si->next)
-       {
-       vty_out (vty, "ipv6 route %s/%d",
-                inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
-                rn->p.prefixlen);
+       for (rn = route_top (stable); rn; rn = route_next (rn))
+         for (si = rn->info; si; si = si->next)
+           {
+             vty_out (vty, "ipv6 route %s", prefix2str (&rn->p, buf, sizeof buf));
  
-       switch (si->type)
-         {
-         case STATIC_IPV6_GATEWAY:
-           vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ));
-           break;
-         case STATIC_IPV6_IFNAME:
-           vty_out (vty, " %s", si->ifname);
-           break;
-         case STATIC_IPV6_GATEWAY_IFNAME:
-           vty_out (vty, " %s %s",
-                    inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ), si->ifname);
-           break;
-         }
 -            switch (si->type)
 -              {
 -              case STATIC_IPV6_GATEWAY:
 -                vty_out (vty, " %s",
 -                         inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
 -                break;
 -              case STATIC_IPV6_IFNAME:
 -                vty_out (vty, " %s", si->ifname);
 -                break;
 -              case STATIC_IPV6_GATEWAY_IFNAME:
 -                vty_out (vty, " %s %s",
 -                         inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ),
 -                         si->ifname);
 -                break;
 -              }
++          switch (si->type)
++            {
++            case STATIC_IPV6_GATEWAY:
++              vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ));
++              break;
++            case STATIC_IPV6_IFNAME:
++              vty_out (vty, " %s", si->ifname);
++              break;
++            case STATIC_IPV6_GATEWAY_IFNAME:
++              vty_out (vty, " %s %s",
++                       inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ), si->ifname);
++              break;
++            }
  
-        if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
-                vty_out (vty, " %s", "reject");
+             if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
+               vty_out (vty, " %s", "reject");
  
-        if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
-                vty_out (vty, " %s", "blackhole");
+             if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
+               vty_out (vty, " %s", "blackhole");
  
-         if (si->tag)
-           vty_out (vty, " tag %d", si->tag);
+             if (si->tag)
+               vty_out (vty, " tag %d", si->tag);
  
-       if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
-         vty_out (vty, " %d", si->distance);
-       vty_out (vty, "%s", VTY_NEWLINE);
+             if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
+               vty_out (vty, " %d", si->distance);
  
-       write = 1;
-       }
+             if (si->vrf_id != VRF_DEFAULT)
+               vty_out (vty, " vrf %u", si->vrf_id);
+             vty_out (vty, "%s", VTY_NEWLINE);
+             write = 1;
+           }
+     }
    return write;
  }
  #endif /* HAVE_IPV6 */