]> git.puffer.fish Git - mirror/frr.git/commitdiff
Merge branch 'cmaster-next' into vtysh-grammar
authorQuentin Young <qlyoung@cumulusnetworks.com>
Mon, 17 Oct 2016 23:36:21 +0000 (23:36 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Mon, 17 Oct 2016 23:36:21 +0000 (23:36 +0000)
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Conflicts:
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_vty.c
isisd/isis_redist.c
isisd/isis_routemap.c
isisd/isis_vty.c
isisd/isisd.c
lib/command.c
lib/distribute.c
lib/if.c
lib/keychain.c
lib/routemap.c
lib/routemap.h
ospf6d/ospf6_asbr.c
ospf6d/ospf6_interface.c
ospf6d/ospf6_neighbor.c
ospf6d/ospf6_top.c
ospf6d/ospf6_zebra.c
ospf6d/ospf6d.c
ospfd/ospf_routemap.c
ospfd/ospf_vty.c
ripd/rip_routemap.c
ripngd/ripng_routemap.c
vtysh/extract.pl.in
vtysh/vtysh.c
zebra/interface.c
zebra/irdp_interface.c
zebra/rt_netlink.c
zebra/rtadv.c
zebra/test_main.c
zebra/zebra_routemap.c
zebra/zebra_vty.c

77 files changed:
1  2 
bgpd/bgp_attr.c
bgpd/bgp_debug.c
bgpd/bgp_encap.c
bgpd/bgp_encap_tlv.c
bgpd/bgp_filter.c
bgpd/bgp_fsm.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_nexthop.c
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_vty.c
bgpd/bgpd.c
bgpd/rfapi/rfapi_vty.c
bgpd/rfapi/vnc_debug.c
configure.ac
isisd/isis_redist.c
isisd/isis_te.c
isisd/isis_vty.c
isisd/isisd.c
ldpd/ldp_vty_cmds.c
lib/Makefile.am
lib/command.c
lib/command.h
lib/distribute.c
lib/if.c
lib/json.h
lib/keychain.c
lib/log.h
lib/plist.c
lib/route_types.txt
lib/routemap.c
lib/routemap.h
lib/thread.c
lib/vrf.h
lib/vty.c
ospf6d/ospf6_area.c
ospf6d/ospf6_asbr.c
ospf6d/ospf6_interface.c
ospf6d/ospf6_neighbor.c
ospf6d/ospf6_route.h
ospf6d/ospf6_top.c
ospf6d/ospf6_zebra.c
ospf6d/ospf6d.c
ospfd/ospf_dump.c
ospfd/ospf_ri.c
ospfd/ospf_routemap.c
ospfd/ospf_te.c
ospfd/ospf_vty.c
pimd/pim_cmd.c
ripd/rip_interface.c
ripd/rip_routemap.c
ripd/rip_zebra.c
ripd/ripd.c
ripd/ripd.h
ripngd/ripng_debug.c
ripngd/ripng_interface.c
ripngd/ripng_routemap.c
ripngd/ripng_zebra.c
ripngd/ripngd.c
ripngd/ripngd.h
vtysh/extract.pl.in
vtysh/vtysh.c
zebra/connected.c
zebra/debug.c
zebra/interface.c
zebra/irdp_interface.c
zebra/rt_netlink.c
zebra/rtadv.c
zebra/test_main.c
zebra/zebra_fpm.c
zebra/zebra_mpls_vty.c
zebra/zebra_routemap.c
zebra/zebra_static.c
zebra/zebra_vrf.c
zebra/zebra_vty.c
zebra/zserv.c
zebra/zserv.h

diff --cc bgpd/bgp_attr.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc bgpd/bgp_fsm.c
Simple merge
index 48baedcea51237ce1847c7f87fc83785b6993b67,86e87883510f4bb819257aef42229b3312667761..c050e6ddd88e4b55234c032143b98ea50db075e8
@@@ -217,12 -270,25 +270,25 @@@ bgp_nlri_parse_vpn (struct peer *peer, 
                psize - VPN_PREFIXLEN_MIN_BYTES);
  
        if (attr)
 -          bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
 -                      ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
+         {
 +      bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
 +                  ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
+ #if ENABLE_BGP_VNC
+           rfapiProcessUpdate(peer, NULL, &p, &prd, attr, packet->afi, 
+                              SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
+                              &label);
+ #endif
+         }
        else
 -          bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
 -                        ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
 -        }
+         {
+ #if ENABLE_BGP_VNC
+           rfapiProcessWithdraw(peer, NULL, &p, &prd, attr, packet->afi, 
+                                SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP, 0);
+ #endif
 +      bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
 +                    ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
 +    }
+     }
    /* Packet length consistency check. */
    if (pnt != lim)
      return -1;
Simple merge
index 9f3c9baae5f9a1bfe6b4435ca02ebf489034cb41,764bb6c438d8c521e50f6ceab783994fb4b1c70c..db73d379d494a37a88ae9f48ea8cda8ecc4cc152
@@@ -60,7 -60,14 +60,13 @@@ Software Foundation, Inc., 59 Temple Pl
  #include "bgpd/bgp_mpath.h"
  #include "bgpd/bgp_nht.h"
  #include "bgpd/bgp_updgrp.h"
 -#include "bgpd/bgp_vty.h"
  
+ #if ENABLE_BGP_VNC
+ #include "bgpd/rfapi/rfapi_backend.h"
+ #include "bgpd/rfapi/vnc_import_bgp.h"
+ #include "bgpd/rfapi/vnc_export_bgp.h"
+ #endif
  /* Extern from bgp_dump.c */
  extern const char *bgp_origin_str[];
  extern const char *bgp_origin_long_str[];
@@@ -1868,8 -1924,13 +1923,13 @@@ bgp_process_main (struct work_queue *wq
        !bgp->addpath_tx_used[afi][safi])
      {
        if (bgp_zebra_has_route_changed (rn, old_select))
 -          bgp_zebra_announce (p, old_select, bgp, afi, safi);
+         {
+ #if ENABLE_BGP_VNC
+               vnc_import_bgp_add_route(bgp, p, old_select);
+               vnc_import_bgp_exterior_add_route(bgp, p, old_select);
+ #endif
-           
 +        bgp_zebra_announce (p, old_select, bgp, afi, safi);
+         }
        UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
        bgp_zebra_clear_route_change_flags (rn);
        UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
@@@ -2150,7 -2226,33 +2225,33 @@@ bgp_rib_withdraw (struct bgp_node *rn, 
          bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
          return;
        }
 - 
 +    
+ #if ENABLE_BGP_VNC
+     if (safi == SAFI_MPLS_VPN) {
+       struct bgp_node         *prn = NULL;
+       struct bgp_table        *table = NULL;
+       prn = bgp_node_get(peer->bgp->rib[afi][safi], (struct prefix *) prd);
+       if (prn->info) {
+           table = (struct bgp_table *)(prn->info);
+           vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
+               peer->bgp,
+               prd,
+               table,
+               &rn->p,
+               ri);
+       }
+       bgp_unlock_node(prn);
+     }
+     if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
+         if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) {
+           vnc_import_bgp_del_route(peer->bgp, &rn->p, ri);
+           vnc_import_bgp_exterior_del_route(peer->bgp, &rn->p, ri);
+       }
+     }
+ #endif    
    bgp_rib_remove (rn, ri, peer, afi, safi);
  }
  
@@@ -3116,9 -3317,15 +3316,15 @@@ bgp_cleanup_table(struct bgp_table *tab
              && ri->type == ZEBRA_ROUTE_BGP
              && (ri->sub_type == BGP_ROUTE_NORMAL ||
                  ri->sub_type == BGP_ROUTE_AGGREGATE))
 -            bgp_zebra_withdraw (&rn->p, ri, safi);
 -          }
+           {
+ #if ENABLE_BGP_VNC
+             if (table->owner && table->owner->bgp)
+               vnc_import_bgp_del_route(table->owner->bgp, &rn->p, ri);
+ #endif
 +          bgp_zebra_withdraw (&rn->p, ri, safi);
        }
  }
++}
  
  /* Delete all kernel routes. */
  void
@@@ -5958,7 -6374,14 +6225,14 @@@ route_vty_out (struct vty *vty, struct 
        json_object_array_add(json_paths, json_path);
      }
    else
 -      vty_out (vty, "%s", VTY_NEWLINE);
+     {
 +    vty_out (vty, "%s", VTY_NEWLINE);
+ #if ENABLE_BGP_VNC
+       /* prints an additional line, indented, with VNC info, if present */
+       if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_UNICAST))
+         rfapi_vty_out_vncinfo(vty, p, binfo, safi);
+ #endif
+     }
  }  
  
  /* called from terminal list command */
@@@ -7191,7 -7618,16 +7467,8 @@@ bgp_show_table (struct vty *vty, struc
  
          for (ri = rn->info; ri; ri = ri->next)
            {
+             total_count++;
              if (type == bgp_show_type_flap_statistics
 -                || type == bgp_show_type_flap_address
 -                || type == bgp_show_type_flap_prefix
 -                || type == bgp_show_type_flap_cidr_only
 -                || type == bgp_show_type_flap_regexp
 -                || type == bgp_show_type_flap_filter_list
 -                || type == bgp_show_type_flap_prefix_list
 -                || type == bgp_show_type_flap_prefix_longer
 -                || type == bgp_show_type_flap_route_map
                  || type == bgp_show_type_flap_neighbor
                  || type == bgp_show_type_dampend_paths
                  || type == bgp_show_type_damp_neighbor)
@@@ -10244,31 -14846,137 +10524,30 @@@ bgp_route_init (void
    install_element (BGP_IPV4M_NODE, &aggregate_address_mask_as_set_cmd);
    install_element (BGP_IPV4M_NODE, &aggregate_address_as_set_summary_cmd);
    install_element (BGP_IPV4M_NODE, &aggregate_address_mask_as_set_summary_cmd);
 -  install_element (BGP_IPV4M_NODE, &aggregate_address_summary_as_set_cmd);
 -  install_element (BGP_IPV4M_NODE, &aggregate_address_mask_summary_as_set_cmd);
    install_element (BGP_IPV4M_NODE, &no_aggregate_address_cmd);
 -  install_element (BGP_IPV4M_NODE, &no_aggregate_address_summary_only_cmd);
 -  install_element (BGP_IPV4M_NODE, &no_aggregate_address_as_set_cmd);
 -  install_element (BGP_IPV4M_NODE, &no_aggregate_address_as_set_summary_cmd);
 -  install_element (BGP_IPV4M_NODE, &no_aggregate_address_summary_as_set_cmd);
    install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
 -  install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_summary_only_cmd);
 -  install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_as_set_cmd);
 -  install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_as_set_summary_cmd);
 -  install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_summary_as_set_cmd);
  
 -  install_element (VIEW_NODE, &show_ip_bgp_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_cmd);
    install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd);
    install_element (VIEW_NODE, &show_ip_bgp_ipv4_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv4_safi_cmd);
    install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_route_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_route_pathtype_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_route_pathtype_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv4_safi_route_pathtype_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_route_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv4_safi_route_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_route_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_route_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_prefix_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_prefix_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_pathtype_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv4_safi_prefix_pathtype_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv4_safi_prefix_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_prefix_pathtype_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_prefix_pathtype_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd);
 -
 -  install_element (VIEW_NODE, &show_ip_bgp_regexp_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_regexp_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_prefix_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_prefix_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_filter_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_filter_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_filter_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_route_map_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_route_map_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_route_map_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_cidr_only_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_cidr_only_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_community_all_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_all_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_community_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_community2_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_community3_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_community4_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_community2_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_community3_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_community4_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community_all_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community2_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community3_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community4_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_community_exact_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_community2_exact_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_community3_exact_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_community4_exact_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_exact_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_community2_exact_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_community3_exact_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_community4_exact_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_community_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_community_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_community_list_exact_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_list_exact_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_prefix_longer_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_prefix_longer_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_longer_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_neighbor_advertised_route_cmd);
 +
 +  install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd);
 +  install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
 +  install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
 +  install_element (VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
 +  install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd);
 +  
 +  /* Restricted node: VIEW_NODE - (set of dangerous commands) */
-   install_element (RESTRICTED_NODE, &show_ip_bgp_route_cmd);
 +
-   install_element (ENABLE_NODE, &show_ip_bgp_instance_all_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_route_cmd);
++  install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd);
++  install_element (VIEW_NODE, &show_ip_bgp_ipv4_cmd);
++  install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
 +
-   install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_neighbor_routes_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_dampening_params_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd);
+   install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_neighbor_advertised_route_rmap_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_rmap_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_rmap_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_routes_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_received_routes_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_routes_rmap_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_received_routes_rmap_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_rmap_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_afi_safi_neighbor_adv_recd_routes_cmd);
+   install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_routes_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_routes_cmd);
+   install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd);
+   install_element (VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
+   install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_dampened_paths_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_dampd_paths_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_flap_stats_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_damp_dampened_paths_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_flap_statistics_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_damp_flap_statistics_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_flap_address_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_damp_flap_address_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_flap_prefix_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_flap_cidr_only_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_damp_flap_cidr_only_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_flap_regexp_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_flap_filter_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_damp_flap_filter_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_flap_prefix_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_damp_flap_prefix_list_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_flap_prefix_longer_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_damp_flap_prefix_longer_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_flap_route_map_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_damp_flap_route_map_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_neighbor_flap_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_neighbor_damp_cmd);
 -
 -  install_element (VIEW_NODE, &show_bgp_ipv4_prefix_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_route_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv4_vpn_route_cmd);
 -
 -  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_route_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_route_cmd);
  
   /* BGP dampening clear commands */
    install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
index 33a29e8f4c7f273d5727e35118428533c1d3ac65,acb7449a0955f0cf0091cfd260903abb1e0616f4..028158e5202e979e486efae7c7a3c3b49917de95
@@@ -108,7 -110,7 +111,7 @@@ o Local extension
    set ipv6 next-hop local : Done
    set as-path exclude     : Done
  
--*/ 
++*/
  
   /* generic value manipulation to be shared in multiple rules */
  
@@@ -330,7 -332,7 +333,7 @@@ struct route_map_rule_cmd route_match_p
  /* Match function should return 1 if match is success else return
     zero. */
  static route_map_result_t
--route_match_ip_address (void *rule, struct prefix *prefix, 
++route_match_ip_address (void *rule, struct prefix *prefix,
                        route_map_object_t type, void *object)
  {
    struct access_list *alist;
        alist = access_list_lookup (AFI_IP, (char *) rule);
        if (alist == NULL)
        return RMAP_NOMATCH;
--    
++
        return (access_list_apply (alist, prefix) == FILTER_DENY ?
              RMAP_NOMATCH : RMAP_MATCH);
      }
@@@ -376,7 -378,7 +379,7 @@@ struct route_map_rule_cmd route_match_i
  
  /* Match function return 1 if match is success else return zero. */
  static route_map_result_t
--route_match_ip_next_hop (void *rule, struct prefix *prefix, 
++route_match_ip_next_hop (void *rule, struct prefix *prefix,
                         route_map_object_t type, void *object)
  {
    struct access_list *alist;
@@@ -428,7 -430,7 +431,7 @@@ struct route_map_rule_cmd route_match_i
  
  /* Match function return 1 if match is success else return zero. */
  static route_map_result_t
--route_match_ip_route_source (void *rule, struct prefix *prefix, 
++route_match_ip_route_source (void *rule, struct prefix *prefix,
                             route_map_object_t type, void *object)
  {
    struct access_list *alist;
@@@ -485,7 -487,7 +488,7 @@@ struct route_map_rule_cmd route_match_i
  /* `match ip address prefix-list PREFIX_LIST' */
  
  static route_map_result_t
--route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, 
++route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
                                    route_map_object_t type, void *object)
  {
    struct prefix_list *plist;
        plist = prefix_list_lookup (AFI_IP, (char *) rule);
        if (plist == NULL)
        return RMAP_NOMATCH;
--    
++
        return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
              RMAP_NOMATCH : RMAP_MATCH);
      }
@@@ -692,7 -694,7 +695,7 @@@ struct route_map_rule_cmd route_match_l
  
  /* Match function return 1 if match is success else return zero. */
  static route_map_result_t
--route_match_metric (void *rule, struct prefix *prefix, 
++route_match_metric (void *rule, struct prefix *prefix,
                    route_map_object_t type, void *object)
  {
    struct rmap_value *rv;
@@@ -720,10 -722,10 +723,10 @@@ struct route_map_rule_cmd route_match_m
  
  /* Match function for as-path match.  I assume given object is */
  static route_map_result_t
--route_match_aspath (void *rule, struct prefix *prefix, 
++route_match_aspath (void *rule, struct prefix *prefix,
                    route_map_object_t type, void *object)
  {
--  
++
    struct as_list *as_list;
    struct bgp_info *bgp_info;
  
@@@ -756,7 -758,7 +759,7 @@@ route_match_aspath_free (void *rule
  }
  
  /* Route map commands for aspath matching. */
--struct route_map_rule_cmd route_match_aspath_cmd = 
++struct route_map_rule_cmd route_match_aspath_cmd =
  {
    "as-path",
    route_match_aspath,
@@@ -773,14 -775,14 +776,14 @@@ struct rmap_communit
  
  /* Match function for community match. */
  static route_map_result_t
--route_match_community (void *rule, struct prefix *prefix, 
++route_match_community (void *rule, struct prefix *prefix,
                       route_map_object_t type, void *object)
  {
    struct community_list *list;
    struct bgp_info *bgp_info;
    struct rmap_community *rcom;
  
--  if (type == RMAP_BGP) 
++  if (type == RMAP_BGP)
      {
        bgp_info = object;
        rcom = rule;
@@@ -835,12 -837,12 +838,12 @@@ route_match_community_free (void *rule
  {
    struct rmap_community *rcom = rule;
  
--  XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name); 
++  XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
    XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
  }
  
  /* Route map commands for community matching. */
--struct route_map_rule_cmd route_match_community_cmd = 
++struct route_map_rule_cmd route_match_community_cmd =
  {
    "community",
    route_match_community,
  
  /* Match function for extcommunity match. */
  static route_map_result_t
--route_match_ecommunity (void *rule, struct prefix *prefix, 
++route_match_ecommunity (void *rule, struct prefix *prefix,
                        route_map_object_t type, void *object)
  {
    struct community_list *list;
    struct bgp_info *bgp_info;
  
--  if (type == RMAP_BGP) 
++  if (type == RMAP_BGP)
      {
        bgp_info = object;
--      
++
        if (!bgp_info->attr->extra)
          return RMAP_NOMATCH;
--      
++
        list = community_list_lookup (bgp_clist, (char *) rule,
                                    EXTCOMMUNITY_LIST_MASTER);
        if (! list)
@@@ -889,7 -891,7 +892,7 @@@ route_match_ecommunity_free (void *rule
  }
  
  /* Route map commands for community matching. */
--struct route_map_rule_cmd route_match_ecommunity_cmd = 
++struct route_map_rule_cmd route_match_ecommunity_cmd =
  {
    "extcommunity",
    route_match_ecommunity,
  
  /* `match origin' */
  static route_map_result_t
--route_match_origin (void *rule, struct prefix *prefix, 
++route_match_origin (void *rule, struct prefix *prefix,
                    route_map_object_t type, void *object)
  {
    u_char *origin;
      {
        origin = rule;
        bgp_info = object;
--    
++
        if (bgp_info->attr->origin == *origin)
        return RMAP_MATCH;
      }
@@@ -1159,7 -1128,7 +1129,7 @@@ route_set_ip_nexthop (void *rule, struc
        {
           if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
             CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
--            && peer->su_remote 
++            && peer->su_remote
              && sockunion_family (peer->su_remote) == AF_INET)
            {
              bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
@@@ -1233,7 -1202,7 +1203,7 @@@ route_set_ip_nexthop_free (void *rule
  
    if (rins->address)
      XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
--    
++
    XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
  }
  
@@@ -1262,8 -1231,8 +1232,8 @@@ route_set_local_pref (void *rule, struc
        /* Fetch routemap's rule information. */
        rv = rule;
        bgp_info = object;
--    
--      /* Set local preference value. */ 
++
++      /* Set local preference value. */
        if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
        locpref = bgp_info->attr->local_pref;
  
  }
  
  /* Set local preference rule structure. */
--struct route_map_rule_cmd route_set_local_pref_cmd = 
++struct route_map_rule_cmd route_set_local_pref_cmd =
  {
    "local-preference",
    route_set_local_pref,
@@@ -1299,8 -1268,8 +1269,8 @@@ route_set_weight (void *rule, struct pr
        /* Fetch routemap's rule information. */
        rv = rule;
        bgp_info = object;
--    
--      /* Set weight value. */ 
++
++      /* Set weight value. */
        weight = route_value_adjust(rv, 0, bgp_info->peer);
        if (weight)
          (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
  }
  
  /* Set local preference rule structure. */
--struct route_map_rule_cmd route_set_weight_cmd = 
++struct route_map_rule_cmd route_set_weight_cmd =
  {
    "weight",
    route_set_weight,
  
  /* Set metric to attribute. */
  static route_map_result_t
--route_set_metric (void *rule, struct prefix *prefix, 
++route_set_metric (void *rule, struct prefix *prefix,
                  route_map_object_t type, void *object)
  {
    struct rmap_value *rv;
  }
  
  /* Set metric rule structure. */
--struct route_map_rule_cmd route_set_metric_cmd = 
++struct route_map_rule_cmd route_set_metric_cmd =
  {
    "metric",
    route_set_metric,
@@@ -1368,7 -1337,7 +1338,7 @@@ route_set_aspath_prepend (void *rule, s
    if (type == RMAP_BGP)
      {
        binfo = object;
--    
++
        if (binfo->attr->aspath->refcnt)
        new = aspath_dup (binfo->attr->aspath);
        else
@@@ -1412,7 -1381,7 +1382,7 @@@ route_set_aspath_prepend_free (void *ru
  
  
  /* Set as-path prepend rule structure. */
--struct route_map_rule_cmd route_set_aspath_prepend_cmd = 
++struct route_map_rule_cmd route_set_aspath_prepend_cmd =
  {
    "as-path prepend",
    route_set_aspath_prepend,
@@@ -1446,7 -1415,7 +1416,7 @@@ route_set_aspath_exclude (void *rule, s
  }
  
  /* Set ASn exlude rule structure. */
--struct route_map_rule_cmd route_set_aspath_exclude_cmd = 
++struct route_map_rule_cmd route_set_aspath_exclude_cmd =
  {
    "as-path exclude",
    route_set_aspath_exclude,
@@@ -1473,7 -1442,7 +1443,7 @@@ route_set_community (void *rule, struc
    struct community *new = NULL;
    struct community *old;
    struct community *merge;
--  
++
    if (type == RMAP_BGP)
      {
        rcs = rule;
        if (rcs->additive && old)
        {
          merge = community_merge (community_dup (old), rcs->com);
--        
--        /* HACK: if the old community is not intern'd, 
++
++        /* HACK: if the old community is not intern'd,
             * we should free it here, or all reference to it may be lost.
             * Really need to cleanup attribute caching sometime.
             */
        }
        else
        new = community_dup (rcs->com);
--      
++
        /* will be interned by caller if required */
        attr->community = new;
  
@@@ -1527,7 -1496,7 +1497,7 @@@ route_set_community_compile (const cha
    char *sp;
    int additive = 0;
    int none = 0;
--  
++
    if (strcmp (arg, "none") == 0)
      none = 1;
    else
        if (! com)
        return NULL;
      }
--  
++
    rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
    rcs->com = com;
    rcs->additive = additive;
    rcs->none = none;
--  
++
    return rcs;
  }
  
@@@ -1570,7 -1539,7 +1540,7 @@@ route_set_community_free (void *rule
  }
  
  /* Set community rule structure. */
--struct route_map_rule_cmd route_set_community_cmd = 
++struct route_map_rule_cmd route_set_community_cmd =
  {
    "community",
    route_set_community,
@@@ -1683,10 -1652,10 +1653,10 @@@ route_set_ecommunity (void *rule, struc
      {
        ecom = rule;
        bgp_info = object;
--    
++
        if (! ecom)
        return RMAP_OKAY;
--    
++
        /* We assume additive for Extended Community. */
        old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
  
@@@ -1731,7 -1700,7 +1701,7 @@@ route_set_ecommunity_free (void *rule
  }
  
  /* Set community rule structure. */
--struct route_map_rule_cmd route_set_ecommunity_rt_cmd = 
++struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
  {
    "extcommunity rt",
    route_set_ecommunity,
@@@ -1750,12 -1719,12 +1720,12 @@@ route_set_ecommunity_soo_compile (cons
    ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
    if (! ecom)
      return NULL;
--  
++
    return ecommunity_intern (ecom);
  }
  
  /* Set community rule structure. */
--struct route_map_rule_cmd route_set_ecommunity_soo_cmd = 
++struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
  {
    "extcommunity soo",
    route_set_ecommunity,
@@@ -1776,7 -1745,7 +1746,7 @@@ route_set_origin (void *rule, struct pr
      {
        origin = rule;
        bgp_info = object;
--    
++
        bgp_info->attr->origin = *origin;
      }
  
@@@ -1809,7 -1778,7 +1779,7 @@@ route_set_origin_free (void *rule
  }
  
  /* Set origin rule structure. */
--struct route_map_rule_cmd route_set_origin_cmd = 
++struct route_map_rule_cmd route_set_origin_cmd =
  {
    "origin",
    route_set_origin,
@@@ -1850,7 -1819,7 +1820,7 @@@ route_set_atomic_aggregate_free (void *
  }
  
  /* Set atomic aggregate rule structure. */
--struct route_map_rule_cmd route_set_atomic_aggregate_cmd = 
++struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
  {
    "atomic-aggregate",
    route_set_atomic_aggregate,
@@@ -1866,7 -1835,7 +1836,7 @@@ struct aggregato
  };
  
  static route_map_result_t
--route_set_aggregator_as (void *rule, struct prefix *prefix, 
++route_set_aggregator_as (void *rule, struct prefix *prefix,
                         route_map_object_t type, void *object)
  {
    struct bgp_info *bgp_info;
        bgp_info = object;
        aggregator = rule;
        ae = bgp_attr_extra_get (bgp_info->attr);
--      
++
        ae->aggregator_as = aggregator->as;
        ae->aggregator_addr = aggregator->address;
        bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
@@@ -1909,7 -1878,7 +1879,7 @@@ route_set_aggregator_as_free (void *rul
    XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  }
  
--struct route_map_rule_cmd route_set_aggregator_as_cmd = 
++struct route_map_rule_cmd route_set_aggregator_as_cmd =
  {
    "aggregator as",
    route_set_aggregator_as,
@@@ -1988,7 -1923,7 +1924,7 @@@ static struct route_map_rule_cmd route_
  /* `match ipv6 address IP_ACCESS_LIST' */
  
  static route_map_result_t
--route_match_ipv6_address (void *rule, struct prefix *prefix, 
++route_match_ipv6_address (void *rule, struct prefix *prefix,
                          route_map_object_t type, void *object)
  {
    struct access_list *alist;
        alist = access_list_lookup (AFI_IP6, (char *) rule);
        if (alist == NULL)
        return RMAP_NOMATCH;
--    
++
        return (access_list_apply (alist, prefix) == FILTER_DENY ?
              RMAP_NOMATCH : RMAP_MATCH);
      }
@@@ -2029,7 -1964,7 +1965,7 @@@ struct route_map_rule_cmd route_match_i
  /* `match ipv6 next-hop IP_ADDRESS' */
  
  static route_map_result_t
--route_match_ipv6_next_hop (void *rule, struct prefix *prefix, 
++route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
                           route_map_object_t type, void *object)
  {
    struct in6_addr *addr = rule;
    if (type == RMAP_BGP)
      {
        bgp_info = object;
--      
++
        if (!bgp_info->attr->extra)
          return RMAP_NOMATCH;
--      
++
        if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
        return RMAP_MATCH;
  
@@@ -2090,7 -2025,7 +2026,7 @@@ struct route_map_rule_cmd route_match_i
  /* `match ipv6 address prefix-list PREFIX_LIST' */
  
  static route_map_result_t
--route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix, 
++route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
                              route_map_object_t type, void *object)
  {
    struct prefix_list *plist;
        plist = prefix_list_lookup (AFI_IP6, (char *) rule);
        if (plist == NULL)
        return RMAP_NOMATCH;
--    
++
        return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
              RMAP_NOMATCH : RMAP_MATCH);
      }
@@@ -2131,7 -2066,7 +2067,7 @@@ struct route_map_rule_cmd route_match_i
  
  /* Set nexthop to object.  ojbect must be pointer to struct attr. */
  static route_map_result_t
--route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix, 
++route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
                               route_map_object_t type, void *object)
  {
    struct in6_addr *address;
        /* Fetch routemap's rule information. */
        address = rule;
        bgp_info = object;
--    
--      /* Set next hop value. */ 
++
++      /* Set next hop value. */
        (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
  
        /* Set nexthop length. */
@@@ -2259,7 -2194,7 +2195,7 @@@ struct route_map_rule_cmd route_set_ipv
  
  /* Set nexthop to object.  ojbect must be pointer to struct attr. */
  static route_map_result_t
--route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix, 
++route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
                              route_map_object_t type, void *object)
  {
    struct in6_addr *address;
        /* Fetch routemap's rule information. */
        address = rule;
        bgp_info = object;
--    
--      /* Set next hop value. */ 
++
++      /* Set next hop value. */
        (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
--    
++
        /* Set nexthop length. */
        if (bgp_info->attr->extra->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
        bgp_info->attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
@@@ -2418,7 -2353,7 +2354,7 @@@ struct route_map_rule_cmd route_set_ipv
  /* `set vpnv4 nexthop A.B.C.D' */
  
  static route_map_result_t
--route_set_vpnv4_nexthop (void *rule, struct prefix *prefix, 
++route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
                         route_map_object_t type, void *object)
  {
    struct in_addr *address;
        /* Fetch routemap's rule information. */
        address = rule;
        bgp_info = object;
--    
--      /* Set next hop value. */ 
++
++      /* Set next hop value. */
        (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
        (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
      }
@@@ -2481,11 -2416,11 +2417,11 @@@ route_set_originator_id (void *rule, st
    struct in_addr *address;
    struct bgp_info *bgp_info;
  
--  if (type == RMAP_BGP) 
++  if (type == RMAP_BGP)
      {
        address = rule;
        bgp_info = object;
--    
++
        bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
        (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
      }
@@@ -2521,7 -2456,7 +2457,7 @@@ route_set_originator_id_free (void *rul
  }
  
  /* Set originator-id rule structure. */
--struct route_map_rule_cmd route_set_originator_id_cmd = 
++struct route_map_rule_cmd route_set_originator_id_cmd =
  {
    "originator-id",
    route_set_originator_id,
@@@ -3718,8 -4180,8 +3662,8 @@@ DEFUN (set_aggregator_as
    int ret;
    struct in_addr address;
    char *argstr;
--  
 -  ret = inet_aton (argv[1], &address);
++
 +  ret = inet_aton (argv[idx_ipv4]->arg, &address);
    if (ret == 0)
      {
        vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
@@@ -3755,10 -4212,10 +3699,10 @@@ DEFUN (no_set_aggregator_as
    struct in_addr address;
    char *argstr;
  
 -  if (argv == 0)
 -    return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
 -  
 -  ret = inet_aton (argv[1], &address);
 +  if (argc <= idx_asn)
 +    return generic_set_delete (vty, vty->index, "aggregator as", NULL);
-   
++
 +  ret = inet_aton (argv[idx_ip]->arg, &address);
    if (ret == 0)
      {
        vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
    return ret;
  }
  
 -ALIAS (no_set_aggregator_as,
 -       no_set_aggregator_as_val_cmd,
 -       "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
 -       NO_STR
 -       SET_STR
 -       "BGP aggregator attribute\n"
 -       "AS number of aggregator\n"
 -       "AS number\n"
 -       "IP address of aggregator\n")
 -
 -DEFUN (set_tag,
 -       set_tag_cmd,
 -       "set tag <1-4294967295>",
 -       SET_STR
 -       "Tag value for routing protocol\n"
 -       "Tag value\n")
 -{
 -  return bgp_route_set_add (vty, vty->index, "tag", argv[0]);
 -}
 -
 -DEFUN (no_set_tag,
 -       no_set_tag_cmd,
 -       "no set tag",
 -       NO_STR
 -       SET_STR
 -       "Tag value for routing protocol\n")
 -{
 -  if (argc == 0)
 -      bgp_route_set_delete(vty, vty->index, "tag", NULL);
 -
 -  return bgp_route_set_delete (vty, vty->index, "tag", argv[0]);
 -}
 -
 -ALIAS (no_set_tag,
 -       no_set_tag_val_cmd,
 -       "no set tag <1-4294967295>",
 -       NO_STR
 -       SET_STR
 -       "Tag value for routing protocol\n"
 -       "Tag value\n")
 -
--
  #ifdef HAVE_IPV6
 -DEFUN (match_ipv6_address, 
 -       match_ipv6_address_cmd,
 -       "match ipv6 address WORD",
 -       MATCH_STR
 -       IPV6_STR
 -       "Match IPv6 address of route\n"
 -       "IPv6 access-list name\n")
 -{
 -  return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0],
 -                            RMAP_EVENT_FILTER_ADDED);
 -}
 -
 -DEFUN (no_match_ipv6_address, 
 -       no_match_ipv6_address_cmd,
 -       "no match ipv6 address WORD",
 -       NO_STR
 -       MATCH_STR
 -       IPV6_STR
 -       "Match IPv6 address of route\n"
 -       "IPv6 access-list name\n")
 -{
 -  return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0],
 -                               RMAP_EVENT_FILTER_DELETED);
 -}
 -
 -DEFUN (match_ipv6_next_hop, 
 +DEFUN (match_ipv6_next_hop,
         match_ipv6_next_hop_cmd,
         "match ipv6 next-hop X:X::X:X",
         MATCH_STR
diff --cc bgpd/bgp_vty.c
index b5e2d9e36fa7ea52d75221961edd89a1a221604a,258a709837e12eeaa089515a205f847288e8567e..0f8d0c76ddea34ebc0e3e9319f7c65e7b8638320
@@@ -695,16 -696,15 +695,16 @@@ DEFUN (router_bgp
    // "router bgp X"
    else
      {
 -      VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
 +      VTY_GET_INTEGER_RANGE ("AS", as, argv[idx_asn]->arg, 1, BGP_AS4_MAX);
  
        inst_type = BGP_INSTANCE_TYPE_DEFAULT;
 -      if (argc == 3)
 +      if (argc > 3)
          {
 -          name = argv[2];
 -          if (!strcmp(argv[1], "vrf")) 
 +          name = argv[idx_vrf]->arg;
 +
-           if (!strcmp(argv[idx_view_vrf]->text, "vrf")) 
++          if (!strcmp(argv[idx_view_vrf]->text, "vrf"))
              inst_type = BGP_INSTANCE_TYPE_VRF;
-           else if (!strcmp(argv[idx_view_vrf]->text, "view")) 
 -          else if (!strcmp(argv[1], "view")) 
++          else if (!strcmp(argv[idx_view_vrf]->text, "view"))
              inst_type = BGP_INSTANCE_TYPE_VIEW;
          }
  
@@@ -1997,12 -2144,11 +1997,12 @@@ DEFUN (bgp_bestpath_med
         "Compare MED among confederation paths\n"
         "Treat missing MED as the least preferred one\n")
  {
 +  int idx_med_knob = 3;
    struct bgp *bgp;
--  
++
    bgp = vty->index;
  
 -  if (strncmp (argv[0], "confed", 1) == 0)
 +  if (strncmp (argv[idx_med_knob]->arg, "confed", 1) == 0)
      bgp_flag_set (bgp, BGP_FLAG_MED_CONFED);
    else
      bgp_flag_set (bgp, BGP_FLAG_MED_MISSING_AS_WORST);
@@@ -2019,12 -2165,10 +2019,12 @@@ DEFUN (bgp_bestpath_med2
         "Change the default bestpath selection\n"
         "MED attribute\n"
         "Compare MED among confederation paths\n"
 -       "Treat missing MED as the least preferred one\n")
 +       "Treat missing MED as the least preferred one\n"
 +       "Treat missing MED as the least preferred one\n"
 +       "Compare MED among confederation paths\n")
  {
    struct bgp *bgp;
--  
++
    bgp = vty->index;
    bgp_flag_set (bgp, BGP_FLAG_MED_CONFED);
    bgp_flag_set (bgp, BGP_FLAG_MED_MISSING_AS_WORST);
@@@ -2048,8 -2199,8 +2048,8 @@@ DEFUN (no_bgp_bestpath_med
    struct bgp *bgp;
  
    bgp = vty->index;
--  
 -  if (strncmp (argv[0], "confed", 1) == 0)
++
 +  if (strncmp (argv[idx_med_knob]->arg, "confed", 1) == 0)
      bgp_flag_unset (bgp, BGP_FLAG_MED_CONFED);
    else
      bgp_flag_unset (bgp, BGP_FLAG_MED_MISSING_AS_WORST);
@@@ -2070,7 -2221,7 +2070,7 @@@ DEFUN (no_bgp_bestpath_med2
         "Treat missing MED as the least preferred one\n")
  {
    struct bgp *bgp;
--  
++
    bgp = vty->index;
    bgp_flag_unset (bgp, BGP_FLAG_MED_CONFED);
    bgp_flag_unset (bgp, BGP_FLAG_MED_MISSING_AS_WORST);
@@@ -2571,7 -2746,7 +2571,7 @@@ DEFUN (no_bgp_disable_connected_route_c
  
  
  static int
--peer_remote_as_vty (struct vty *vty, const char *peer_str, 
++peer_remote_as_vty (struct vty *vty, const char *peer_str,
                      const char *as_str, afi_t afi, safi_t safi)
  {
    int ret;
@@@ -3318,7 -3559,7 +3318,7 @@@ DEFUN (no_neighbor_set_peer_group
  }
  
  static int
--peer_flag_modify_vty (struct vty *vty, const char *ip_str, 
++peer_flag_modify_vty (struct vty *vty, const char *ip_str,
                        u_int16_t flag, int set)
  {
    int ret;
@@@ -4098,10 -4288,39 +4098,10 @@@ DEFUN (neighbor_attr_unchanged4
                               bgp_node_safi (vty), flags);
  }
  
 -ALIAS (neighbor_attr_unchanged,
 -       neighbor_attr_unchanged5_cmd,
 -       NEIGHBOR_CMD2 "attribute-unchanged as-path next-hop med",
 -       NEIGHBOR_STR
 -       NEIGHBOR_ADDR_STR2
 -       "BGP attribute is propagated unchanged to this neighbor\n"
 -       "As-path attribute\n"
 -       "Nexthop attribute\n"
 -       "Med attribute\n")
 -
 -ALIAS (neighbor_attr_unchanged,
 -       neighbor_attr_unchanged6_cmd,
 -       NEIGHBOR_CMD2 "attribute-unchanged as-path med next-hop",
 -       NEIGHBOR_STR
 -       NEIGHBOR_ADDR_STR2
 -       "BGP attribute is propagated unchanged to this neighbor\n"
 -       "As-path attribute\n"
 -       "Med attribute\n"
 -       "Nexthop attribute\n")
 -
 -ALIAS (neighbor_attr_unchanged,
 -       neighbor_attr_unchanged7_cmd,
 -       NEIGHBOR_CMD2 "attribute-unchanged next-hop med as-path",
 -       NEIGHBOR_STR
 -       NEIGHBOR_ADDR_STR2
 -       "BGP attribute is propagated unchanged to this neighbor\n"
 -       "Nexthop attribute\n"
 -       "Med attribute\n"
 -       "As-path attribute\n")
 -
 -ALIAS (neighbor_attr_unchanged,
 -       neighbor_attr_unchanged8_cmd,
 -       NEIGHBOR_CMD2 "attribute-unchanged next-hop as-path med",
 +DEFUN (no_neighbor_attr_unchanged,
 +       no_neighbor_attr_unchanged_cmd,
 +       "no neighbor <A.B.C.D|X:X::X:X|WORD> attribute-unchanged [as-path] [next-hop] [med]",
-        NO_STR  
++       NO_STR
         NEIGHBOR_STR
         NEIGHBOR_ADDR_STR2
         "BGP attribute is propagated unchanged to this neighbor\n"
@@@ -4223,7 -4511,17 +4223,7 @@@ DEFUN (no_neighbor_attr_unchanged4
  
  /* EBGP multihop configuration. */
  static int
--peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str, 
++peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str,
                              const char *ttl_str)
  {
    struct peer *peer;
  }
  
  static int
--peer_ebgp_multihop_unset_vty (struct vty *vty, const char *ip_str) 
++peer_ebgp_multihop_unset_vty (struct vty *vty, const char *ip_str)
  {
    struct peer *peer;
  
@@@ -4371,7 -4684,15 +4371,7 @@@ DEFUN (no_neighbor_description
  
  /* Neighbor update-source. */
  static int
--peer_update_source_vty (struct vty *vty, const char *peer_str, 
++peer_update_source_vty (struct vty *vty, const char *peer_str,
                          const char *source_str)
  {
    struct peer *peer;
@@@ -4431,8 -4752,8 +4431,8 @@@ DEFUN (no_neighbor_update_source
  }
  
  static int
--peer_default_originate_set_vty (struct vty *vty, const char *peer_str, 
--                                afi_t afi, safi_t safi, 
++peer_default_originate_set_vty (struct vty *vty, const char *peer_str,
++                                afi_t afi, safi_t safi,
                                  const char *rmap, int set)
  {
    int ret;
@@@ -4496,7 -4811,16 +4496,7 @@@ DEFUN (no_neighbor_default_originate
  
  /* Set neighbor's BGP port.  */
  static int
--peer_port_vty (struct vty *vty, const char *ip_str, int afi, 
++peer_port_vty (struct vty *vty, const char *ip_str, int afi,
                 const char *port_str)
  {
    struct peer *peer;
      return CMD_WARNING;
  
    if (! port_str)
--    { 
++    {
        sp = getservbyname ("bgp", "tcp");
        port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs (sp->s_port);
      }
@@@ -4552,7 -4872,16 +4552,8 @@@ DEFUN (no_neighbor_port
  
  /* neighbor weight. */
  static int
--peer_weight_set_vty (struct vty *vty, const char *ip_str, 
++peer_weight_set_vty (struct vty *vty, const char *ip_str,
+                      afi_t afi, safi_t safi,
                       const char *weight_str)
  {
    int ret;
@@@ -4591,9 -4921,7 +4593,13 @@@ DEFUN (neighbor_weight
         "Set default weight for routes from this neighbor\n"
         "default weight\n")
  {
 -  return peer_weight_set_vty (vty, argv[0], bgp_node_afi (vty), bgp_node_safi (vty), argv[1]);
 +  int idx_peer = 1;
 +  int idx_number = 3;
-   return peer_weight_set_vty (vty, argv[idx_peer]->arg, argv[idx_number]->arg);
++  return peer_weight_set_vty (vty,
++                              argv[idx_peer]->arg,
++                              bgp_node_afi (vty),
++                              bgp_node_safi (vty),
++                              argv[idx_number]->arg);
  }
  
  DEFUN (no_neighbor_weight,
         NO_STR
         NEIGHBOR_STR
         NEIGHBOR_ADDR_STR2
 -       "Set default weight for routes from this neighbor\n")
 +       "Set default weight for routes from this neighbor\n"
 +       "default weight\n")
  {
 -  return peer_weight_unset_vty (vty, argv[0], bgp_node_afi (vty), bgp_node_safi (vty));
 +  int idx_peer = 2;
-   return peer_weight_unset_vty (vty, argv[idx_peer]->arg);
++  return peer_weight_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty), bgp_node_safi (vty));
  }
  
 -ALIAS (no_neighbor_weight,
 -       no_neighbor_weight_val_cmd,
 -       NO_NEIGHBOR_CMD2 "weight <0-65535>",
 -       NO_STR
 -       NEIGHBOR_STR
 -       NEIGHBOR_ADDR_STR2
 -       "Set default weight for routes from this neighbor\n"
 -       "default weight\n")
  
  /* Override capability negotiation. */
  DEFUN (neighbor_override_capability,
@@@ -4658,7 -4988,7 +4664,7 @@@ DEFUN (no_neighbor_strict_capability
  }
  
  static int
--peer_timers_set_vty (struct vty *vty, const char *ip_str, 
++peer_timers_set_vty (struct vty *vty, const char *ip_str,
                       const char *keep_str, const char *hold_str)
  {
    int ret;
@@@ -4717,14 -5055,9 +4723,14 @@@ DEFUN (no_neighbor_timers
         "BGP per neighbor timers\n"
         "Keepalive interval\n"
         "Holdtime\n")
 +{
 +  int idx_peer = 2;
 +  return peer_timers_unset_vty (vty, argv[idx_peer]->arg);
 +}
 +
  
  static int
--peer_timers_connect_set_vty (struct vty *vty, const char *ip_str, 
++peer_timers_connect_set_vty (struct vty *vty, const char *ip_str,
                               const char *time_str)
  {
    int ret;
@@@ -4778,17 -5109,24 +4784,17 @@@ DEFUN (no_neighbor_timers_connect
         NEIGHBOR_STR
         NEIGHBOR_ADDR_STR2
         "BGP per neighbor timers\n"
 -       "BGP connect timer\n")
 +       "BGP connect timer\n"
 +       "Connect timer\n")
  {
 -  return peer_timers_connect_unset_vty (vty, argv[0]);
 +  int idx_peer = 2;
 +  return peer_timers_connect_unset_vty (vty, argv[idx_peer]->arg);
  }
  
 -ALIAS (no_neighbor_timers_connect,
 -       no_neighbor_timers_connect_val_cmd,
 -       NO_NEIGHBOR_CMD2 "timers connect <1-65535>",
 -       NO_STR
 -       NEIGHBOR_STR
 -       NEIGHBOR_ADDR_STR2
 -       "BGP per neighbor timers\n"
 -       "BGP connect timer\n"
 -       "Connect timer\n")
  
  static int
--peer_advertise_interval_vty (struct vty *vty, const char *ip_str, 
--                             const char *time_str, int set)  
++peer_advertise_interval_vty (struct vty *vty, const char *ip_str,
++                             const char *time_str, int set)
  {
    int ret;
    struct peer *peer;
@@@ -4928,7 -5275,7 +4934,7 @@@ DEFUN (no_neighbor_interface
  
  /* Set distribute list to the peer. */
  static int
--peer_distribute_set_vty (struct vty *vty, const char *ip_str, 
++peer_distribute_set_vty (struct vty *vty, const char *ip_str,
                           afi_t afi, safi_t safi,
                         const char *name_str, const char *direct_str)
  {
@@@ -5015,7 -5357,7 +5021,7 @@@ DEFUN (no_neighbor_distribute_list
  /* Set prefix list to the peer. */
  static int
  peer_prefix_list_set_vty (struct vty *vty, const char *ip_str, afi_t afi,
--                        safi_t safi, const char *name_str, 
++                        safi_t safi, const char *name_str,
                            const char *direct_str)
  {
    int ret;
@@@ -5048,7 -5390,7 +5054,7 @@@ peer_prefix_list_unset_vty (struct vty 
    peer = peer_and_group_lookup_vty (vty, ip_str);
    if (! peer)
      return CMD_WARNING;
--  
++
    /* Check filter direction. */
    if (strncmp (direct_str, "i", 1) == 0)
      direct = FILTER_IN;
@@@ -5095,7 -5432,7 +5101,7 @@@ DEFUN (no_neighbor_prefix_list
  }
  
  static int
--peer_aslist_set_vty (struct vty *vty, const char *ip_str, 
++peer_aslist_set_vty (struct vty *vty, const char *ip_str,
                       afi_t afi, safi_t safi,
                     const char *name_str, const char *direct_str)
  {
  }
  
  static int
--peer_aslist_unset_vty (struct vty *vty, const char *ip_str, 
++peer_aslist_unset_vty (struct vty *vty, const char *ip_str,
                         afi_t afi, safi_t safi,
                       const char *direct_str)
  {
@@@ -5178,7 -5510,7 +5184,7 @@@ DEFUN (no_neighbor_filter_list
  
  /* Set route-map to the peer. */
  static int
--peer_route_map_set_vty (struct vty *vty, const char *ip_str, 
++peer_route_map_set_vty (struct vty *vty, const char *ip_str,
                          afi_t afi, safi_t safi,
                        const char *name_str, const char *direct_str)
  {
@@@ -5322,7 -5646,7 +5328,7 @@@ DEFUN (no_neighbor_unsuppress_map
  
  static int
  peer_maximum_prefix_set_vty (struct vty *vty, const char *ip_str, afi_t afi,
--                           safi_t safi, const char *num_str,  
++                           safi_t safi, const char *num_str,
                             const char *threshold_str, int warning,
                             const char *restart_str)
  {
@@@ -5478,30 -5785,83 +5484,30 @@@ DEFUN (no_neighbor_maximum_prefix
         NO_STR
         NEIGHBOR_STR
         NEIGHBOR_ADDR_STR2
 -       "Maximum number of prefix accept from this peer\n")
 +       "Maximum number of prefix accept from this peer\n"
 +       "maximum no. of prefix limit\n"
 +       "Threshold value (%) at which to generate a warning msg\n"
 +       "Restart bgp connection after limit is exceeded\n"
 +       "Restart interval in minutes"
 +       "Only give warning message when limit is exceeded\n")
  {
 -  return peer_maximum_prefix_unset_vty (vty, argv[0], bgp_node_afi (vty),
 +  int idx_peer = 2;
 +  return peer_maximum_prefix_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
                                        bgp_node_safi (vty));
  }
-- 
 -ALIAS (no_neighbor_maximum_prefix,
 -       no_neighbor_maximum_prefix_val_cmd,
 -       NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295>",
 -       NO_STR
++
 +
 +/* "neighbor allowas-in" */
 +DEFUN (neighbor_allowas_in,
 +       neighbor_allowas_in_cmd,
 +       "neighbor <A.B.C.D|X:X::X:X|WORD> allowas-in [(1-10)]",
         NEIGHBOR_STR
         NEIGHBOR_ADDR_STR2
 -       "Maximum number of prefix accept from this peer\n"
 -       "maximum no. of prefix limit\n")
 -
 -ALIAS (no_neighbor_maximum_prefix,
 -       no_neighbor_maximum_prefix_threshold_cmd,
 -       NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100>",
 -       NO_STR
 -       NEIGHBOR_STR
 -       NEIGHBOR_ADDR_STR2
 -       "Maximum number of prefix accept from this peer\n"
 -       "maximum no. of prefix limit\n"
 -       "Threshold value (%) at which to generate a warning msg\n")
 -
 -ALIAS (no_neighbor_maximum_prefix,
 -       no_neighbor_maximum_prefix_warning_cmd,
 -       NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> warning-only",
 -       NO_STR
 -       NEIGHBOR_STR
 -       NEIGHBOR_ADDR_STR2
 -       "Maximum number of prefix accept from this peer\n"
 -       "maximum no. of prefix limit\n"
 -       "Only give warning message when limit is exceeded\n")
 -
 -ALIAS (no_neighbor_maximum_prefix,
 -       no_neighbor_maximum_prefix_threshold_warning_cmd,
 -       NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100> warning-only",
 -       NO_STR
 -       NEIGHBOR_STR
 -       NEIGHBOR_ADDR_STR2
 -       "Maximum number of prefix accept from this peer\n"
 -       "maximum no. of prefix limit\n"
 -       "Threshold value (%) at which to generate a warning msg\n"
 -       "Only give warning message when limit is exceeded\n")
 -
 -ALIAS (no_neighbor_maximum_prefix,
 -       no_neighbor_maximum_prefix_restart_cmd,
 -       NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> restart <1-65535>",
 -       NO_STR
 -       NEIGHBOR_STR
 -       NEIGHBOR_ADDR_STR2
 -       "Maximum number of prefix accept from this peer\n"
 -       "maximum no. of prefix limit\n"
 -       "Restart bgp connection after limit is exceeded\n"
 -       "Restart interval in minutes")
 -
 -ALIAS (no_neighbor_maximum_prefix,
 -       no_neighbor_maximum_prefix_threshold_restart_cmd,
 -       NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100> restart <1-65535>",
 -       NO_STR
 -       NEIGHBOR_STR
 -       NEIGHBOR_ADDR_STR2
 -       "Maximum number of prefix accept from this peer\n"
 -       "maximum no. of prefix limit\n"
 -       "Threshold value (%) at which to generate a warning msg\n"
 -       "Restart bgp connection after limit is exceeded\n"
 -       "Restart interval in minutes")
 -
 -/* "neighbor allowas-in" */
 -DEFUN (neighbor_allowas_in,
 -       neighbor_allowas_in_cmd,
 -       NEIGHBOR_CMD2 "allowas-in",
 -       NEIGHBOR_STR
 -       NEIGHBOR_ADDR_STR2
 -       "Accept as-path with my AS present in it\n")
 +       "Accept as-path with my AS present in it\n"
 +       "Number of occurances of AS number\n")
  {
 +  int idx_peer = 1;
 +  int idx_number = 3;
    int ret;
    struct peer *peer;
    unsigned int allow_num;
@@@ -5556,11 -5928,11 +5562,11 @@@ DEFUN (neighbor_ttl_security
    struct peer *peer;
    int gtsm_hops;
  
 -  peer = peer_and_group_lookup_vty (vty, argv[0]);
 +  peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
    if (! peer)
      return CMD_WARNING;
--    
 -  VTY_GET_INTEGER_RANGE ("", gtsm_hops, argv[1], 1, 254);
++
 +  VTY_GET_INTEGER_RANGE ("", gtsm_hops, argv[idx_number]->arg, 1, 254);
  
    /*
     * If 'neighbor swpX', then this is for directly connected peers,
@@@ -6170,7 -10009,7 +6176,7 @@@ DEFUN (show_bgp_views
        vty_out (vty, "BGP Multiple Instance is not enabled%s", VTY_NEWLINE);
        return CMD_WARNING;
      }
--  
++
    vty_out (vty, "Defined BGP views:%s", VTY_NEWLINE);
    for (ALL_LIST_ELEMENTS_RO(inst, node, bgp))
      {
                 bgp->name ? bgp->name : "(null)",
                 bgp->as, VTY_NEWLINE);
      }
--  
++
    return CMD_SUCCESS;
  }
  
@@@ -6302,14 -10141,14 +6308,14 @@@ DEFUN (show_bgp_memory
  {
    char memstrbuf[MTYPE_MEMSTR_LEN];
    unsigned long count;
--  
++
    /* RIB related usage stats */
    count = mtype_stats_alloc (MTYPE_BGP_NODE);
    vty_out (vty, "%ld RIB nodes, using %s of memory%s", count,
             mtype_memstr (memstrbuf, sizeof (memstrbuf),
                           count * sizeof (struct bgp_node)),
             VTY_NEWLINE);
--  
++
    count = mtype_stats_alloc (MTYPE_BGP_ROUTE);
    vty_out (vty, "%ld BGP routes, using %s of memory%s", count,
             mtype_memstr (memstrbuf, sizeof (memstrbuf),
               mtype_memstr (memstrbuf, sizeof (memstrbuf),
                             count * sizeof (struct bgp_info_extra)),
               VTY_NEWLINE);
--  
++
    if ((count = mtype_stats_alloc (MTYPE_BGP_STATIC)))
      vty_out (vty, "%ld Static routes, using %s of memory%s", count,
               mtype_memstr (memstrbuf, sizeof (memstrbuf),
               mtype_memstr (memstrbuf, sizeof (memstrbuf),
                           count * sizeof (struct bpacket)),
               VTY_NEWLINE);
--  
++
    /* Adj-In/Out */
    if ((count = mtype_stats_alloc (MTYPE_BGP_ADJ_IN)))
      vty_out (vty, "%ld Adj-In entries, using %s of memory%s", count,
               mtype_memstr (memstrbuf, sizeof (memstrbuf),
                             count * sizeof (struct bgp_adj_out)),
               VTY_NEWLINE);
--  
++
    if ((count = mtype_stats_alloc (MTYPE_BGP_NEXTHOP_CACHE)))
      vty_out (vty, "%ld Nexthop cache entries, using %s of memory%s", count,
               mtype_memstr (memstrbuf, sizeof (memstrbuf),
  
    /* Attributes */
    count = attr_count();
--  vty_out (vty, "%ld BGP attributes, using %s of memory%s", count, 
--           mtype_memstr (memstrbuf, sizeof (memstrbuf), 
--                         count * sizeof(struct attr)), 
++  vty_out (vty, "%ld BGP attributes, using %s of memory%s", count,
++           mtype_memstr (memstrbuf, sizeof (memstrbuf),
++                         count * sizeof(struct attr)),
             VTY_NEWLINE);
    if ((count = mtype_stats_alloc (MTYPE_ATTR_EXTRA)))
--    vty_out (vty, "%ld BGP extra attributes, using %s of memory%s", count, 
--             mtype_memstr (memstrbuf, sizeof (memstrbuf), 
--                           count * sizeof(struct attr_extra)), 
++    vty_out (vty, "%ld BGP extra attributes, using %s of memory%s", count,
++             mtype_memstr (memstrbuf, sizeof (memstrbuf),
++                           count * sizeof(struct attr_extra)),
               VTY_NEWLINE);
--  
++
    if ((count = attr_unknown_count()))
      vty_out (vty, "%ld unknown attributes%s", count, VTY_NEWLINE);
--  
++
    /* AS_PATH attributes */
    count = aspath_count ();
    vty_out (vty, "%ld BGP AS-PATH entries, using %s of memory%s", count,
             mtype_memstr (memstrbuf, sizeof (memstrbuf),
                           count * sizeof (struct aspath)),
             VTY_NEWLINE);
--  
++
    count = mtype_stats_alloc (MTYPE_AS_SEG);
    vty_out (vty, "%ld BGP AS-PATH segments, using %s of memory%s", count,
             mtype_memstr (memstrbuf, sizeof (memstrbuf),
                           count * sizeof (struct assegment)),
             VTY_NEWLINE);
--  
++
    /* Other attributes */
    if ((count = community_count ()))
      vty_out (vty, "%ld BGP community entries, using %s of memory%s", count,
               mtype_memstr (memstrbuf, sizeof (memstrbuf),
                           count * sizeof (struct ecommunity)),
               VTY_NEWLINE);
--  
++
    if ((count = mtype_stats_alloc (MTYPE_CLUSTER)))
      vty_out (vty, "%ld Cluster lists, using %s of memory%s", count,
               mtype_memstr (memstrbuf, sizeof (memstrbuf),
                           count * sizeof (struct cluster_list)),
               VTY_NEWLINE);
--  
++
    /* Peer related usage */
    count = mtype_stats_alloc (MTYPE_BGP_PEER);
    vty_out (vty, "%ld peers, using %s of memory%s", count,
             mtype_memstr (memstrbuf, sizeof (memstrbuf),
                           count * sizeof (struct peer)),
             VTY_NEWLINE);
--  
++
    if ((count = mtype_stats_alloc (MTYPE_PEER_GROUP)))
      vty_out (vty, "%ld peer groups, using %s of memory%s", count,
               mtype_memstr (memstrbuf, sizeof (memstrbuf),
                             count * sizeof (struct peer_group)),
               VTY_NEWLINE);
--  
++
    /* Other */
    if ((count = mtype_stats_alloc (MTYPE_HASH)))
      vty_out (vty, "%ld hash tables, using %s of memory%s", count,
@@@ -6614,7 -10453,7 +6620,7 @@@ bgp_show_summary (struct vty *vty, stru
                    vty_out (vty, "%s%s", header, VTY_NEWLINE);
                  }
              }
--          
++
            count++;
  
            if (use_json)
@@@ -7633,7 -11729,7 +7641,7 @@@ bgp_show_peer (struct vty *vty, struct 
        if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION)
            && bgp_confederation_peers_check (bgp, p->as))
          vty_out (vty, "  Neighbor under common administration%s", VTY_NEWLINE);
--  
++
        /* Status. */
        vty_out (vty, "  BGP state = %s", LOOKUP (bgp_status_msg, p->status));
  
          }
      }
    /* Capability. */
--  if (p->status == Established) 
++  if (p->status == Established)
      {
        if (p->cap
          || p->afc_adv[AFI_IP][SAFI_UNICAST]
                              }
                          }
                      if (! restart_af_count)
 -                          json_object_string_add(json_cap, "addressFamiliesByPeer", "none");
+                         {
 +                      json_object_string_add(json_cap, "addressFamiliesByPeer", "none");
+                           json_object_free(json_restart);
+                         }
                        else
                          json_object_object_add(json_cap, "addressFamiliesByPeer", json_restart);
                      }
            if (p->t_gr_restart)
              vty_out (vty, "    The remaining time of restart timer is %ld%s",
                       thread_timer_remain_second (p->t_gr_restart), VTY_NEWLINE);
--      
++
            if (p->t_gr_stale)
              vty_out (vty, "    The remaining time of stalepath timer is %ld%s",
                       thread_timer_remain_second (p->t_gr_stale), VTY_NEWLINE);
                 ntohs (p->su_local->sin.sin_port),
                 VTY_NEWLINE);
      }
--      
++
    /* Remote address. */
    if (p->su_remote)
      {
@@@ -8647,71 -12793,93 +8652,71 @@@ bgp_show_all_instances_neighbors_vty (s
      vty_out (vty, "}%s", VTY_NEWLINE);
  }
  
 -/* "show ip bgp neighbors" commands.  */
 -DEFUN (show_ip_bgp_neighbors,
 -       show_ip_bgp_neighbors_cmd,
 -       "show ip bgp neighbors {json}",
 -       SHOW_STR
 -       IP_STR
 -       BGP_STR
 -       "Detailed information on TCP and BGP neighbor connections\n"
 -       "JavaScript Object Notation\n")
 +static int
 +bgp_show_neighbor_vty (struct vty *vty, const char *name,
 +                       enum show_type type, const char *ip_str, u_char use_json)
  {
 -  u_char uj = use_json(argc, argv);
 -
 -  return bgp_show_neighbor_vty (vty, NULL, show_all, NULL, uj, NULL);
 -}
 -
 -ALIAS (show_ip_bgp_neighbors,
 -       show_ip_bgp_ipv4_neighbors_cmd,
 -       "show ip bgp ipv4 (unicast|multicast) neighbors {json}",
 -       SHOW_STR
 -       IP_STR
 -       BGP_STR
 -       "Address family\n"
 -       "Address Family modifier\n"
 -       "Address Family modifier\n"
 -       "Detailed information on TCP and BGP neighbor connections\n"
 -       "JavaScript Object Notation\n")
 -
 -ALIAS (show_ip_bgp_neighbors,
 -       show_ip_bgp_vpnv4_all_neighbors_cmd,
 -       "show ip bgp vpnv4 all neighbors {json}",
 -       SHOW_STR
 -       IP_STR
 -       BGP_STR
 -       "Display VPNv4 NLRI specific information\n"
 -       "Display information about all VPNv4 NLRIs\n"
 -       "Detailed information on TCP and BGP neighbor connections\n"
 -       "JavaScript Object Notation\n")
 +  int ret;
 +  struct bgp *bgp;
 +  union sockunion su;
 +  json_object *json = NULL;
  
 -ALIAS (show_ip_bgp_neighbors,
 -       show_ip_bgp_vpnv4_rd_neighbors_cmd,
 -       "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors {json}",
 -       SHOW_STR
 -       IP_STR
 -       BGP_STR
 -       "Display VPNv4 NLRI specific information\n"
 -       "Display information for a route distinguisher\n"
 -       "VPN Route Distinguisher\n"
 -       "Detailed information on TCP and BGP neighbor connections\n"
 -       "JavaScript Object Notation\n")
 +  if (use_json)
 +    json = json_object_new_object();
  
 -ALIAS (show_ip_bgp_neighbors,
 -       show_bgp_neighbors_cmd,
 -       "show bgp neighbors {json}",
 -       SHOW_STR
 -       BGP_STR
 -       "Detailed information on TCP and BGP neighbor connections\n"
 -       "JavaScript Object Notation\n")
 +  if (name)
 +    {
 +      if (strmatch(name, "all"))
 +        {
 +          bgp_show_all_instances_neighbors_vty (vty, use_json);
 +          return CMD_SUCCESS;
 +        }
 +      else
 +        {
 +          bgp = bgp_lookup_by_name (name);
 +          if (! bgp)
 +            {
 +              if (use_json)
 +                {
 +                  json_object_boolean_true_add(json, "bgpNoSuchInstance");
-                   vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
++                  vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
 +                  json_object_free(json);
 +                }
 +              else
 +                vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE);
  
 -ALIAS (show_ip_bgp_neighbors,
 -       show_bgp_ipv6_neighbors_cmd,
 -       "show bgp ipv6 neighbors {json}",
 -       SHOW_STR
 -       BGP_STR
 -       "Address family\n"
 -       "Detailed information on TCP and BGP neighbor connections\n"
 -       "JavaScript Object Notation\n")
 +              return CMD_WARNING;
 +            }
 +          }
 +    }
 +  else
 +    {
 +      bgp = bgp_get_default ();
 +    }
  
 -DEFUN (show_ip_bgp_neighbors_peer,
 -       show_ip_bgp_neighbors_peer_cmd,
 -       "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) {json}",
 -       SHOW_STR
 -       IP_STR
 -       BGP_STR
 -       "Detailed information on TCP and BGP neighbor connections\n"
 -       "Neighbor to display information about\n"
 -       "Neighbor to display information about\n"
 -       "Neighbor on bgp configured interface\n"
 -       "JavaScript Object Notation\n")
 -{
 -  u_char uj = use_json(argc, argv);
 +  if (bgp)
 +    {
 +      if (ip_str)
 +        {
 +          ret = str2sockunion (ip_str, &su);
 +          if (ret < 0)
 +            bgp_show_neighbor (vty, bgp, type, NULL, ip_str, use_json, json);
 +          else
 +            bgp_show_neighbor (vty, bgp, type, &su, NULL, use_json, json);
 +        }
 +      else
 +        {
 +          bgp_show_neighbor (vty, bgp, type, NULL, NULL, use_json, json);
 +        }
 +    }
  
 -  return bgp_show_neighbor_vty (vty, NULL, show_peer, argv[argc - 2], uj, NULL);
 +  return CMD_SUCCESS;
  }
  
 -ALIAS (show_ip_bgp_neighbors_peer,
 -       show_ip_bgp_ipv4_neighbors_peer_cmd,
 -       "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) {json}",
 +/* "show ip bgp neighbors" commands.  */
 +DEFUN (show_ip_bgp_neighbors,
 +       show_ip_bgp_neighbors_cmd,
 +       "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]",
         SHOW_STR
         IP_STR
         BGP_STR
@@@ -8817,7 -13088,7 +8822,7 @@@ DEFUN (show_ip_bgp_community_info
  {
    vty_out (vty, "Address Refcnt Community%s", VTY_NEWLINE);
  
--  hash_iterate (community_hash (), 
++  hash_iterate (community_hash (),
                (void (*) (struct hash_backet *, void *))
                community_show_all_iterator,
                vty);
@@@ -10062,7 -14478,7 +10067,7 @@@ bgp_vty_init (void
    install_default (BGP_VPNV6_NODE);
    install_default (BGP_ENCAP_NODE);
    install_default (BGP_ENCAPV6_NODE);
--  
++
    /* "bgp multiple-instance" commands. */
    install_element (CONFIG_NODE, &bgp_multiple_instance_cmd);
    install_element (CONFIG_NODE, &no_bgp_multiple_instance_cmd);
    /* "bgp always-compare-med" commands */
    install_element (BGP_NODE, &bgp_always_compare_med_cmd);
    install_element (BGP_NODE, &no_bgp_always_compare_med_cmd);
--  
++
    /* "bgp deterministic-med" commands */
    install_element (BGP_NODE, &bgp_deterministic_med_cmd);
    install_element (BGP_NODE, &no_bgp_deterministic_med_cmd);
    install_element (BGP_NODE, &no_bgp_graceful_restart_cmd);
    install_element (BGP_NODE, &bgp_graceful_restart_stalepath_time_cmd);
    install_element (BGP_NODE, &no_bgp_graceful_restart_stalepath_time_cmd);
 -  install_element (BGP_NODE, &no_bgp_graceful_restart_stalepath_time_val_cmd);
    install_element (BGP_NODE, &bgp_graceful_restart_restart_time_cmd);
    install_element (BGP_NODE, &no_bgp_graceful_restart_restart_time_cmd);
 -  install_element (BGP_NODE, &no_bgp_graceful_restart_restart_time_val_cmd);
-- 
++
    /* "bgp fast-external-failover" commands */
    install_element (BGP_NODE, &bgp_fast_external_failover_cmd);
    install_element (BGP_NODE, &no_bgp_fast_external_failover_cmd);
    /* "no bgp default ipv4-unicast" commands. */
    install_element (BGP_NODE, &no_bgp_default_ipv4_unicast_cmd);
    install_element (BGP_NODE, &bgp_default_ipv4_unicast_cmd);
--  
++
    /* "bgp network import-check" commands. */
    install_element (BGP_NODE, &bgp_network_import_check_cmd);
    install_element (BGP_NODE, &bgp_network_import_check_exact_cmd);
    install_element (BGP_VPNV6_NODE, &no_neighbor_set_peer_group_cmd);
    install_element (BGP_ENCAP_NODE, &no_neighbor_set_peer_group_cmd);
    install_element (BGP_ENCAPV6_NODE, &no_neighbor_set_peer_group_cmd);
--  
++
    /* "neighbor softreconfiguration inbound" commands.*/
    install_element (BGP_NODE, &neighbor_soft_reconfiguration_cmd);
    install_element (BGP_NODE, &no_neighbor_soft_reconfiguration_cmd);
    /* "neighbor weight" commands. */
    install_element (BGP_NODE, &neighbor_weight_cmd);
    install_element (BGP_NODE, &no_neighbor_weight_cmd);
 -  install_element (BGP_NODE, &no_neighbor_weight_val_cmd);
 +
+   install_element (BGP_IPV4_NODE, &neighbor_weight_cmd);
+   install_element (BGP_IPV4_NODE, &no_neighbor_weight_cmd);
 -  install_element (BGP_IPV4_NODE, &no_neighbor_weight_val_cmd);
+   install_element (BGP_IPV4M_NODE, &neighbor_weight_cmd);
+   install_element (BGP_IPV4M_NODE, &no_neighbor_weight_cmd);
 -  install_element (BGP_IPV4M_NODE, &no_neighbor_weight_val_cmd);
+   install_element (BGP_IPV6_NODE, &neighbor_weight_cmd);
+   install_element (BGP_IPV6_NODE, &no_neighbor_weight_cmd);
 -  install_element (BGP_IPV6_NODE, &no_neighbor_weight_val_cmd);
+   install_element (BGP_IPV6M_NODE, &neighbor_weight_cmd);
+   install_element (BGP_IPV6M_NODE, &no_neighbor_weight_cmd);
 -  install_element (BGP_IPV6M_NODE, &no_neighbor_weight_val_cmd);
+   install_element (BGP_VPNV4_NODE, &neighbor_weight_cmd);
+   install_element (BGP_VPNV4_NODE, &no_neighbor_weight_cmd);
 -  install_element (BGP_VPNV4_NODE, &no_neighbor_weight_val_cmd);
+   install_element (BGP_VPNV6_NODE, &neighbor_weight_cmd);
+   install_element (BGP_VPNV6_NODE, &no_neighbor_weight_cmd);
 -  install_element (BGP_VPNV6_NODE, &no_neighbor_weight_val_cmd);
+   install_element (BGP_ENCAP_NODE, &neighbor_weight_cmd);
+   install_element (BGP_ENCAP_NODE, &no_neighbor_weight_cmd);
 -  install_element (BGP_ENCAP_NODE, &no_neighbor_weight_val_cmd);
+   install_element (BGP_ENCAPV6_NODE, &neighbor_weight_cmd);
+   install_element (BGP_ENCAPV6_NODE, &no_neighbor_weight_cmd);
 -  install_element (BGP_ENCAPV6_NODE, &no_neighbor_weight_val_cmd);
    /* "neighbor override-capability" commands. */
    install_element (BGP_NODE, &neighbor_override_capability_cmd);
    install_element (BGP_NODE, &no_neighbor_override_capability_cmd);
    install_element (VIEW_NODE, &show_bgp_updgrps_adj_s_cmd);
    install_element (VIEW_NODE, &show_bgp_instance_updgrps_adj_s_cmd);
    install_element (VIEW_NODE, &show_bgp_updgrps_afi_adj_s_cmd);
-   install_element (RESTRICTED_NODE, &show_ip_bgp_summary_cmd);
-   install_element (RESTRICTED_NODE, &show_ip_bgp_updgrps_cmd);
-   install_element (RESTRICTED_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd);
-   install_element (RESTRICTED_NODE, &show_ip_bgp_updgrps_adj_cmd);
-   install_element (RESTRICTED_NODE, &show_ip_bgp_instance_updgrps_adj_cmd);
-   install_element (RESTRICTED_NODE, &show_bgp_updgrps_adj_cmd);
-   install_element (RESTRICTED_NODE, &show_bgp_instance_updgrps_adj_cmd);
-   install_element (RESTRICTED_NODE, &show_bgp_updgrps_afi_adj_cmd);
-   install_element (RESTRICTED_NODE, &show_ip_bgp_updgrps_adj_s_cmd);
-   install_element (RESTRICTED_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd);
-   install_element (RESTRICTED_NODE, &show_bgp_updgrps_adj_s_cmd);
-   install_element (RESTRICTED_NODE, &show_bgp_instance_updgrps_adj_s_cmd);
-   install_element (RESTRICTED_NODE, &show_bgp_updgrps_afi_adj_s_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_summary_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_updgrps_cmd);
-   install_element (ENABLE_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_updgrps_adj_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_instance_updgrps_adj_cmd);
-   install_element (ENABLE_NODE, &show_bgp_updgrps_adj_cmd);
-   install_element (ENABLE_NODE, &show_bgp_instance_updgrps_adj_cmd);
-   install_element (ENABLE_NODE, &show_bgp_updgrps_afi_adj_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_updgrps_adj_s_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd);
-   install_element (ENABLE_NODE, &show_bgp_updgrps_adj_s_cmd);
-   install_element (ENABLE_NODE, &show_bgp_instance_updgrps_adj_s_cmd);
-   install_element (ENABLE_NODE, &show_bgp_updgrps_afi_adj_s_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_summary_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_all_summary_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_summary_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv4_safi_summary_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_ipv4_summary_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_ipv4_safi_summary_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_summary_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_summary_cmd);
 -#ifdef HAVE_IPV6
 -  install_element (VIEW_NODE, &show_bgp_summary_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_summary_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_all_summary_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv6_summary_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv6_safi_summary_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_ipv6_summary_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_ipv6_safi_summary_cmd);
 -#endif /* HAVE_IPV6 */
 -
 -  install_element (VIEW_NODE, &show_bgp_ipv4_vpn_summary_cmd);
 -
 -  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_summary_cmd);
++  install_element (VIEW_NODE, &show_ip_bgp_summary_cmd);
++  install_element (VIEW_NODE, &show_ip_bgp_updgrps_cmd);
++  install_element (VIEW_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd);
++  install_element (VIEW_NODE, &show_ip_bgp_updgrps_adj_cmd);
++  install_element (VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_cmd);
++  install_element (VIEW_NODE, &show_bgp_updgrps_adj_cmd);
++  install_element (VIEW_NODE, &show_bgp_instance_updgrps_adj_cmd);
++  install_element (VIEW_NODE, &show_bgp_updgrps_afi_adj_cmd);
++  install_element (VIEW_NODE, &show_ip_bgp_updgrps_adj_s_cmd);
++  install_element (VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd);
++  install_element (VIEW_NODE, &show_bgp_updgrps_adj_s_cmd);
++  install_element (VIEW_NODE, &show_bgp_instance_updgrps_adj_s_cmd);
++  install_element (VIEW_NODE, &show_bgp_updgrps_afi_adj_s_cmd);
  
    /* "show ip bgp neighbors" commands. */
    install_element (VIEW_NODE, &show_ip_bgp_neighbors_cmd);
-   install_element (ENABLE_NODE, &show_ip_bgp_neighbors_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbors_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_neighbors_peer_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbors_peer_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbors_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbors_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbors_peer_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbors_peer_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_neighbors_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_all_neighbors_cmd);
 -  install_element (VIEW_NODE, &show_ip_bgp_instance_neighbors_peer_cmd);
 -
 -#ifdef HAVE_IPV6
 -  install_element (VIEW_NODE, &show_bgp_neighbors_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv6_neighbors_cmd);
 -  install_element (VIEW_NODE, &show_bgp_neighbors_peer_cmd);
 -  install_element (VIEW_NODE, &show_bgp_ipv6_neighbors_peer_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_neighbors_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbors_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_neighbors_peer_cmd);
 -  install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbors_peer_cmd);
 -
 -  /* Old commands.  */
 -  install_element (VIEW_NODE, &show_ipv6_bgp_summary_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_mbgp_summary_cmd);
 -#endif /* HAVE_IPV6 */
  
    /* "show ip bgp peer-group" commands. */
    install_element (VIEW_NODE, &show_ip_bgp_peer_groups_cmd);
  
    /* "show bgp memory" commands. */
    install_element (VIEW_NODE, &show_bgp_memory_cmd);
-   install_element (RESTRICTED_NODE, &show_bgp_memory_cmd);
-   install_element (ENABLE_NODE, &show_bgp_memory_cmd);
--  
++
    /* "show bgp views" commands. */
    install_element (VIEW_NODE, &show_bgp_views_cmd);
-   install_element (RESTRICTED_NODE, &show_bgp_views_cmd);
-   install_element (ENABLE_NODE, &show_bgp_views_cmd);
--  
++
    /* "show bgp vrfs" commands. */
    install_element (VIEW_NODE, &show_bgp_vrfs_cmd);
-   install_element (RESTRICTED_NODE, &show_bgp_vrfs_cmd);
-   install_element (ENABLE_NODE, &show_bgp_vrfs_cmd);
--  
++
    /* Community-list. */
    community_list_vty ();
  }
@@@ -11219,7 -16209,7 +11213,7 @@@ community_list_unset_vty (struct vty *v
  
    if (argc > 1)
      {
-       // Check the list direct. 
 -      /* Check the list direct. */
++      // Check the list direct.
        if (strncmp (argv[1], "p", 1) == 0)
        direct = COMMUNITY_PERMIT;
        else if (strncmp (argv[1], "d", 1) == 0)
@@@ -11396,10 -16529,9 +11390,10 @@@ DEFUN (show_ip_community_list_arg
  }
  
  static int
- extcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv, 
 -extcommunity_list_set_vty (struct vty *vty, int argc, const char **argv, 
 -                           int style, int reject_all_digit_name)
++extcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv,
 +                           int style)
  {
 +  /* CHECK ME dwalton finish this
    int ret;
    int direct;
    char *str;
        return CMD_WARNING;
      }
  
-   // All digit name check. 
 -  /* All digit name check.  */
++  // All digit name check.
    if (reject_all_digit_name && all_digit (argv[0]))
      {
        vty_out (vty, "%% Community name cannot have all digits%s", VTY_NEWLINE);
  
    ret = extcommunity_list_set (bgp_clist, argv[0], str, direct, style);
  
-   // Free temporary community list string allocated by argv_concat(). 
 -  /* Free temporary community list string allocated by
 -     argv_concat().  */
++  // Free temporary community list string allocated by argv_concat().
    if (str)
      XFREE (MTYPE_TMP, str);
  
@@@ -11722,20 -16994,41 +11716,16 @@@ community_list_vty (void
  
    /* Community-list.  */
    install_element (CONFIG_NODE, &ip_community_list_standard_cmd);
 -  install_element (CONFIG_NODE, &ip_community_list_standard2_cmd);
 -  install_element (CONFIG_NODE, &ip_community_list_expanded_cmd);
 -  install_element (CONFIG_NODE, &ip_community_list_name_standard_cmd);
 -  install_element (CONFIG_NODE, &ip_community_list_name_standard2_cmd);
 -  install_element (CONFIG_NODE, &ip_community_list_name_expanded_cmd);
    install_element (CONFIG_NODE, &no_ip_community_list_standard_all_cmd);
 -  install_element (CONFIG_NODE, &no_ip_community_list_standard_direction_cmd);
    install_element (CONFIG_NODE, &no_ip_community_list_expanded_all_cmd);
 -  install_element (CONFIG_NODE, &no_ip_community_list_name_standard_all_cmd);
 -  install_element (CONFIG_NODE, &no_ip_community_list_name_expanded_all_cmd);
 -  install_element (CONFIG_NODE, &no_ip_community_list_standard_cmd);
 -  install_element (CONFIG_NODE, &no_ip_community_list_expanded_cmd);
 -  install_element (CONFIG_NODE, &no_ip_community_list_name_standard_cmd);
 -  install_element (CONFIG_NODE, &no_ip_community_list_name_standard_brief_cmd);
 -  install_element (CONFIG_NODE, &no_ip_community_list_name_expanded_cmd);
    install_element (VIEW_NODE, &show_ip_community_list_cmd);
    install_element (VIEW_NODE, &show_ip_community_list_arg_cmd);
-   install_element (ENABLE_NODE, &show_ip_community_list_cmd);
-   install_element (ENABLE_NODE, &show_ip_community_list_arg_cmd);
  
    /* Extcommunity-list.  */
    install_element (CONFIG_NODE, &ip_extcommunity_list_standard_cmd);
 -  install_element (CONFIG_NODE, &ip_extcommunity_list_standard2_cmd);
 -  install_element (CONFIG_NODE, &ip_extcommunity_list_expanded_cmd);
 -  install_element (CONFIG_NODE, &ip_extcommunity_list_name_standard_cmd);
 -  install_element (CONFIG_NODE, &ip_extcommunity_list_name_standard2_cmd);
    install_element (CONFIG_NODE, &ip_extcommunity_list_name_expanded_cmd);
    install_element (CONFIG_NODE, &no_ip_extcommunity_list_standard_all_cmd);
 -  install_element (CONFIG_NODE, &no_ip_extcommunity_list_standard_direction_cmd);
    install_element (CONFIG_NODE, &no_ip_extcommunity_list_expanded_all_cmd);
 -  install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_standard_all_cmd);
 -  install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_expanded_all_cmd);
 -  install_element (CONFIG_NODE, &no_ip_extcommunity_list_standard_cmd);
 -  install_element (CONFIG_NODE, &no_ip_extcommunity_list_expanded_cmd);
 -  install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_standard_cmd);
 -  install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_standard_brief_cmd);
 -  install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_expanded_cmd);
    install_element (VIEW_NODE, &show_ip_extcommunity_list_cmd);
    install_element (VIEW_NODE, &show_ip_extcommunity_list_arg_cmd);
-   install_element (ENABLE_NODE, &show_ip_extcommunity_list_cmd);
-   install_element (ENABLE_NODE, &show_ip_extcommunity_list_arg_cmd);
  }
diff --cc bgpd/bgpd.c
index 9a7b297fb37231a0319fc292837c66bbdf860e70,9ad68fbc67168484a4f23dd4a6ba47acdbabb3d5..eb8a50b267ed3761c0abfcbc4948e80782bade46
@@@ -4515,9 -4562,14 +4562,14 @@@ peer_weight_set (struct peer *peer, afi
    group = peer->group;
    for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
      {
-       peer->weight = group->conf->weight;
+       if (peer->weight[afi][safi] != weight)
+         {
+           peer->weight[afi][safi] = weight;
+           SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT);
+           peer_on_policy_change (peer, afi, safi, 0);
 -        }
++    }
      }
-   return 1;
+   return 0;
  }
  
  int
@@@ -4526,24 -4578,55 +4578,55 @@@ peer_weight_unset (struct peer *peer, a
    struct peer_group *group;
    struct listnode *node, *nnode;
  
-   /* Set default weight. */
+   /* not the peer-group itself but a peer in a peer-group */
 -  if (peer_group_active(peer))
 +  if (peer_group_active (peer))
-     peer->weight = peer->group->conf->weight;
-   else
-     peer->weight = 0;
+     {
+       group = peer->group;
  
-   UNSET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
+       /* inherit weight from the peer-group */
+       if (CHECK_FLAG (group->conf->af_flags[afi][safi], PEER_FLAG_WEIGHT))
+         {
+           peer->weight[afi][safi] = group->conf->weight[afi][safi];
+           peer_af_flag_set (peer, afi, safi, PEER_FLAG_WEIGHT);
+           peer_on_policy_change (peer, afi, safi, 0);
+         }
+       else
+         {
+           if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT))
+             {
+               peer->weight[afi][safi] = 0;
+               peer_af_flag_unset (peer, afi, safi, PEER_FLAG_WEIGHT);
+               peer_on_policy_change (peer, afi, safi, 0);
+             }
+         }
+     }
  
-   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
-     return 0;
+   else
+     {
+       if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT))
+         {
+           peer->weight[afi][safi] = 0;
+           peer_af_flag_unset (peer, afi, safi, PEER_FLAG_WEIGHT);
+           peer_on_policy_change (peer, afi, safi, 0);
+         }
  
 -      /* peer-group member updates. */
 -      group = peer->group;
 +  /* peer-group member updates. */
 +  group = peer->group;
+       if (group)
+         {
 -          for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 -            {
 +  for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 +    {
-       peer->weight = 0;
+               if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT))
+                 {
+                   peer->weight[afi][safi] = 0;
+                   peer_af_flag_unset (peer, afi, safi, PEER_FLAG_WEIGHT);
+                   peer_on_policy_change (peer, afi, safi, 0);
+                 }
+             }
 -        }
++    }
      }
-   return 1;
+   return 0;
  }
  
  int
index 0000000000000000000000000000000000000000,1978bec280d0c92966ae4425ea93e742673b44d7..e519ed48032abc7a0928fc54b5f764dd66b1a64f
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,5016 +1,5016 @@@
 -       "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255> lifetime <1-4294967295> .LNH_OPTIONS",
+ /* 
+  *
+  * Copyright 2009-2016, LabN Consulting, L.L.C.
+  *
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version 2
+  * of the License, or (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+  *
+  */
+ #include <errno.h>
+ #include "lib/zebra.h"
+ #include "lib/prefix.h"
+ #include "lib/table.h"
+ #include "lib/vty.h"
+ #include "lib/memory.h"
+ #include "lib/routemap.h"
+ #include "lib/log.h"
+ #include "lib/linklist.h"
+ #include "lib/command.h"
+ #include "bgpd/bgpd.h"
+ #include "bgpd/bgp_ecommunity.h"
+ #include "bgpd/bgp_attr.h"
+ #include "bgpd/bgp_mplsvpn.h"
+ #include "bgpd/rfapi/bgp_rfapi_cfg.h"
+ #include "bgpd/rfapi/rfapi.h"
+ #include "bgpd/rfapi/rfapi_backend.h"
+ #include "bgpd/bgp_route.h"
+ #include "bgpd/bgp_aspath.h"
+ #include "bgpd/bgp_community.h"
+ #include "bgpd/bgp_vnc_types.h"
+ #include "bgpd/rfapi/rfapi_import.h"
+ #include "bgpd/rfapi/rfapi_private.h"
+ #include "bgpd/rfapi/rfapi_monitor.h"
+ #include "bgpd/rfapi/rfapi_rib.h"
+ #include "bgpd/rfapi/rfapi_vty.h"
+ #include "bgpd/rfapi/rfapi_ap.h"
+ #include "bgpd/rfapi/rfapi_encap_tlv.h"
+ #include "bgpd/rfapi/vnc_debug.h"
+ #define DEBUG_L2_EXTRA 0
+ #define VNC_SHOW_STR "VNC information\n"
+ /* format related utilies */
+ #define FMT_MIN      60         /* seconds */
+ #define FMT_HOUR    (60  * FMT_MIN)
+ #define FMT_DAY     (24  * FMT_HOUR)
+ #define FMT_YEAR    (365 * FMT_DAY)
+ char *
+ rfapiFormatSeconds (uint32_t seconds, char *buf, size_t len)
+ {
+   int year, day, hour, min;
+   if (seconds >= FMT_YEAR)
+     {
+       year = seconds / FMT_YEAR;
+       seconds -= year * FMT_YEAR;
+     }
+   else
+     year = 0;
+   if (seconds >= FMT_DAY)
+     {
+       day = seconds / FMT_DAY;
+       seconds -= day * FMT_DAY;
+     }
+   else
+     day = 0;
+   if (seconds >= FMT_HOUR)
+     {
+       hour = seconds / FMT_HOUR;
+       seconds -= hour * FMT_HOUR;
+     }
+   else
+     hour = 0;
+   if (seconds >= FMT_MIN)
+     {
+       min = seconds / FMT_MIN;
+       seconds -= min * FMT_MIN;
+     }
+   else
+     min = 0;
+   if (year > 0)
+     {
+       snprintf (buf, len, "%dy%dd%dh", year, day, hour);
+     }
+   else if (day > 0)
+     {
+       snprintf (buf, len, "%dd%dh%dm", day, hour, min);
+     }
+   else
+     {
+       snprintf (buf, len, "%02d:%02d:%02d", hour, min, seconds);
+     }
+   return buf;
+ }
+ char *
+ rfapiFormatAge (time_t age, char *buf, size_t len)
+ {
+   time_t now, age_adjusted;
+   now = rfapi_time (NULL);
+   age_adjusted = now - age;
+   return rfapiFormatSeconds (age_adjusted, buf, len);
+ }
+ /*
+  * Reimplementation of quagga/lib/prefix.c function, but
+  * for RFAPI-style prefixes
+  */
+ void
+ rfapiRprefixApplyMask (struct rfapi_ip_prefix *rprefix)
+ {
+   uint8_t *pnt;
+   int index;
+   int offset;
+   static uint8_t maskbit[] =
+     { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
+   switch (rprefix->prefix.addr_family)
+     {
+     case AF_INET:
+       index = rprefix->length / 8;
+       if (index < 4)
+         {
+           pnt = (uint8_t *) & rprefix->prefix.addr.v4;
+           offset = rprefix->length % 8;
+           pnt[index] &= maskbit[offset];
+           index++;
+           while (index < 4)
+             pnt[index++] = 0;
+         }
+       break;
+     case AF_INET6:
+       index = rprefix->length / 8;
+       if (index < 16)
+         {
+           pnt = (uint8_t *) & rprefix->prefix.addr.v6;
+           offset = rprefix->length % 8;
+           pnt[index] &= maskbit[offset];
+           index++;
+           while (index < 16)
+             pnt[index++] = 0;
+         }
+       break;
+     default:
+       assert (0);
+     }
+ }
+ /*
+  * translate a quagga prefix into a rfapi IP address. The
+  * prefix is REQUIRED to be 32 bits for IPv4 and 128 bits for IPv6
+  *
+  * RETURNS:
+  *
+  *    0       Success
+  *    <0      Error
+  */
+ int
+ rfapiQprefix2Raddr (struct prefix *qprefix, struct rfapi_ip_addr *raddr)
+ {
+   memset (raddr, 0, sizeof (struct rfapi_ip_addr));
+   raddr->addr_family = qprefix->family;
+   switch (qprefix->family)
+     {
+     case AF_INET:
+       if (qprefix->prefixlen != 32)
+         return -1;
+       raddr->addr.v4 = qprefix->u.prefix4;
+       break;
+     case AF_INET6:
+       if (qprefix->prefixlen != 128)
+         return -1;
+       raddr->addr.v6 = qprefix->u.prefix6;
+       break;
+     default:
+       return -1;
+     }
+   return 0;
+ }
+ /* 
+  * Translate Quagga prefix to RFAPI prefix
+  */
+ /* rprefix->cost set to 0 */
+ void
+ rfapiQprefix2Rprefix (struct prefix *qprefix, struct rfapi_ip_prefix *rprefix)
+ {
+   memset (rprefix, 0, sizeof (struct rfapi_ip_prefix));
+   rprefix->length = qprefix->prefixlen;
+   rprefix->prefix.addr_family = qprefix->family;
+   switch (qprefix->family)
+     {
+     case AF_INET:
+       rprefix->prefix.addr.v4 = qprefix->u.prefix4;
+       break;
+     case AF_INET6:
+       rprefix->prefix.addr.v6 = qprefix->u.prefix6;
+       break;
+     default:
+       assert (0);
+     }
+ }
+ int
+ rfapiRprefix2Qprefix (struct rfapi_ip_prefix *rprefix, struct prefix *qprefix)
+ {
+   memset (qprefix, 0, sizeof (struct prefix));
+   qprefix->prefixlen = rprefix->length;
+   qprefix->family = rprefix->prefix.addr_family;
+   switch (rprefix->prefix.addr_family)
+     {
+     case AF_INET:
+       qprefix->u.prefix4 = rprefix->prefix.addr.v4;
+       break;
+     case AF_INET6:
+       qprefix->u.prefix6 = rprefix->prefix.addr.v6;
+       break;
+     default:
+       return EAFNOSUPPORT;
+     }
+   return 0;
+ }
+ /*
+  * returns 1 if prefixes have same addr family, prefix len, and address
+  * Note that host bits matter in this comparison!
+  *
+  * For paralellism with quagga/lib/prefix.c. if we need a comparison
+  * where host bits are ignored, call that function rfapiRprefixCmp.
+  */
+ int
+ rfapiRprefixSame (struct rfapi_ip_prefix *hp1, struct rfapi_ip_prefix *hp2)
+ {
+   if (hp1->prefix.addr_family != hp2->prefix.addr_family)
+     return 0;
+   if (hp1->length != hp2->length)
+     return 0;
+   if (hp1->prefix.addr_family == AF_INET)
+     if (IPV4_ADDR_SAME (&hp1->prefix.addr.v4, &hp2->prefix.addr.v4))
+       return 1;
+   if (hp1->prefix.addr_family == AF_INET6)
+     if (IPV6_ADDR_SAME (&hp1->prefix.addr.v6, &hp2->prefix.addr.v6))
+       return 1;
+   return 0;
+ }
+ int
+ rfapiRaddr2Qprefix (struct rfapi_ip_addr *hia, struct prefix *pfx)
+ {
+   memset (pfx, 0, sizeof (struct prefix));
+   pfx->family = hia->addr_family;
+   switch (hia->addr_family)
+     {
+     case AF_INET:
+       pfx->prefixlen = 32;
+       pfx->u.prefix4 = hia->addr.v4;
+       break;
+     case AF_INET6:
+       pfx->prefixlen = 128;
+       pfx->u.prefix6 = hia->addr.v6;
+       break;
+     default:
+       return EAFNOSUPPORT;
+     }
+   return 0;
+ }
+ void
+ rfapiL2o2Qprefix (struct rfapi_l2address_option *l2o, struct prefix *pfx)
+ {
+   memset (pfx, 0, sizeof (struct prefix));
+   pfx->family = AF_ETHERNET;
+   pfx->prefixlen = 48;
+   pfx->u.prefix_eth = l2o->macaddr;
+ }
+ char *
+ rfapiEthAddr2Str (const struct ethaddr *ea, char *buf, int bufsize)
+ {
+   int i;
+   char *p = buf;
+   assert (bufsize > (3 * ETHER_ADDR_LEN));
+   for (i = 0; i <= ETHER_ADDR_LEN; ++i)
+     {
+       sprintf (p, "%02x", ea->octet[i]);
+       if (i < (ETHER_ADDR_LEN - 1))
+         *(p + 2) = ':';
+       p += 3;
+     }
+   return buf;
+ }
+ int
+ rfapiStr2EthAddr (const char *str, struct ethaddr *ea)
+ {
+   unsigned int a[6];
+   int i;
+   if (sscanf (str, "%2x:%2x:%2x:%2x:%2x:%2x",
+               a + 0, a + 1, a + 2, a + 3, a + 4, a + 5) != 6)
+     {
+       return EINVAL;
+     }
+   for (i = 0; i < 6; ++i)
+     ea->octet[i] = a[i] & 0xff;
+   return 0;
+ }
+ const char *
+ rfapi_ntop (int af, const void *src, char *buf, socklen_t size)
+ {
+   if (af == AF_ETHERNET)
+     {
+       return rfapiEthAddr2Str ((const struct ethaddr *) src, buf, size);
+     }
+   return inet_ntop (af, src, buf, size);
+ }
+ int
+ rfapiDebugPrintf (void *dummy, const char *format, ...)
+ {
+   va_list args;
+   va_start (args, format);
+   vzlog (NULL, LOG_DEBUG, format, args);
+   va_end (args);
+   return 0;
+ }
+ static int
+ rfapiStdioPrintf (void *stream, const char *format, ...)
+ {
+   FILE *file = NULL;
+   va_list args;
+   va_start (args, format);
+   switch ((uintptr_t) stream)
+     {
+     case 1:
+       file = stdout;
+       break;
+     case 2:
+       file = stderr;
+       break;
+     default:
+       assert (0);
+     }
+   vfprintf (file, format, args);
+   va_end (args);
+   return 0;
+ }
+ /* Fake out for debug logging */
+ static struct vty vty_dummy_zlog;
+ static struct vty vty_dummy_stdio;
+ #define HVTY_NEWLINE ((vty == &vty_dummy_zlog)? "": VTY_NEWLINE)
+ static const char *
+ str_vty_newline (struct vty *vty)
+ {
+   if (vty == &vty_dummy_zlog)
+     return "";
+   return VTY_NEWLINE;
+ }
+ int
+ rfapiStream2Vty (
+   void        *stream,                                        /* input */
+   int         (**fp) (void *, const char *, ...),     /* output */
+   struct vty  **vty,                                  /* output */
+   void        **outstream,                                    /* output */
+   const char  **vty_newline)                          /* output */
+ {
+   if (!stream)
+     {
+       vty_dummy_zlog.type = VTY_SHELL;  /* for VTY_NEWLINE */
+       *vty = &vty_dummy_zlog;
+       *fp = (int (*)(void *, const char *,...)) rfapiDebugPrintf;
+       *outstream = NULL;
+       *vty_newline = str_vty_newline (*vty);
+       return (vzlog_test (NULL, LOG_DEBUG));
+     }
+   if (((uintptr_t) stream == (uintptr_t) 1) ||
+       ((uintptr_t) stream == (uintptr_t) 2))
+     {
+       vty_dummy_stdio.type = VTY_SHELL; /* for VTY_NEWLINE */
+       *vty = &vty_dummy_stdio;
+       *fp = (int (*)(void *, const char *,...)) rfapiStdioPrintf;
+       *outstream = stream;
+       *vty_newline = str_vty_newline (*vty);
+       return 1;
+     }
+   if (stream)
+     {
+       *vty = stream;            /* VTY_NEWLINE requires vty to be legit */
+       *fp = (int (*)(void *, const char *,...)) vty_out;
+       *outstream = stream;
+       *vty_newline = str_vty_newline (*vty);
+       return 1;
+     }
+   return 0;
+ }
+ /* called from bgpd/bgp_vty.c'route_vty_out() */
+ void
+ rfapi_vty_out_vncinfo (
+   struct vty          *vty,
+   struct prefix               *p,
+   struct bgp_info     *bi,
+   safi_t              safi)
+ {
+   char *s;
+   uint32_t lifetime;
+   /*
+    * Print, on an indented line:
+    *  UN address [if VPN route and VNC UN addr subtlv]
+    *  EC list
+    *  VNC lifetime
+    */
+   vty_out (vty, "    ");
+   if (safi == SAFI_MPLS_VPN)
+     {
+       struct prefix pfx_un;
+       if (!rfapiGetVncTunnelUnAddr (bi->attr, &pfx_un))
+         {
+           char buf[BUFSIZ];
+           vty_out (vty, "UN=%s", inet_ntop (pfx_un.family,
+                                             pfx_un.u.val, buf, BUFSIZ));
+         }
+     }
+   if (bi->attr && bi->attr->extra && bi->attr->extra->ecommunity)
+     {
+       s = ecommunity_ecom2str (bi->attr->extra->ecommunity,
+                                ECOMMUNITY_FORMAT_ROUTE_MAP);
+       vty_out (vty, " EC{%s}", s);
+       XFREE (MTYPE_ECOMMUNITY_STR, s);
+     }
+   if (bi->extra != NULL)
+     vty_out (vty, " label=%u", decode_label (bi->extra->tag));
+   if (rfapiGetVncLifetime (bi->attr, &lifetime))
+     {
+       if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
+         {
+           vty_out (vty, " life=none");
+         }
+     }
+   else
+     {
+       vty_out (vty, " life=%d", lifetime);
+     }
+   vty_out (vty, " type=%s, subtype=%d",
+            zebra_route_string (bi->type), bi->sub_type);
+   vty_out (vty, "%s", HVTY_NEWLINE);
+ }
+ void
+ rfapiPrintAttrPtrs (void *stream, struct attr *attr)
+ {
+   int (*fp) (void *, const char *, ...);
+   struct vty *vty;
+   void *out;
+   const char *vty_newline;
+   struct attr_extra *ae;
+   char buf[BUFSIZ];
+   if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
+     return;
+   fp (out, "Attr[%p]:%s", attr, HVTY_NEWLINE);
+   if (!attr)
+     return;
+   /* IPv4 Nexthop */
+   inet_ntop (AF_INET, &attr->nexthop, buf, BUFSIZ);
+   fp (out, "  nexthop=%s%s", buf, HVTY_NEWLINE);
+   fp (out, "  aspath=%p, refcnt=%d%s", attr->aspath,
+       (attr->aspath ? attr->aspath->refcnt : 0), HVTY_NEWLINE);
+   fp (out, "  community=%p, refcnt=%d%s", attr->community,
+       (attr->community ? attr->community->refcnt : 0), HVTY_NEWLINE);
+   if ((ae = attr->extra))
+     {
+       fp (out, "  ecommunity=%p, refcnt=%d%s", ae->ecommunity,
+           (ae->ecommunity ? ae->ecommunity->refcnt : 0), HVTY_NEWLINE);
+       fp (out, "  cluster=%p, refcnt=%d%s", ae->cluster,
+           (ae->cluster ? ae->cluster->refcnt : 0), HVTY_NEWLINE);
+       fp (out, "  transit=%p, refcnt=%d%s", ae->transit,
+           (ae->transit ? ae->transit->refcnt : 0), HVTY_NEWLINE);
+     }
+ }
+ /*
+  * Print BI in an Import Table
+  */
+ void
+ rfapiPrintBi (void *stream, struct bgp_info *bi)
+ {
+   char buf[BUFSIZ];
+   char *s;
+   int (*fp) (void *, const char *, ...);
+   struct vty *vty;
+   void *out;
+   const char *vty_newline;
+   char line[BUFSIZ];
+   char *p = line;
+   int r;
+   int has_macaddr = 0;
+   struct ethaddr macaddr;
+   struct rfapi_l2address_option l2o_buf;
+   uint8_t l2hid=0;                /* valid if has_macaddr */
+ #define REMAIN (BUFSIZ - (p-line))
+ #define INCP {p += (r > REMAIN)? REMAIN: r;}
+   if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
+     return;
+   if (!bi)
+     return;
+   if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && bi->extra
+       && bi->extra->vnc.import.timer)
+     {
+       struct thread *t = (struct thread *) bi->extra->vnc.import.timer;
+       r = snprintf (p, REMAIN, " [%4lu] ", thread_timer_remain_second (t));
+       INCP;
+     }
+   else
+     {
+       r = snprintf (p, REMAIN, "        ");
+       INCP;
+     }
+   if (bi->extra)
+     {
+       /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
+       if (decode_rd_type(bi->extra->vnc.import.rd.val) == RD_TYPE_VNC_ETH)
+         {
+           has_macaddr = 1;
+           memcpy (macaddr.octet, bi->extra->vnc.import.rd.val + 2, 6);
+           l2hid = bi->extra->vnc.import.rd.val[1];
+         }
+     }
+   /*
+    * Print these items:
+    *          type/subtype
+    *          nexthop address
+    *          lifetime
+    *          RFP option sizes (they are opaque values)
+    *          extended communities (RTs)
+    */
+   if (bi->attr && bi->attr->extra)
+     {
+       uint32_t lifetime;
+       int printed_1st_gol = 0;
+       struct bgp_attr_encap_subtlv *pEncap;
+       struct prefix pfx_un;
+       int af = BGP_MP_NEXTHOP_FAMILY (bi->attr->extra->mp_nexthop_len);
+       /* Nexthop */
+       if (af == AF_INET)
+         {
+           r = snprintf (p, REMAIN, "%s", inet_ntop (AF_INET,
+                                                     &bi->attr->extra->mp_nexthop_global_in,
+                                                     buf, BUFSIZ));
+           INCP;
+         }
+       else if (af == AF_INET6)
+         {
+           r = snprintf (p, REMAIN, "%s", inet_ntop (AF_INET6,
+                                                     &bi->attr->extra->mp_nexthop_global,
+                                                     buf, BUFSIZ));
+           INCP;
+         }
+       else
+         {
+           r = snprintf (p, REMAIN, "?");
+           INCP;
+         }
+       /*
+        * VNC tunnel subtlv, if present, contains UN address
+        */
+       if (!rfapiGetVncTunnelUnAddr (bi->attr, &pfx_un))
+         {
+           r = snprintf (p, REMAIN, " un=%s", inet_ntop (pfx_un.family,
+                                                         pfx_un.u.val, buf,
+                                                         BUFSIZ));
+           INCP;
+         }
+       /* Lifetime */
+       if (rfapiGetVncLifetime (bi->attr, &lifetime))
+         {
+           r = snprintf (p, REMAIN, " nolife");
+           INCP;
+         }
+       else
+         {
+           if (lifetime == 0xffffffff)
+             r = snprintf (p, REMAIN, " %6s", "infini");
+           else
+             r = snprintf (p, REMAIN, " %6u", lifetime);
+           INCP;
+         }
+       /* RFP option lengths */
+       for (pEncap = bi->attr->extra->vnc_subtlvs; pEncap;
+            pEncap = pEncap->next)
+         {
+           if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION)
+             {
+               if (printed_1st_gol)
+                 {
+                   r = snprintf (p, REMAIN, ",");
+                   INCP;
+                 }
+               else
+                 {
+                   r = snprintf (p, REMAIN, " ");        /* leading space */
+                   INCP;
+                 }
+               r = snprintf (p, REMAIN, "%d", pEncap->length);
+               INCP;
+               printed_1st_gol = 1;
+             }
+         }
+       /* RT list */
+       if (bi->attr->extra->ecommunity)
+         {
+           s = ecommunity_ecom2str (bi->attr->extra->ecommunity,
+                                    ECOMMUNITY_FORMAT_ROUTE_MAP);
+           r = snprintf (p, REMAIN, " %s", s);
+           INCP;
+           XFREE (MTYPE_ECOMMUNITY_STR, s);
+         }
+     }
+   r = snprintf (p, REMAIN, " bi@%p", bi);
+   INCP;
+   r = snprintf (p, REMAIN, " p@%p", bi->peer);
+   INCP;
+   if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
+     {
+       r = snprintf (p, REMAIN, " HD=yes");
+       INCP;
+     }
+   else
+     {
+       r = snprintf (p, REMAIN, " HD=no");
+       INCP;
+     }
+   if (bi->attr)
+     {
+       if (bi->attr->extra)
+         {
+           r = snprintf (p, REMAIN, " W=%d", bi->attr->extra->weight);
+           INCP;
+         }
+       if (bi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
+         {
+           r = snprintf (p, REMAIN, " LP=%d", bi->attr->local_pref);
+           INCP;
+         }
+       else
+         {
+           r = snprintf (p, REMAIN, " LP=unset");
+           INCP;
+         }
+     }
+   r =
+     snprintf (p, REMAIN, " %c:%u", zebra_route_char (bi->type), bi->sub_type);
+   INCP;
+   fp (out, "%s%s", line, HVTY_NEWLINE);
+   if (has_macaddr)
+     {
+       fp (out, "        RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s",
+           l2hid,
+           macaddr.octet[0],
+           macaddr.octet[1],
+           macaddr.octet[2],
+           macaddr.octet[3], macaddr.octet[4], macaddr.octet[5], HVTY_NEWLINE);
+     }
+   if (!rfapiGetL2o (bi->attr, &l2o_buf))
+     {
+       fp (out,
+           "        L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
+           l2o_buf.macaddr.octet[0], l2o_buf.macaddr.octet[1],
+           l2o_buf.macaddr.octet[2], l2o_buf.macaddr.octet[3],
+           l2o_buf.macaddr.octet[4], l2o_buf.macaddr.octet[5], l2o_buf.label,
+           l2o_buf.logical_net_id, l2o_buf.local_nve_id, HVTY_NEWLINE);
+     }
+   if (bi->extra && bi->extra->vnc.import.aux_prefix.family)
+     {
+       char buf[BUFSIZ];
+       const char *sp;
+       sp = rfapi_ntop (bi->extra->vnc.import.aux_prefix.family,
+                        &bi->extra->vnc.import.aux_prefix.u.prefix,
+                        buf, BUFSIZ);
+       buf[BUFSIZ - 1] = 0;
+       if (sp)
+         {
+           fp (out, "        IP: %s%s", sp, HVTY_NEWLINE);
+         }
+     }
+   {
+     struct rfapi_un_option *uo = rfapi_encap_tlv_to_un_option (bi->attr);
+     if (uo)
+       {
+         rfapi_print_tunneltype_option (stream, 8, &uo->v.tunnel);
+         rfapi_un_options_free (uo);
+       }
+   }
+ }
+ char *
+ rfapiMonitorVpn2Str (struct rfapi_monitor_vpn *m, char *buf, int size)
+ {
+   char buf_pfx[BUFSIZ];
+   char buf_vn[BUFSIZ];
+   char buf_un[BUFSIZ];
+   int rc;
+   rfapiRfapiIpAddr2Str (&m->rfd->un_addr, buf_vn, BUFSIZ);
+   rfapiRfapiIpAddr2Str (&m->rfd->vn_addr, buf_un, BUFSIZ);
+   rc = snprintf (buf, size,
+                  "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p",
+                  m, m->next, m->rfd, buf_vn, buf_un,
+                  inet_ntop (m->p.family, &m->p.u.prefix, buf_pfx, BUFSIZ),
+                  m->p.prefixlen, m->node);
+   buf[size - 1] = 0;
+   if (rc >= size)
+     return NULL;
+   return buf;
+ }
+ static void
+ rfapiDebugPrintMonitorVpn (void *stream, struct rfapi_monitor_vpn *m)
+ {
+   char buf[BUFSIZ];
+   int (*fp) (void *, const char *, ...);
+   struct vty *vty;
+   void *out;
+   const char *vty_newline;
+   if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
+     return;
+   rfapiMonitorVpn2Str (m, buf, BUFSIZ);
+   fp (out, "    Mon %s%s", buf, HVTY_NEWLINE);
+ }
+ static void
+ rfapiDebugPrintMonitorEncap (void *stream, struct rfapi_monitor_encap *m)
+ {
+   int (*fp) (void *, const char *, ...);
+   struct vty *vty;
+   void *out = NULL;
+   const char *vty_newline;
+   if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
+     return;
+   fp (out, "    Mon m=%p, next=%p, node=%p, bi=%p%s",
+       m, m->next, m->node, m->bi, HVTY_NEWLINE);
+ }
+ void
+ rfapiShowItNode (void *stream, struct route_node *rn)
+ {
+   struct bgp_info *bi;
+   char buf[BUFSIZ];
+   int (*fp) (void *, const char *, ...);
+   struct vty *vty;
+   void *out;
+   const char *vty_newline;
+   if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
+     return;
+   fp (out, "%s/%d @%p #%d%s",
+       rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ),
+       rn->p.prefixlen, rn, rn->lock, HVTY_NEWLINE);
+   for (bi = rn->info; bi; bi = bi->next)
+     {
+       rfapiPrintBi (stream, bi);
+     }
+   /* doesn't show montors */
+ }
+ void
+ rfapiShowImportTable (
+   void                        *stream,
+   const char          *label,
+   struct route_table  *rt,
+   int                 isvpn)
+ {
+   struct route_node *rn;
+   char buf[BUFSIZ];
+   int (*fp) (void *, const char *, ...);
+   struct vty *vty;
+   void *out;
+   const char *vty_newline;
+   if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
+     return;
+   fp (out, "Import Table [%s]%s", label, HVTY_NEWLINE);
+   for (rn = route_top (rt); rn; rn = route_next (rn))
+     {
+       struct bgp_info *bi;
+       if (rn->p.family == AF_ETHERNET)
+         {
+           rfapiEthAddr2Str (&rn->p.u.prefix_eth, buf, BUFSIZ);
+         }
+       else
+         {
+           inet_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ);
+         }
+       fp (out, "%s/%d @%p #%d%s", buf, rn->p.prefixlen, rn, rn->lock - 1,       /* account for loop iterator locking */
+           HVTY_NEWLINE);
+       for (bi = rn->info; bi; bi = bi->next)
+         {
+           rfapiPrintBi (stream, bi);
+         }
+       if (isvpn)
+         {
+           struct rfapi_monitor_vpn *m;
+           for (m = RFAPI_MONITOR_VPN (rn); m; m = m->next)
+             {
+               rfapiDebugPrintMonitorVpn (stream, m);
+             }
+         }
+       else
+         {
+           struct rfapi_monitor_encap *m;
+           for (m = RFAPI_MONITOR_ENCAP (rn); m; m = m->next)
+             {
+               rfapiDebugPrintMonitorEncap (stream, m);
+             }
+         }
+     }
+ }
+ int
+ rfapiShowVncQueries (void *stream, struct prefix *pfx_match)
+ {
+   struct bgp *bgp;
+   struct rfapi *h;
+   struct listnode *node;
+   struct rfapi_descriptor *rfd;
+   int (*fp) (void *, const char *, ...);
+   struct vty *vty;
+   void *out;
+   const char *vty_newline;
+   int printedheader = 0;
+   int nves_total = 0;
+   int nves_with_queries = 0;
+   int nves_displayed = 0;
+   int queries_total = 0;
+   int queries_displayed = 0;
+   if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
+     return CMD_WARNING;
+   bgp = bgp_get_default ();     /* assume 1 instance for now */
+   if (!bgp)
+     {
+       vty_out (vty, "No BGP instance%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   h = bgp->rfapi;
+   if (!h)
+     {
+       vty_out (vty, "No RFAPI instance%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
+     {
+       struct route_node *rn;
+       int printedquerier = 0;
+       ++nves_total;
+       if (rfd->mon || (rfd->mon_eth && skiplist_count (rfd->mon_eth)))
+         {
+           ++nves_with_queries;
+         }
+       else
+         {
+           continue;
+         }
+       /*
+        * IP Queries
+        */
+       if (rfd->mon)
+         {
+           for (rn = route_top (rfd->mon); rn; rn = route_next (rn))
+             {
+               struct rfapi_monitor_vpn *m;
+               char buf_remain[BUFSIZ];
+               char buf_pfx[BUFSIZ];
+               if (!rn->info)
+                 continue;
+               m = rn->info;
+               ++queries_total;
+               if (pfx_match && !prefix_match (pfx_match, &rn->p) &&
+                   !prefix_match (&rn->p, pfx_match))
+                 continue;
+               ++queries_displayed;
+               if (!printedheader)
+                 {
+                   ++printedheader;
+                   fp (out, "%s", VTY_NEWLINE);
+                   fp (out, "%-15s %-15s %-15s %-10s%s",
+                       "VN Address", "UN Address",
+                       "Target", "Remaining", VTY_NEWLINE);
+                 }
+               if (!printedquerier)
+                 {
+                   char buf_vn[BUFSIZ];
+                   char buf_un[BUFSIZ];
+                   rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ);
+                   rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ);
+                   fp (out, "%-15s %-15s", buf_vn, buf_un);
+                   printedquerier = 1;
+                   ++nves_displayed;
+                 }
+               else
+                 fp (out, "%-15s %-15s", "", "");
+               buf_remain[0] = 0;
+               if (m->timer)
+                 {
+                   rfapiFormatSeconds (thread_timer_remain_second (m->timer),
+                                       buf_remain, BUFSIZ);
+                 }
+               fp (out, " %-15s %-10s%s",
+                   inet_ntop (m->p.family, &m->p.u.prefix, buf_pfx, BUFSIZ),
+                   buf_remain, VTY_NEWLINE);
+             }
+         }
+       /*
+        * Ethernet Queries
+        */
+       if (rfd->mon_eth && skiplist_count (rfd->mon_eth))
+         {
+           int rc;
+           void *cursor;
+           struct rfapi_monitor_eth *mon_eth;
+           for (cursor = NULL,
+                rc =
+                skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth,
+                               &cursor); rc == 0;
+                rc =
+                skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth,
+                               &cursor))
+             {
+               char buf_remain[BUFSIZ];
+               char buf_pfx[BUFSIZ];
+               struct prefix pfx_mac;
+               ++queries_total;
+               zlog_debug ("%s: checking rfd=%p mon_eth=%p", __func__, rfd,
+                           mon_eth);
+               memset ((void *) &pfx_mac, 0, sizeof (struct prefix));
+               pfx_mac.family = AF_ETHERNET;
+               pfx_mac.prefixlen = 48;
+               pfx_mac.u.prefix_eth = mon_eth->macaddr;
+               if (pfx_match && !prefix_match (pfx_match, &pfx_mac) &&
+                   !prefix_match (&pfx_mac, pfx_match))
+                 continue;
+               ++queries_displayed;
+               if (!printedheader)
+                 {
+                   ++printedheader;
+                   fp (out, "%s", VTY_NEWLINE);
+                   fp (out, "%-15s %-15s %-17s %10s %-10s%s",
+                       "VN Address", "UN Address",
+                       "Target", "LNI", "Remaining", VTY_NEWLINE);
+                 }
+               if (!printedquerier)
+                 {
+                   char buf_vn[BUFSIZ];
+                   char buf_un[BUFSIZ];
+                   rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ);
+                   rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ);
+                   fp (out, "%-15s %-15s", buf_vn, buf_un);
+                   printedquerier = 1;
+                   ++nves_displayed;
+                 }
+               else
+                 fp (out, "%-15s %-15s", "", "");
+               buf_remain[0] = 0;
+               if (mon_eth->timer)
+                 {
+                   rfapiFormatSeconds (thread_timer_remain_second
+                                       (mon_eth->timer), buf_remain, BUFSIZ);
+                 }
+               fp (out, " %-17s %10d %-10s%s",
+                   rfapi_ntop (pfx_mac.family, &pfx_mac.u.prefix, buf_pfx,
+                               BUFSIZ), mon_eth->logical_net_id, buf_remain,
+                   VTY_NEWLINE);
+             }
+         }
+     }
+   if (queries_total)
+     {
+       fp (out, "%s", VTY_NEWLINE);
+       fp (out, "Displayed %d out of %d total queries%s",
+           queries_displayed, queries_total, VTY_NEWLINE);
+     }
+   return CMD_SUCCESS;
+ }
+ static int
+ rfapiPrintRemoteRegBi (
+   struct bgp          *bgp,
+   void                        *stream,
+   struct route_node   *rn,
+   struct bgp_info     *bi)
+ {
+   int (*fp) (void *, const char *, ...);
+   struct vty *vty;
+   void *out;
+   const char *vty_newline;
+   struct prefix pfx_un;
+   struct prefix pfx_vn;
+   uint8_t cost;
+   uint32_t lifetime;
+   bgp_encap_types tun_type;
+   char buf_pfx[BUFSIZ];
+   char buf_ntop[BUFSIZ];
+   char buf_un[BUFSIZ];
+   char buf_vn[BUFSIZ];
+   char buf_lifetime[BUFSIZ];
+   int nlines = 0;
+   if (!stream)
+     return 0;                   /* for debug log, print into buf & call output once */
+   if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
+     return 0;
+   /*
+    * Prefix
+    */
+   buf_pfx[0] = 0;
+   snprintf (buf_pfx, BUFSIZ, "%s/%d",
+             rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf_ntop, BUFSIZ),
+             rn->p.prefixlen);
+   buf_pfx[BUFSIZ - 1] = 0;
+   nlines++;
+   /*
+    * UN addr
+    */
+   buf_un[0] = 0;
+   if (!rfapiGetUnAddrOfVpnBi (bi, &pfx_un))
+     {
+       snprintf (buf_un, BUFSIZ, "%s",
+                 inet_ntop (pfx_un.family, &pfx_un.u.prefix, buf_ntop,
+                            BUFSIZ));
+     }
+   buf_un[BUFSIZ - 1] = 0;
+   rfapiGetTunnelType(bi->attr,&tun_type);
+   /*
+    * VN addr
+    */
+   buf_vn[0] = 0;
+   if (tun_type == BGP_ENCAP_TYPE_MPLS)
+     {
+       /* MPLS carries un in nrli next hop (same as vn for IP tunnels) */
+       if (bi->extra)
+         {
+           u_int32_t l = decode_label (bi->extra->tag);
+           snprintf (buf_vn, BUFSIZ, "Label: %d", l);
+         }
+       else                      /* should never happen */
+         {
+           snprintf (buf_vn, BUFSIZ, "Label: N/A");
+         }
+     }
+   else
+     {
+       rfapiNexthop2Prefix (bi->attr, &pfx_vn);
+       snprintf (buf_vn, BUFSIZ, "%s",
+                 inet_ntop (pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ));
+     }
+   buf_vn[BUFSIZ - 1] = 0;
+   
+   /*
+    * Cost is encoded in local_pref as (255-cost)
+    * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
+    * back to cost.
+    */
+   if (bi->attr)
+     {
+       uint32_t local_pref;
+       if (bi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
+         local_pref = bi->attr->local_pref;
+       else
+         local_pref = 0;
+       cost = (local_pref > 255) ? 0 : 255 - local_pref;
+     }
+   else
+     {
+       cost = 0;
+     }
+   fp (out, "%-20s ", buf_pfx);
+   fp (out, "%-15s ", buf_vn);
+   fp (out, "%-15s ", buf_un);
+   fp (out, "%-4d ", cost);
+   /* Lifetime */
+   /* NB rfapiGetVncLifetime sets infinite value when returning !0 */
+   if (rfapiGetVncLifetime (bi->attr, &lifetime) ||
+       (lifetime == RFAPI_INFINITE_LIFETIME))
+     {
+       fp (out, "%-10s ", "infinite");
+     }
+   else
+     {
+       time_t t_lifetime = lifetime;
+       rfapiFormatSeconds (t_lifetime, buf_lifetime, BUFSIZ);
+       fp (out, "%-10s ", buf_lifetime);
+     }
+   if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) &&
+       bi->extra && bi->extra->vnc.import.timer)
+     {
+       uint32_t remaining;
+       time_t age;
+       char buf_age[BUFSIZ];
+       struct thread *t = (struct thread *) bi->extra->vnc.import.timer;
+       remaining = thread_timer_remain_second (t);
+ #if RFAPI_REGISTRATIONS_REPORT_AGE
+       /*
+        * Calculate when the timer started. Doing so here saves
+        * us a timestamp field in "struct bgp_info".
+        *
+        * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
+        * original calculation.
+        */
+       age = rfapiGetHolddownFromLifetime (lifetime, factor) - remaining;
+ #else /* report remaining time */
+       age = remaining;
+ #endif
+       rfapiFormatSeconds (age, buf_age, BUFSIZ);
+       fp (out, "%-10s ", buf_age);
+     }
+   else if (RFAPI_LOCAL_BI (bi))
+     {
+       char buf_age[BUFSIZ];
+       if (bi && bi->extra && bi->extra->vnc.import.create_time)
+         {
+           rfapiFormatAge (bi->extra->vnc.import.create_time, buf_age, BUFSIZ);
+         }
+       else
+         {
+           buf_age[0] = '?';
+           buf_age[1] = 0;
+         }
+       fp (out, "%-10s ", buf_age);
+     }
+   fp (out, "%s", HVTY_NEWLINE);
+   if (rn->p.family == AF_ETHERNET)
+     {
+       /*
+        * If there is a corresponding IP address && != VN address, 
+        * print that on the next line
+        */
+       if (bi && bi->extra && bi->extra->vnc.import.aux_prefix.family)
+         {
+           const char *sp;
+           sp = rfapi_ntop (bi->extra->vnc.import.aux_prefix.family,
+                            &bi->extra->vnc.import.aux_prefix.u.prefix,
+                            buf_ntop, BUFSIZ);
+           buf_ntop[BUFSIZ - 1] = 0;
+           if (sp && strcmp (buf_vn, sp) != 0)
+             {
+               fp (out, "  IP: %s", sp);
+               if (nlines == 1)
+                 nlines++;
+             }
+         }
+     }
+   if (tun_type != BGP_ENCAP_TYPE_MPLS && bi->extra)
+     {
+       u_int32_t l = decode_label (bi->extra->tag);
+       if (!MPLS_LABEL_IS_NULL (l))
+         {
+           fp (out, "  Label: %d", l);
+           if (nlines == 1)
+             nlines++;
+         }
+     }
+   if (nlines > 1)
+     fp (out, "%s", HVTY_NEWLINE);
+   return 1;
+ }
+ static int
+ rfapiShowRemoteRegistrationsIt (
+   struct bgp                  *bgp,
+   void                                *stream,
+   struct rfapi_import_table   *it,
+   struct prefix                       *prefix_only,
+   int                         show_expiring,  /* either/or */
+   int                         show_local,
+   int                         show_remote,
+   int                         show_imported,  /* either/or */
+   uint32_t                    *pLni)          /* AFI_ETHER only */
+ {
+   afi_t afi;
+   int printed_rtlist_hdr = 0;
+   int (*fp) (void *, const char *, ...);
+   struct vty *vty;
+   void *out;
+   const char *vty_newline;
+   int total = 0;
+   int printed = 0;
+   if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
+     return printed;
+   for (afi = AFI_IP; afi < AFI_MAX; ++afi)
+     {
+       struct route_node *rn;
+       if (!it->imported_vpn[afi])
+         continue;
+       for (rn = route_top (it->imported_vpn[afi]); rn; rn = route_next (rn))
+         {
+           struct bgp_info *bi;
+           int count_only;
+           /* allow for wider or more narrow mask from user */
+           if (prefix_only &&
+               !prefix_match (prefix_only, &rn->p) &&
+               !prefix_match (&rn->p, prefix_only))
+             count_only = 1;
+           else
+             count_only = 0;
+           for (bi = rn->info; bi; bi = bi->next)
+             {
+               if (!show_local && RFAPI_LOCAL_BI (bi))
+                 {
+                   /* local route from RFP */
+                   continue;
+                 }
+               if (!show_remote && !RFAPI_LOCAL_BI (bi))
+                 {
+                   /* remote route */
+                   continue;
+                 }
+               if (show_expiring && !CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
+                 continue;
+               if (!show_expiring && CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
+                 continue;
+               if (bi->type == ZEBRA_ROUTE_BGP_DIRECT ||
+                   bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT)
+                 {
+                   if (!show_imported)
+                     continue;
+                 }
+               else
+                 {
+                   if (show_imported)
+                     continue;
+                 }
+               total++;
+               if (count_only == 1)
+                 continue;
+               if (!printed_rtlist_hdr)
+                 {
+                   const char *agetype = "";
+                   char *s;
+                   const char *type = "";
+                   if (show_imported)
+                     {
+                       type = "Imported";
+                     }
+                   else
+                     {
+                       if (show_expiring)
+                         {
+                           type = "Holddown";
+                         }
+                       else
+                         {
+                           if (RFAPI_LOCAL_BI (bi))
+                             {
+                               type = "Local";
+                             }
+                           else
+                             {
+                               type = "Remote";
+                             }
+                         }
+                     }
+                   s = ecommunity_ecom2str (it->rt_import_list,
+                                            ECOMMUNITY_FORMAT_ROUTE_MAP);
+                   if (pLni)
+                     {
+                       fp (out, "%s[%s] L2VPN Network 0x%x (%u) RT={%s}%s",
+                           HVTY_NEWLINE, type, *pLni, (*pLni & 0xfff), s,
+                           HVTY_NEWLINE);
+                     }
+                   else
+                     {
+                       fp (out, "%s[%s] Prefix RT={%s}%s",
+                           HVTY_NEWLINE, type, s, HVTY_NEWLINE);
+                     }
+                   XFREE (MTYPE_ECOMMUNITY_STR, s);
+                   if (show_expiring)
+                     {
+ #if RFAPI_REGISTRATIONS_REPORT_AGE
+                       agetype = "Age";
+ #else
+                       agetype = "Remaining";
+ #endif
+                     }
+                   else if (show_local)
+                     {
+                       agetype = "Age";
+                     }
+                   printed_rtlist_hdr = 1;
+                   fp (out, "%-20s %-15s %-15s %4s %-10s %-10s%s",
+                       (pLni ? "L2 Address/IP" : "Prefix"),
+                       "VN Address", "UN Address", "Cost",
+                       "Lifetime", agetype, HVTY_NEWLINE);
+                 }
+               printed += rfapiPrintRemoteRegBi (bgp, stream, rn, bi);
+             }
+         }
+     }
+   if (printed > 0)
+     {
+       const char *type = "prefixes";
+       if (show_imported)
+         {
+           type = "imported prefixes";
+         }
+       else
+         {
+           if (show_expiring)
+             {
+               type = "prefixes in holddown";
+             }
+           else
+             {
+               if (show_local && !show_remote)
+                 {
+                   type = "locally registered prefixes";
+                 }
+               else if (!show_local && show_remote)
+                 {
+                   type = "remotely registered prefixes";
+                 }
+             }
+         }
+       fp (out, "Displayed %d out of %d %s%s",
+           printed, total, type, HVTY_NEWLINE);
+     }
+   return printed;
+ }
+ /*
+  * rfapiShowRemoteRegistrations
+  *
+  * Similar to rfapiShowImportTable() above. This function
+  * is mean to produce the "remote" portion of the output
+  * of "show vnc registrations".
+  */
+ int
+ rfapiShowRemoteRegistrations (
+   void                *stream,
+   struct prefix       *prefix_only,
+   int         show_expiring,
+   int         show_local,
+   int         show_remote,
+   int         show_imported)
+ {
+   struct bgp *bgp;
+   struct rfapi *h;
+   struct rfapi_import_table *it;
+   int printed = 0;
+   bgp = bgp_get_default ();
+   if (!bgp)
+     {
+       return printed;
+     }
+   h = bgp->rfapi;
+   if (!h)
+     {
+       return printed;
+     }
+   for (it = h->imports; it; it = it->next)
+     {
+       printed +=
+         rfapiShowRemoteRegistrationsIt (bgp, stream, it, prefix_only,
+                                         show_expiring, show_local,
+                                         show_remote, show_imported, NULL);
+     }
+   if (h->import_mac)
+     {
+       void *cursor = NULL;
+       int rc;
+       uintptr_t lni_as_ptr;
+       uint32_t lni;
+       uint32_t *pLni;
+       for (rc =
+            skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it,
+                           &cursor); !rc;
+            rc =
+            skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it,
+                           &cursor))
+         {
+           pLni = NULL;
+           if ((lni_as_ptr & 0xffffffff) == lni_as_ptr)
+             {
+               lni = (uint32_t) (lni_as_ptr & 0xffffffff);
+               pLni = &lni;
+             }
+           printed +=
+             rfapiShowRemoteRegistrationsIt (bgp, stream, it, prefix_only,
+                                             show_expiring, show_local,
+                                             show_remote, show_imported, pLni);
+         }
+     }
+   return printed;
+ }
+ /*------------------------------------------
+  * rfapiRfapiIpAddr2Str
+  *
+  * UI helper: generate string from rfapi_ip_addr
+  *
+  * input: 
+  *    a                       IP v4/v6 address
+  *
+  * output
+  *    buf                     put string here
+  *    bufsize                 max space to write
+  *
+  * return value:
+  *    NULL                    conversion failed
+  *    non-NULL                pointer to buf
+  --------------------------------------------*/
+ const char *
+ rfapiRfapiIpAddr2Str (struct rfapi_ip_addr *a, char *buf, int bufsize)
+ {
+   const char *rc = NULL;
+   switch (a->addr_family)
+     {
+     case AF_INET:
+       rc = inet_ntop (a->addr_family, &a->addr.v4, buf, bufsize);
+       break;
+     case AF_INET6:
+       rc = inet_ntop (a->addr_family, &a->addr.v6, buf, bufsize);
+       break;
+     }
+   return rc;
+ }
+ void
+ rfapiPrintRfapiIpAddr (void *stream, struct rfapi_ip_addr *a)
+ {
+   char buf[BUFSIZ];
+   const char *rc = NULL;
+   int (*fp) (void *, const char *, ...);
+   struct vty *vty;
+   void *out = NULL;
+   const char *vty_newline;
+   if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
+     return;
+   rc = rfapiRfapiIpAddr2Str (a, buf, BUFSIZ);
+   if (rc)
+     fp (out, "%s", buf);
+ }
+ const char *
+ rfapiRfapiIpPrefix2Str (struct rfapi_ip_prefix *p, char *buf, int bufsize)
+ {
+   struct rfapi_ip_addr *a = &p->prefix;
+   const char *rc = NULL;
+   switch (a->addr_family)
+     {
+     case AF_INET:
+       rc = inet_ntop (a->addr_family, &a->addr.v4, buf, bufsize);
+       break;
+     case AF_INET6:
+       rc = inet_ntop (a->addr_family, &a->addr.v6, buf, bufsize);
+       break;
+     }
+   if (rc)
+     {
+       int alen = strlen (buf);
+       int remaining = bufsize - alen - 1;
+       int slen;
+       if (remaining > 0)
+         {
+           slen = snprintf (buf + alen, remaining, "/%u", p->length);
+           if (slen < remaining) /* see man page for snprintf(3) */
+             return rc;
+         }
+     }
+   return NULL;
+ }
+ void
+ rfapiPrintRfapiIpPrefix (void *stream, struct rfapi_ip_prefix *p)
+ {
+   char buf[BUFSIZ];
+   const char *rc;
+   int (*fp) (void *, const char *, ...);
+   struct vty *vty;
+   void *out = NULL;
+   const char *vty_newline;
+   if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
+     return;
+   rc = rfapiRfapiIpPrefix2Str (p, buf, BUFSIZ);
+   if (rc)
+     fp (out, "%s:%u", buf, p->cost);
+   else
+     fp (out, "?/?:?");
+ }
+ void
+ rfapiPrintRd (struct vty *vty, struct prefix_rd *prd)
+ {
+   char buf[BUFSIZ];
+   buf[0] = 0;
+   prefix_rd2str (prd, buf, BUFSIZ);
+   buf[BUFSIZ - 1] = 0;
+   vty_out (vty, "%s", buf);
+ }
+ void
+ rfapiPrintAdvertisedInfo (
+   struct vty                  *vty,
+   struct rfapi_descriptor     *rfd,
+   safi_t                      safi,
+   struct prefix                       *p)
+ {
+   afi_t afi;                    /* of the VN address */
+   struct bgp_node *bn;
+   struct bgp_info *bi;
+   uint8_t type = ZEBRA_ROUTE_BGP;
+   struct bgp *bgp;
+   int printed = 0;
+   struct prefix_rd prd0;
+   struct prefix_rd *prd;
+   /*
+    * Find the bgp_info in the RIB corresponding to this
+    * prefix and rfd
+    */
+   afi = family2afi (p->family);
+   assert (afi == AFI_IP || afi == AFI_IP6);
+   bgp = bgp_get_default ();     /* assume 1 instance for now */
+   assert (bgp);
+   if (safi == SAFI_ENCAP)
+     {
+       memset (&prd0, 0, sizeof (prd0));
+       prd0.family = AF_UNSPEC;
+       prd0.prefixlen = 64;
+       prd = &prd0;
+     }
+   else
+     {
+       prd = &rfd->rd;
+     }
+   bn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
+   vty_out (vty, "  bn=%p%s", bn, HVTY_NEWLINE);
+   for (bi = bn->info; bi; bi = bi->next)
+     {
+       if (bi->peer == rfd->peer &&
+           bi->type == type &&
+           bi->sub_type == BGP_ROUTE_RFP &&
+           bi->extra && bi->extra->vnc.export.rfapi_handle == (void *) rfd)
+         {
+           rfapiPrintBi (vty, bi);
+           printed = 1;
+         }
+     }
+   if (!printed)
+     {
+       vty_out (vty, "    --?--%s", HVTY_NEWLINE);
+       return;
+     }
+ }
+ void
+ rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd)
+ {
+   /* pHD un-addr vn-addr pCB cookie rd lifetime */
+   /* RT export list */
+   /* RT import list */
+   /* list of advertised prefixes */
+   /* dump import table */
+   char *s;
+   void *cursor;
+   int rc;
+   afi_t afi;
+   struct rfapi_adb *adb;
+   char buf[BUFSIZ];
+   vty_out (vty, "%-10p ", rfd);
+   rfapiPrintRfapiIpAddr (vty, &rfd->un_addr);
+   vty_out (vty, " ");
+   rfapiPrintRfapiIpAddr (vty, &rfd->vn_addr);
+   vty_out (vty, " %p %p ", rfd->response_cb, rfd->cookie);
+   rfapiPrintRd (vty, &rfd->rd);
+   vty_out (vty, " %d", rfd->response_lifetime);
+   vty_out (vty, " %s", (rfd->rfg ? rfd->rfg->name : "<orphaned>"));
+   vty_out (vty, "%s", HVTY_NEWLINE);
+   vty_out (vty, " Peer %p #%d%s", rfd->peer, rfd->peer->lock, HVTY_NEWLINE);
+   /* export RT list */
+   if (rfd->rt_export_list)
+     {
+       s =
+         ecommunity_ecom2str (rfd->rt_export_list,
+                              ECOMMUNITY_FORMAT_ROUTE_MAP);
+       vty_out (vty, " Export %s%s", s, HVTY_NEWLINE);
+       XFREE (MTYPE_ECOMMUNITY_STR, s);
+     }
+   else
+     {
+       vty_out (vty, " Export (nil)%s", HVTY_NEWLINE);
+     }
+   /* import RT list */
+   if (rfd->import_table)
+     {
+       s = ecommunity_ecom2str (rfd->import_table->rt_import_list,
+                                ECOMMUNITY_FORMAT_ROUTE_MAP);
+       vty_out (vty, " Import %s%s", s, HVTY_NEWLINE);
+       XFREE (MTYPE_ECOMMUNITY_STR, s);
+     }
+   else
+     {
+       vty_out (vty, " Import (nil)%s", HVTY_NEWLINE);
+     }
+   for (afi = AFI_IP; afi < AFI_MAX; ++afi)
+     {
+       u_char family;
+       family = afi2family (afi);
+       if (!family)
+         continue;
+       cursor = NULL;
+       for (rc =
+            skiplist_next (rfd->advertised.ipN_by_prefix, NULL, (void **) &adb,
+                           &cursor); rc == 0;
+            rc =
+            skiplist_next (rfd->advertised.ipN_by_prefix, NULL, (void **) &adb,
+                           &cursor))
+         {
+           /* group like family prefixes together in output */
+           if (family != adb->prefix_ip.family)
+             continue;
+           prefix2str (&adb->prefix_ip, buf, BUFSIZ);
+           buf[BUFSIZ - 1] = 0;  /* guarantee NUL-terminated */
+           vty_out (vty, "  Adv Pfx: %s%s", buf, HVTY_NEWLINE);
+           rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->prefix_ip);
+         }
+     }
+   for (rc =
+        skiplist_next (rfd->advertised.ip0_by_ether, NULL, (void **) &adb,
+                       &cursor); rc == 0;
+        rc =
+        skiplist_next (rfd->advertised.ip0_by_ether, NULL, (void **) &adb,
+                       &cursor))
+     {
+       prefix2str (&adb->prefix_eth, buf, BUFSIZ);
+       buf[BUFSIZ - 1] = 0;      /* guarantee NUL-terminated */
+       vty_out (vty, "  Adv Pfx: %s%s", buf, HVTY_NEWLINE);
+       /* TBD update the following function to print ethernet info */
+       /* Also need to pass/use rd */
+       rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->prefix_ip);
+     }
+   vty_out (vty, "%s", HVTY_NEWLINE);
+ }
+ /*
+  * test scripts rely on first line for each nve starting in 1st column,
+  * leading whitespace for additional detail of that nve
+  */
+ void
+ rfapiPrintMatchingDescriptors (struct vty *vty,
+                                struct prefix *vn_prefix,
+                                struct prefix *un_prefix)
+ {
+   struct bgp *bgp;
+   struct rfapi *h;
+   struct listnode *ln;
+   struct rfapi_descriptor *rfd;
+   int printed = 0;
+   bgp = bgp_get_default ();     /* assume 1 instance for now */
+   if (!bgp)
+     return;
+   h = bgp->rfapi;
+   assert (h);
+   for (ln = listhead (&h->descriptors); ln; ln = listnextnode (ln))
+     {
+       rfd = listgetdata (ln);
+       struct prefix pfx;
+       if (vn_prefix)
+         {
+           assert (!rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx));
+           if (!prefix_match (vn_prefix, &pfx))
+             continue;
+         }
+       if (un_prefix)
+         {
+           assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx));
+           if (!prefix_match (un_prefix, &pfx))
+             continue;
+         }
+       if (!printed)
+         {
+           /* print column header */
+           vty_out (vty,
+                    "%s %s %s %s %s %s %s %s%s",
+                    "descriptor", "un-addr", "vn-addr", "callback", "cookie",
+                    "RD", "lifetime", "group", HVTY_NEWLINE);
+         }
+       rfapiPrintDescriptor (vty, rfd);
+       printed = 1;
+     }
+ }
+ /*
+  * Parse an address and put into a struct prefix
+  */
+ int
+ rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p)
+ {
+   if (!str2prefix (str, p))
+     {
+       vty_out (vty, "Malformed address \"%s\"%s", str, HVTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   switch (p->family)
+     {
+     case AF_INET:
+       if (p->prefixlen != 32)
+         {
+           vty_out (vty, "Not a host address: \"%s\"%s", str, HVTY_NEWLINE);
+           return CMD_WARNING;
+         }
+       break;
+     case AF_INET6:
+       if (p->prefixlen != 128)
+         {
+           vty_out (vty, "Not a host address: \"%s\"%s", str, HVTY_NEWLINE);
+           return CMD_WARNING;
+         }
+       break;
+     default:
+       vty_out (vty, "Invalid address \"%s\"%s", str, HVTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   return 0;
+ }
+ int
+ rfapiCliGetRfapiIpAddr (
+   struct vty          *vty,
+   const char          *str,
+   struct rfapi_ip_addr        *hai)
+ {
+   struct prefix pfx;
+   int rc;
+   rc = rfapiCliGetPrefixAddr (vty, str, &pfx);
+   if (rc)
+     return rc;
+   hai->addr_family = pfx.family;
+   if (pfx.family == AF_INET)
+     hai->addr.v4 = pfx.u.prefix4;
+   else
+     hai->addr.v6 = pfx.u.prefix6;
+   return 0;
+ }
+ /*
+  * Note: this function does not flush vty output, so if it is called
+  * with a stream pointing to a vty, the user will have to type something
+  * before the callback output shows up
+  */
+ void
+ rfapiPrintNhl (void *stream, struct rfapi_next_hop_entry *next_hops)
+ {
+   struct rfapi_next_hop_entry *nh;
+   int count;
+   int (*fp) (void *, const char *, ...);
+   struct vty *vty;
+   void *out;
+   const char *vty_newline;
+ #define REMAIN (BUFSIZ - (p-line))
+ #define INCP {p += (r > REMAIN)? REMAIN: r;}
+   if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
+     return;
+   for (nh = next_hops, count = 1; nh; nh = nh->next, ++count)
+     {
+       char line[BUFSIZ];
+       char *p = line;
+       int r;
+       r = snprintf (p, REMAIN, "%3d  pfx=", count);
+       INCP;
+       if (rfapiRfapiIpPrefix2Str (&nh->prefix, p, REMAIN))
+         {
+           /* it fit, so count length */
+           r = strlen (p);
+         }
+       else
+         {
+           /* didn't fit */
+           goto truncate;
+         }
+       INCP;
+       r = snprintf (p, REMAIN, ", un=");
+       INCP;
+       if (rfapiRfapiIpAddr2Str (&nh->un_address, p, REMAIN))
+         {
+           /* it fit, so count length */
+           r = strlen (p);
+         }
+       else
+         {
+           /* didn't fit */
+           goto truncate;
+         }
+       INCP;
+       r = snprintf (p, REMAIN, ", vn=");
+       INCP;
+       if (rfapiRfapiIpAddr2Str (&nh->vn_address, p, REMAIN))
+         {
+           /* it fit, so count length */
+           r = strlen (p);
+         }
+       else
+         {
+           /* didn't fit */
+           goto truncate;
+         }
+       INCP;
+     truncate:
+       line[BUFSIZ - 1] = 0;
+       fp (out, "%s%s", line, HVTY_NEWLINE);
+       /*
+        * options
+        */
+       if (nh->vn_options)
+         {
+           struct rfapi_vn_option *vo;
+           char offset[] = "     ";
+           for (vo = nh->vn_options; vo; vo = vo->next)
+             {
+               char pbuf[100];
+               switch (vo->type)
+                 {
+                 case RFAPI_VN_OPTION_TYPE_L2ADDR:
+                   rfapiEthAddr2Str (&vo->v.l2addr.macaddr, pbuf,
+                                     sizeof (pbuf));
+                   fp (out, "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s",
+                       offset, pbuf, (vo->v.l2addr.label & 0x00ffffff),
+                       (vo->v.l2addr.logical_net_id & 0x00ffffff),
+                       vo->v.l2addr.local_nve_id, HVTY_NEWLINE);
+                   break;
+                 case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP:
+                   prefix2str (&vo->v.local_nexthop.addr, pbuf, sizeof (pbuf));
+                   fp (out, "%sLNH %s cost=%d%s",
+                       offset, pbuf, vo->v.local_nexthop.cost, HVTY_NEWLINE);
+                   break;
+                 default:
+                   fp (out, "%svn option type %d (unknown)%s",
+                       offset, vo->type, HVTY_NEWLINE);
+                   break;
+                 }
+             }
+         }
+       if (nh->un_options)
+         {
+           struct rfapi_un_option *uo;
+           char offset[] = "     ";
+           for (uo = nh->un_options; uo; uo = uo->next)
+             {
+               switch (uo->type)
+                 {
+                 case RFAPI_UN_OPTION_TYPE_TUNNELTYPE:
+                   rfapi_print_tunneltype_option (stream, 8, &uo->v.tunnel);
+                   break;
+                 default:
+                   fp (out, "%sUN Option type %d%s",
+                       offset, uo->type, vty_newline);
+                   break;
+                 }
+             }
+         }
+     }
+ }
+ /***********************************************************************
+  *                    STATIC ROUTES
+  ***********************************************************************/
+ /*
+  * Add another nexthop to the NHL
+  */
+ static void
+ rfapiAddDeleteLocalRfpPrefix (
+   struct rfapi_ip_addr                *un_addr,
+   struct rfapi_ip_addr                *vn_addr,
+   struct rfapi_ip_prefix      *rprefix,
+   int                         is_add,
+   uint32_t                    lifetime,     /* add only */
+   struct rfapi_vn_option      *vn_options,
+   struct rfapi_next_hop_entry **head,
+   struct rfapi_next_hop_entry **tail)
+ {
+   struct rfapi_next_hop_entry *new;
+   /*
+    * construct NHL
+    */
+   new = XCALLOC (MTYPE_RFAPI_NEXTHOP, sizeof (struct rfapi_next_hop_entry));
+   new->prefix = *rprefix;
+   new->un_address = *un_addr;
+   new->vn_address = *vn_addr;
+   new->vn_options = vn_options;
+   if (is_add)
+     {
+       new->lifetime = lifetime;
+     }
+   else
+     {
+       new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME;
+     }
+   if (*tail)
+     (*tail)->next = new;
+   *tail = new;
+   if (!*head)
+     {
+       *head = new;
+     }
+ }
+ static int
+ register_add (
+   struct vty *vty,
+   const char *arg_prefix,
+   const char *arg_vn,
+   const char *arg_un,
+   const char *arg_cost,     /* optional */
+   const char *arg_lifetime, /* optional */
+   const char *arg_macaddr,  /* optional */
+   const char *arg_vni,      /* mac present=>mandatory Virtual Network ID */
+   int        argc,
+   const char **argv)
+ {
+        struct rfapi_ip_addr vn_address;
+        struct rfapi_ip_addr un_address;
+        struct prefix pfx;
+        struct rfapi_ip_prefix rpfx;
+        uint32_t cost;
+        uint32_t lnh_cost;
+        uint32_t lifetime;
+        rfapi_handle rfd;
+        struct rfapi_vn_option optary[10];       /* XXX must be big enough */
+        struct rfapi_vn_option *opt = NULL;
+        int opt_next = 0;
+        int rc = CMD_WARNING;
+        char *endptr;
+        struct bgp *bgp;
+        struct rfapi *h;
+        struct rfapi_cfg *rfapi_cfg;
+        const char *arg_lnh = NULL;
+        const char *arg_lnh_cost = NULL;
+          bgp = bgp_get_default ();      /* assume 1 instance for now */
+        if (!bgp)
+          {
+            if (vty)
+              vty_out (vty, "BGP not configured%s", VTY_NEWLINE);
+            return CMD_WARNING;
+          }
+        h = bgp->rfapi;
+        rfapi_cfg = bgp->rfapi_cfg;
+        if (!h || !rfapi_cfg)
+          {
+            if (vty)
+              vty_out (vty, "RFAPI not configured%s", VTY_NEWLINE);
+            return CMD_WARNING;
+          }
+        for (; argc; --argc, ++argv)
+          {
+            if (!strcmp (*argv, "local-next-hop"))
+              {
+                if (arg_lnh)
+                  {
+                    vty_out (vty, "local-next-hop specified more than once%s",
+                             VTY_NEWLINE);
+                    return CMD_WARNING;
+                  }
+                if (argc <= 1)
+                  {
+                    vty_out (vty, "Missing parameter for local-next-hop%s",
+                             VTY_NEWLINE);
+                    return CMD_WARNING;
+                  }
+                ++argv, --argc;
+                arg_lnh = *argv;
+              }
+            if (!strcmp (*argv, "local-cost"))
+              {
+                if (arg_lnh_cost)
+                  {
+                    vty_out (vty, "local-cost specified more than once%s",
+                             VTY_NEWLINE);
+                    return CMD_WARNING;
+                  }
+                if (argc <= 1)
+                  {
+                    vty_out (vty, "Missing parameter for local-cost%s",
+                             VTY_NEWLINE);
+                    return CMD_WARNING;
+                  }
+                ++argv, --argc;
+                arg_lnh_cost = *argv;
+              }
+          }
+        if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_vn, &vn_address)))
+          goto fail;
+        if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_un, &un_address)))
+          goto fail;
+        /* arg_prefix is optional if mac address is given */
+        if (arg_macaddr && !arg_prefix)
+          {
+            /*
+             * fake up a 0/32 or 0/128 prefix
+             */
+            switch (vn_address.addr_family)
+              {
+              case AF_INET:
+                arg_prefix = "0.0.0.0/32";
+                break;
+              case AF_INET6:
+                arg_prefix = "0::0/128";
+                break;
+              default:
+                vty_out (vty, "Internal error, unknown VN address family%s",
+                         VTY_NEWLINE);
+                return CMD_WARNING;
+              }
+          }
+        if (!str2prefix (arg_prefix, &pfx))
+          {
+            vty_out (vty, "Malformed prefix \"%s\"%s", arg_prefix,
+                     VTY_NEWLINE);
+            goto fail;
+          }
+        if (pfx.family != AF_INET
+            && pfx.family != AF_INET6)
+          {
+            vty_out (vty, "prefix \"%s\" has invalid address family%s",
+                     arg_prefix, VTY_NEWLINE);
+            goto fail;
+          }
+        memset (optary, 0, sizeof (optary));
+        if (arg_cost)
+          {
+            endptr = NULL;
+            cost = strtoul (arg_cost, &endptr, 10);
+            if (*endptr != '\0' || cost > 255)
+              {
+                vty_out (vty, "%% Invalid %s value%s", "cost", VTY_NEWLINE);
+                goto fail;
+              }
+          }
+        else
+          {
+            cost = 255;
+          }
+        if (arg_lifetime)
+          {
+            if (!strcmp (arg_lifetime, "infinite"))
+              {
+                lifetime = RFAPI_INFINITE_LIFETIME;
+              }
+            else
+              {
+                endptr = NULL;
+                lifetime = strtoul (arg_lifetime, &endptr, 10);
+                if (*endptr != '\0')
+                  {
+                    vty_out (vty, "%% Invalid %s value%s", "lifetime",
+                             VTY_NEWLINE);
+                    goto fail;
+                  }
+              }
+          }
+        else
+          {
+            lifetime = RFAPI_INFINITE_LIFETIME;  /* default infinite */
+          }
+        if (arg_lnh_cost)
+          {
+            if (!arg_lnh)
+              {
+                vty_out (vty,
+                         "%% %s may only be specified with local-next-hop%s",
+                         "local-cost", VTY_NEWLINE);
+                goto fail;
+              }
+            endptr = NULL;
+            lnh_cost = strtoul (arg_lnh_cost, &endptr, 10);
+            if (*endptr != '\0' || lnh_cost > 255)
+              {
+                vty_out (vty, "%% Invalid %s value%s", "local-cost",
+                         VTY_NEWLINE);
+                goto fail;
+              }
+          }
+        else
+          {
+            lnh_cost = 255;
+          }
+        if (arg_lnh)
+          {
+            if (!arg_prefix)
+              {
+                vty_out (vty, "%% %s may only be specified with prefix%s",
+                         "local-next-hop", VTY_NEWLINE);
+                goto fail;
+              }
+            if ((rc = rfapiCliGetPrefixAddr (vty, arg_lnh,
+                                             &optary[opt_next].v.
+                                             local_nexthop.addr)))
+              {
+                goto fail;
+              }
+            optary[opt_next].v.local_nexthop.cost = lnh_cost;
+            optary[opt_next].type = RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP;
+            if (opt_next)
+              {
+                optary[opt_next - 1].next = optary + opt_next;
+              }
+            else
+              {
+                opt = optary;
+              }
+            ++opt_next;
+          }
+        if (arg_vni && !arg_macaddr)
+          {
+            vty_out (vty, "%% %s may only be specified with mac address%s",
+                     "virtual-network-identifier", VTY_NEWLINE);
+            goto fail;
+          }
+        if (arg_macaddr)
+          {
+            if (!arg_vni)
+              {
+                vty_out (vty,
+                         "Missing \"vni\" parameter (mandatory with mac)%s",
+                         VTY_NEWLINE);
+                return CMD_WARNING;
+              }
+            VTY_GET_INTEGER ("Logical Network ID",
+                             optary[opt_next].v.l2addr.logical_net_id,
+                             arg_vni);
+            if ((rc = rfapiStr2EthAddr (arg_macaddr,
+                                        &optary[opt_next].v.l2addr.macaddr)))
+              {
+                vty_out (vty, "Invalid %s value%s", "mac address",
+                         VTY_NEWLINE);
+                goto fail;
+              }
+            /* TBD label, NVE ID */
+            optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR;
+            if (opt_next)
+              {
+                optary[opt_next - 1].next = optary + opt_next;
+              }
+            else
+              {
+                opt = optary;
+              }
+            ++opt_next;
+          }
+        zlog_debug
+          ("%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s",
+           __func__, arg_vn, arg_un, arg_prefix,
+           (arg_cost ? arg_cost : "NULL"),
+           (arg_lifetime ? arg_lifetime : "NULL"),
+           (arg_lnh ? arg_lnh : "NULL"));
+        rfapiQprefix2Rprefix (&pfx, &rpfx);
+        rpfx.cost = cost & 255;
+        /* look up rf descriptor, call open if it doesn't exist  */
+        rc =
+          rfapi_find_rfd (bgp, &vn_address, &un_address,
+                          (struct rfapi_descriptor **) &rfd);
+        if (rc)
+          {
+            if (ENOENT == rc)
+              {
+                struct rfapi_un_option uo;
+                /*
+                 * flag descriptor as provisionally opened for static route
+                 * registration so that we can fix up the other parameters
+                 * when the real open comes along
+                 */
+                memset (&uo, 0, sizeof (uo));
+                uo.type = RFAPI_UN_OPTION_TYPE_PROVISIONAL;
+                rc = rfapi_open (rfapi_get_rfp_start_val_by_bgp (bgp), &vn_address, &un_address, &uo,    /* flags */
+                                 NULL, NULL,     /* no userdata */
+                                 &rfd);
+                if (rc)
+                  {
+                    vty_out (vty, "Can't open session for this NVE: %s%s",
+                             rfapi_error_str (rc), VTY_NEWLINE);
+                    rc = CMD_WARNING;
+                    goto fail;
+                  }
+              }
+            else
+              {
+                vty_out (vty, "Can't find session for this NVE: %s%s",
+                         rfapi_error_str (rc), VTY_NEWLINE);
+                goto fail;
+              }
+          }
+        rc =
+          rfapi_register (rfd, &rpfx, lifetime, NULL, opt, RFAPI_REGISTER_ADD);
+        if (!rc)
+          {
+            struct rfapi_next_hop_entry *head = NULL;
+            struct rfapi_next_hop_entry *tail = NULL;
+            struct rfapi_vn_option *vn_opt_new;
+            zlog_debug ("%s: rfapi_register succeeded, returning 0", __func__);
+            if (h->rfp_methods.local_cb)
+              {
+                struct rfapi_descriptor *r = (struct rfapi_descriptor *) rfd;
+                vn_opt_new = rfapi_vn_options_dup (opt);
+                rfapiAddDeleteLocalRfpPrefix (&r->un_addr, &r->vn_addr, &rpfx,
+                                              1, lifetime, vn_opt_new, &head,
+                                              &tail);
+                if (head)
+                  {
+                    h->flags |= RFAPI_INCALLBACK;
+                    (*h->rfp_methods.local_cb) (head, r->cookie);
+                    h->flags &= ~RFAPI_INCALLBACK;
+                  }
+                head = tail = NULL;
+              }
+            return 0;
+          }
+        zlog_debug ("%s: rfapi_register failed", __func__);
+        vty_out (vty, "%s", VTY_NEWLINE);
+        vty_out (vty, "Registration failed.%s", VTY_NEWLINE);
+        vty_out (vty,
+                 "Confirm that either the VN or UN address matches a configured NVE group.%s",
+                 VTY_NEWLINE);
+        return CMD_WARNING;
+      fail:
+        zlog_debug ("%s: fail, rc=%d", __func__, rc);
+        return rc;
+ }
+ /************************************************************************
+  *            Add prefix With .LNH_OPTIONS
+  ************************************************************************/
+ DEFUN (add_vnc_prefix_cost_life_lnh,
+        add_vnc_prefix_cost_life_lnh_cmd,
 -       "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295> cost <0-255> .LNH_OPTIONS",
++       "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295) .LNH_OPTIONS",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Administrative cost   [default: 255]\n"
+        "Administrative cost\n"
+        "Registration lifetime [default: infinite]\n"
+        "Lifetime value in seconds\n"
+        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[0], argv[1], argv[2], argv[3], argv[4],
+                        /* mac vni */
+                        NULL, NULL, argc, argv);
+ }
+ DEFUN (add_vnc_prefix_life_cost_lnh,
+        add_vnc_prefix_life_cost_lnh_cmd,
 -       "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255> .LNH_OPTIONS",
++       "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) cost (0-255) .LNH_OPTIONS",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Registration lifetime [default: infinite]\n"
+        "Lifetime value in seconds\n"
+        "Administrative cost   [default: 255]\n"
+        "Administrative cost\n"
+        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[0], argv[1], argv[2], argv[4], argv[3],
+                        /* mac vni */
+                        NULL, NULL, argc, argv);
+ }
+ DEFUN (add_vnc_prefix_cost_lnh,
+        add_vnc_prefix_cost_lnh_cmd,
 -       "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295> .LNH_OPTIONS",
++       "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) .LNH_OPTIONS",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Administrative cost   [default: 255]\n"
+        "Administrative cost\n"
+        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[0], argv[1], argv[2], argv[3], NULL,
+                        /* mac vni */
+                        NULL, NULL, argc, argv);
+ }
+ DEFUN (add_vnc_prefix_life_lnh,
+        add_vnc_prefix_life_lnh_cmd,
 -       "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) .LNH_OPTIONS",
++       "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) .LNH_OPTIONS",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Registration lifetime [default: infinite]\n"
+        "Lifetime value in seconds\n"
+        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[0], argv[1], argv[2], NULL, argv[3],
+                        /* mac vni */
+                        NULL, NULL, argc, argv);
+ }
+ DEFUN (add_vnc_prefix_lnh,
+        add_vnc_prefix_lnh_cmd,
 -       "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255> lifetime <1-4294967295>",
++       "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> .LNH_OPTIONS",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[0], argv[1], argv[2], NULL, NULL,
+                        /* mac vni */
+                        NULL, NULL, argc, argv);
+ }
+ /************************************************************************
+  *            Add prefix Without .LNH_OPTIONS
+  ************************************************************************/
+ DEFUN (add_vnc_prefix_cost_life,
+        add_vnc_prefix_cost_life_cmd,
 -       "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295> cost <0-255>",
++       "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295)",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Administrative cost   [default: 255]\n"
+        "Administrative cost\n"
+        "Registration lifetime [default: infinite]\n"
+        "Lifetime value in seconds\n"
+        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[0], argv[1], argv[2], argv[3], argv[4],
+                        /* mac vni */
+                        NULL, NULL, 0, NULL);
+ }
+ DEFUN (add_vnc_prefix_life_cost,
+        add_vnc_prefix_life_cost_cmd,
 -       "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255>",
++       "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) cost (0-255)",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Registration lifetime [default: infinite]\n"
+        "Lifetime value in seconds\n"
+        "Administrative cost   [default: 255]\n"
+        "Administrative cost\n"
+        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[0], argv[1], argv[2], argv[4], argv[3],
+                        /* mac vni */
+                        NULL, NULL, 0, NULL);
+ }
+ DEFUN (add_vnc_prefix_cost,
+        add_vnc_prefix_cost_cmd,
 -       "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295>",
++       "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255)",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Administrative cost   [default: 255]\n"
+        "Administrative cost\n"
+        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[0], argv[1], argv[2], argv[3], NULL,
+                        /* mac vni */
+                        NULL, NULL, 0, NULL);
+ }
+ DEFUN (add_vnc_prefix_life,
+        add_vnc_prefix_life_cmd,
 -       "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X)",
++       "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295)",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Registration lifetime [default: infinite]\n"
+        "Lifetime value in seconds\n"
+        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[0], argv[1], argv[2], NULL, argv[3],
+                        /* mac vni */
+                        NULL, NULL, 0, NULL);
+ }
+ DEFUN (add_vnc_prefix,
+        add_vnc_prefix_cmd,
 -       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M) cost <0-255> lifetime <1-4294967295>",
++       "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[0], argv[1], argv[2], NULL, NULL,
+                        /* mac vni */
+                        NULL, NULL, 0, NULL);
+ }
+ /************************************************************************
+  *                    Mac address registrations
+  ************************************************************************/
+ DEFUN (add_vnc_mac_vni_prefix_cost_life,
+        add_vnc_mac_vni_prefix_cost_life_cmd,
 -       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M) lifetime <1-4294967295>",
++       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> cost (0-255) lifetime (1-4294967295)",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify mac address infomation\n"
+        "MAC address\n"
+        "Virtual Network Identifier follows\n"
+        "Virtual Network Identifier\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "Administrative cost   [default: 255]\n"
+        "Administrative cost\n"
+        "Registration lifetime [default: infinite]\n"
+        "Lifetime value in seconds\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[4], argv[2], argv[3], argv[5], argv[6],
+                        /* mac vni */
+                        argv[0], argv[1], 0, NULL);
+ }
+ DEFUN (add_vnc_mac_vni_prefix_life,
+        add_vnc_mac_vni_prefix_life_cmd,
 -       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M) cost <0-255>",
++       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime (1-4294967295)",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify mac address infomation\n"
+        "MAC address\n"
+        "Virtual Network Identifier follows\n"
+        "Virtual Network Identifier\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "Registration lifetime [default: infinite]\n"
+        "Lifetime value in seconds\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[4], argv[2], argv[3], NULL, argv[5],
+                        /* mac vni */
+                        argv[0], argv[1], 0, NULL);
+ }
+ DEFUN (add_vnc_mac_vni_prefix_cost,
+        add_vnc_mac_vni_prefix_cost_cmd,
 -       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M)",
++       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> cost (0-255)",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify mac address infomation\n"
+        "MAC address\n"
+        "Virtual Network Identifier follows\n"
+        "Virtual Network Identifier\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "Administrative cost   [default: 255]\n" "Administrative cost\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[4], argv[2], argv[3], argv[5], NULL,
+                        /* mac vni */
+                        argv[0], argv[1], 0, NULL);
+ }
+ DEFUN (add_vnc_mac_vni_prefix,
+        add_vnc_mac_vni_prefix_cmd,
 -       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255> lifetime <1-4294967295>",
++       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M>",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify mac address infomation\n"
+        "MAC address\n"
+        "Virtual Network Identifier follows\n"
+        "Virtual Network Identifier\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Add/modify prefix related infomation\n"
+        "IPv4 prefix\n" "IPv6 prefix\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, argv[4], argv[2], argv[3], NULL, NULL,
+                        /* mac vni */
+                        argv[0], argv[1], 0, NULL);
+ }
+ DEFUN (add_vnc_mac_vni_cost_life,
+        add_vnc_mac_vni_cost_life_cmd,
 -       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255>",
++       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295)",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify mac address infomation\n"
+        "MAC address\n"
+        "Virtual Network Identifier follows\n"
+        "Virtual Network Identifier\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Administrative cost   [default: 255]\n"
+        "Administrative cost\n"
+        "Registration lifetime [default: infinite]\n"
+        "Lifetime value in seconds\n")
+ {
+   /*                       pfx      vn       un       cost     life */
+   return register_add (vty, NULL, argv[2], argv[3], argv[4], argv[5],
+                        /* mac vni */
+                        argv[0], argv[1], 0, NULL);
+ }
+ DEFUN (add_vnc_mac_vni_cost,
+        add_vnc_mac_vni_cost_cmd,
 -       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295>",
++       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255)",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify mac address infomation\n"
+        "MAC address\n"
+        "Virtual Network Identifier follows\n"
+        "Virtual Network Identifier\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Administrative cost   [default: 255]\n" "Administrative cost\n")
+ {
+   /*                       pfx      vn       un    cost     life */
+   return register_add (vty, NULL, argv[2], argv[3], argv[4], NULL,
+                        /* mac vni */
+                        argv[0], argv[1], 0, NULL);
+ }
+ DEFUN (add_vnc_mac_vni_life,
+        add_vnc_mac_vni_life_cmd,
 -       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X)",
++       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295)",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify mac address infomation\n"
+        "MAC address\n"
+        "Virtual Network Identifier follows\n"
+        "Virtual Network Identifier\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Registration lifetime [default: infinite]\n"
+        "Lifetime value in seconds\n")
+ {
+   /*                       pfx      vn       un    cost  life */
+   return register_add (vty, NULL, argv[2], argv[3], NULL, argv[4],
+                        /* mac vni */
+                        argv[0], argv[1], 0, NULL);
+ }
+ DEFUN (add_vnc_mac_vni,
+        add_vnc_mac_vni_cmd,
 -       "clear vnc nve vn (*|A.B.C.D|X:X::X:X) un (*|A.B.C.D|X:X::X:X)",
++       "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
+        "Add registration\n"
+        "VNC Information\n"
+        "Add/modify mac address infomation\n"
+        "MAC address\n"
+        "Virtual Network Identifier follows\n"
+        "Virtual Network Identifier\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n" "UN IPv6 interface address\n")
+ {
+   /*                       pfx      vn       un    cost  life */
+   return register_add (vty, NULL, argv[2], argv[3], NULL, NULL,
+                        /* mac vni */
+                        argv[0], argv[1], 0, NULL);
+ }
+ /************************************************************************
+  *                    Delete prefix
+  ************************************************************************/
+ struct rfapi_local_reg_delete_arg
+ {
+   /*
+    * match parameters
+    */
+   struct rfapi_ip_addr        un_address;     /* AF==0: wildcard */
+   struct rfapi_ip_addr        vn_address;     /* AF==0: wildcard */
+   struct prefix               prefix;         /* AF==0: wildcard */
+   struct rfapi_l2address_option_match l2o;
+   /*
+    * result parameters
+    */
+   struct vty          *vty;
+   uint32_t            reg_count;
+   uint32_t            pfx_count;
+   uint32_t            query_count;
+   uint32_t            failed_pfx_count;
+   uint32_t            nve_count;
+   struct skiplist     *nves;
+   uint32_t            remote_active_nve_count;
+   uint32_t            remote_active_pfx_count;
+   uint32_t            remote_holddown_nve_count;
+   uint32_t            remote_holddown_pfx_count;
+ };
+ struct nve_addr
+ {
+   struct rfapi_ip_addr                        vn;
+   struct rfapi_ip_addr                        un;
+   struct rfapi_descriptor             *rfd;
+   struct rfapi_local_reg_delete_arg   *cda;
+ };
+ static void
+ nve_addr_free (void *hap)
+ {
+   ((struct nve_addr *) hap)->cda->nve_count += 1;
+   XFREE (MTYPE_RFAPI_NVE_ADDR, hap);
+ }
+ static int
+ nve_addr_cmp (void *k1, void *k2)
+ {
+   struct nve_addr *a = (struct nve_addr *) k1;
+   struct nve_addr *b = (struct nve_addr *) k2;
+   int ret = 0;
+   if (!a || !b)
+     {
+       return (a - b);
+     }
+   if (a->un.addr_family != b->un.addr_family)
+     {
+       return (a->un.addr_family - b->un.addr_family);
+     }
+   if (a->vn.addr_family != b->vn.addr_family)
+     {
+       return (a->vn.addr_family - b->vn.addr_family);
+     }
+   if (a->un.addr_family == AF_INET)
+     {
+       ret = IPV4_ADDR_CMP (&a->un.addr.v4, &b->un.addr.v4);
+       if (ret != 0)
+         {
+           return ret;
+         }
+     }
+   else if (a->un.addr_family == AF_INET6)
+     {
+       ret = IPV6_ADDR_CMP (&a->un.addr.v6, &b->un.addr.v6);
+       if (ret != 0)
+         {
+           return ret;
+         }
+     }
+   else
+     {
+       assert (0);
+     }
+   if (a->vn.addr_family == AF_INET)
+     {
+       ret = IPV4_ADDR_CMP (&a->vn.addr.v4, &b->vn.addr.v4);
+       if (ret != 0)
+         return ret;
+     }
+   else if (a->vn.addr_family == AF_INET6)
+     {
+       ret = IPV6_ADDR_CMP (&a->vn.addr.v6, &b->vn.addr.v6);
+       if (ret == 0)
+         {
+           return ret;
+         }
+     }
+   else
+     {
+       assert (0);
+     }
+   return 0;
+ }
+ static int
+ parse_deleter_args (
+   struct vty                          *vty,
+   const char                          *arg_prefix,
+   const char                          *arg_vn,
+   const char                          *arg_un,
+   const char                          *arg_l2addr,
+   const char                          *arg_vni,
+   struct rfapi_local_reg_delete_arg   *rcdarg)
+ {
+   int rc = CMD_WARNING;
+     memset (rcdarg, 0, sizeof (struct rfapi_local_reg_delete_arg));
+   if (arg_vn && strcmp (arg_vn, "*"))
+     {
+       if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_vn, &rcdarg->vn_address)))
+         return rc;
+     }
+   if (arg_un && strcmp (arg_un, "*"))
+     {
+       if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_un, &rcdarg->un_address)))
+         return rc;
+     }
+   if (arg_prefix && strcmp (arg_prefix, "*"))
+     {
+       if (!str2prefix (arg_prefix, &rcdarg->prefix))
+         {
+           vty_out (vty, "Malformed prefix \"%s\"%s", arg_prefix, VTY_NEWLINE);
+           return rc;
+         }
+     }
+   if (arg_l2addr)
+     {
+       if (!arg_vni)
+         {
+           vty_out (vty, "Missing VNI%s", VTY_NEWLINE);
+           return rc;
+         }
+       if (strcmp (arg_l2addr, "*"))
+         {
+           if ((rc = rfapiStr2EthAddr (arg_l2addr, &rcdarg->l2o.o.macaddr)))
+             {
+               vty_out (vty, "Malformed L2 Address \"%s\"%s",
+                        arg_l2addr, VTY_NEWLINE);
+               return rc;
+             }
+           rcdarg->l2o.flags |= RFAPI_L2O_MACADDR;
+         }
+       if (strcmp (arg_vni, "*"))
+         {
+           VTY_GET_INTEGER ("Logical Network ID",
+                            rcdarg->l2o.o.logical_net_id, arg_vni);
+           rcdarg->l2o.flags |= RFAPI_L2O_LNI;
+         }
+     }
+   return 0;
+ }
+ static void
+ record_nve_in_cda_list (
+   struct rfapi_local_reg_delete_arg   *cda,
+   struct rfapi_ip_addr                        *un_address,
+   struct rfapi_ip_addr                        *vn_address,
+   struct rfapi_descriptor             *rfd)
+ {
+   struct nve_addr ha;
+   struct nve_addr *hap;
+     memset (&ha, 0, sizeof (ha));
+     ha.un = *un_address;
+     ha.vn = *vn_address;
+     ha.rfd = rfd;
+   if (!cda->nves)
+       cda->nves = skiplist_new (0, nve_addr_cmp, nve_addr_free);
+   if (skiplist_search (cda->nves, &ha, (void *) &hap))
+     {
+       hap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, sizeof (struct nve_addr));
+         assert (hap);
+         ha.cda = cda;
+       * hap = ha;
+         skiplist_insert (cda->nves, hap, hap);
+     }
+ }
+ static void
+ clear_vnc_responses (struct rfapi_local_reg_delete_arg *cda)
+ {
+   struct rfapi *h;
+   struct rfapi_descriptor *rfd;
+   int query_count = 0;
+   struct listnode *node;
+   struct bgp *bgp_default = bgp_get_default ();
+   if (cda->vn_address.addr_family && cda->un_address.addr_family)
+     {
+       /*
+        * Single nve case
+        */
+       if (rfapi_find_rfd
+           (bgp_default, &cda->vn_address, &cda->un_address, &rfd))
+         return;
+       rfapiRibClear (rfd);
+       rfapi_query_done_all (rfd, &query_count);
+       cda->query_count += query_count;
+       /*
+        * Track unique nves seen
+        */
+       record_nve_in_cda_list (cda, &rfd->un_addr, &rfd->vn_addr, rfd);
+       return;
+     }
+   /*
+    * wildcard case
+    */
+   if (!bgp_default)
+       return;                   /* ENXIO */
+   h = bgp_default->rfapi;
+   if (!h)
+     return;                     /* ENXIO */
+   for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
+     {
+       /*
+        * match un, vn addresses of NVEs
+        */
+       if (cda->un_address.addr_family &&
+           rfapi_ip_addr_cmp (&cda->un_address, &rfd->un_addr))
+         {
+           continue;
+         }
+       if (cda->vn_address.addr_family &&
+           rfapi_ip_addr_cmp (&cda->vn_address, &rfd->vn_addr))
+         {
+           continue;
+         }
+       rfapiRibClear (rfd);
+       rfapi_query_done_all (rfd, &query_count);
+       cda->query_count += query_count;
+       /*
+        * Track unique nves seen
+        */
+       record_nve_in_cda_list (cda, &rfd->un_addr, &rfd->vn_addr, rfd);
+     }
+ }
+ /*
+  * TBD need to count deleted prefixes and nves?
+  *
+  * ENXIO      BGP or VNC not configured
+  */
+ static int
+ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
+ {
+   struct rfapi_ip_addr *pUn;    /* NULL = wildcard */
+   struct rfapi_ip_addr *pVn;    /* NULL = wildcard */
+   struct prefix *pPrefix;       /* NULL = wildcard */
+   struct rfapi *h;
+   struct listnode *node;
+   struct rfapi_descriptor *rfd;
+   struct rfapi_ip_prefix rprefix;
+   struct bgp *bgp_default = bgp_get_default ();
+   struct rfapi_next_hop_entry *head = NULL;
+   struct rfapi_next_hop_entry *tail = NULL;
+   struct rfapi_cfg *rfapi_cfg;
+ #if DEBUG_L2_EXTRA
+     zlog_debug ("%s: entry", __func__);
+ #endif
+   if (!bgp_default)
+       return ENXIO;
+     pUn = (cda->un_address.addr_family ? &cda->un_address : NULL);
+     pVn = (cda->vn_address.addr_family ? &cda->vn_address : NULL);
+     pPrefix = (cda->prefix.family ? &cda->prefix : NULL);
+     h = bgp_default->rfapi;
+     rfapi_cfg = bgp_default->rfapi_cfg;
+   if (!h || !rfapi_cfg)
+       return ENXIO;
+   if (pPrefix)
+     {
+       rfapiQprefix2Rprefix (pPrefix, &rprefix);
+     }
+ #if DEBUG_L2_EXTRA
+   zlog_debug ("%s: starting descriptor loop", __func__);
+ #endif
+   for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
+     {
+       struct rfapi_adb *adb;
+       int rc;
+       int deleted_from_this_nve;
+       struct nve_addr ha;
+       struct nve_addr *hap;
+ #if DEBUG_L2_EXTRA
+       zlog_debug ("%s: rfd=%p", __func__, rfd);
+ #endif
+       /*
+        * match un, vn addresses of NVEs
+        */
+       if (pUn && (rfapi_ip_addr_cmp (pUn, &rfd->un_addr)))
+         continue;
+       if (pVn && (rfapi_ip_addr_cmp (pVn, &rfd->vn_addr)))
+         continue;
+ #if DEBUG_L2_EXTRA
+       zlog_debug ("%s: un, vn match", __func__);
+ #endif
+       /*
+        * match prefix
+        */
+       deleted_from_this_nve = 0;
+       {
+         struct skiplist *sl;
+         struct rfapi_ip_prefix rp;
+         void *cursor;
+         struct list *adb_delete_list;
+         /*
+          * The advertisements are stored in a skiplist. Withdrawing
+          * the registration deletes the advertisement from the
+          * skiplist, which we can't do while iterating over that
+          * same skiplist using the current skiplist API.
+          *
+          * Strategy: iterate over the skiplist and build another
+          * list containing only the matching ADBs. Then delete
+          * _everything_ in that second list (which can be done
+          * using either skiplists or quagga linklists).
+          */
+         adb_delete_list = list_new ();
+         /*
+          * Advertised IP prefixes (not 0/32 or 0/128)
+          */
+         sl = rfd->advertised.ipN_by_prefix;
+         for (cursor = NULL,
+              rc = skiplist_next (sl, NULL, (void **) &adb, &cursor);
+              !rc; rc = skiplist_next (sl, NULL, (void **) &adb, &cursor))
+           {
+             if (pPrefix)
+               {
+                 if (!prefix_same (pPrefix, &adb->prefix_ip))
+                   {
+ #if DEBUG_L2_EXTRA
+                     zlog_debug ("%s: adb=%p, prefix doesn't match, skipping",
+                                 __func__, adb);
+ #endif
+                     continue;
+                   }
+               }
+             if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR))
+               {
+                 if (memcmp
+                     (cda->l2o.o.macaddr.octet,
+                      adb->prefix_eth.u.prefix_eth.octet, ETHER_ADDR_LEN))
+                   {
+ #if DEBUG_L2_EXTRA
+                     zlog_debug ("%s: adb=%p, macaddr doesn't match, skipping",
+                                 __func__, adb);
+ #endif
+                     continue;
+                   }
+               }
+             if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_LNI))
+               {
+                 if (cda->l2o.o.logical_net_id != adb->l2o.logical_net_id)
+                   {
+ #if DEBUG_L2_EXTRA
+                     zlog_debug ("%s: adb=%p, LNI doesn't match, skipping",
+                                 __func__, adb);
+ #endif
+                     continue;
+                   }
+               }
+ #if DEBUG_L2_EXTRA
+             zlog_debug ("%s: ipN adding adb %p to delete list", __func__,
+                         adb);
+ #endif
+             listnode_add (adb_delete_list, adb);
+           }
+         struct listnode *node;
+         for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb))
+           {
+             struct rfapi_vn_option vn1;
+             struct rfapi_vn_option vn2;
+             struct rfapi_vn_option *pVn;
+             int this_advertisement_prefix_count;
+             this_advertisement_prefix_count = 1;
+             rfapiQprefix2Rprefix (&adb->prefix_ip, &rp);
+             /* if mac addr present in advert,  make l2o vn option */
+             if (adb->prefix_eth.family == AF_ETHERNET)
+               {
+                 memset (&vn1, 0, sizeof (vn1));
+                 memset (&vn2, 0, sizeof (vn2));
+                 vn1.type = RFAPI_VN_OPTION_TYPE_L2ADDR;
+                 vn1.v.l2addr.macaddr = adb->prefix_eth.u.prefix_eth;
+                 /*
+                  * use saved RD value instead of trying to invert
+                  * complex L2-style RD computation in rfapi_register()
+                  */
+                 vn2.type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD;
+                 vn2.v.internal_rd = adb->prd;
+                 vn1.next = &vn2;
+                 pVn = &vn1;
+                 ++this_advertisement_prefix_count;
+               }
+             else
+               {
+                 pVn = NULL;
+               }
+ #if DEBUG_L2_EXTRA
+             zlog_debug ("%s: ipN killing reg from adb %p ", __func__, adb);
+ #endif
+             rc = rfapi_register (rfd, &rp, 0, NULL, pVn, RFAPI_REGISTER_KILL);
+             if (!rc)
+               {
+                 cda->pfx_count += this_advertisement_prefix_count;
+                 cda->reg_count += 1;
+                 deleted_from_this_nve = 1;
+               }
+             if (h->rfp_methods.local_cb)
+               {
+                 rfapiAddDeleteLocalRfpPrefix (&rfd->un_addr, &rfd->vn_addr,
+                                               &rp, 0, 0, NULL, &head, &tail);
+               }
+           }
+         list_delete_all_node (adb_delete_list);
+         if (!(pPrefix && !RFAPI_0_PREFIX (pPrefix)))
+           {
+             void *cursor;
+             /*
+              * Caller didn't specify a prefix, or specified (0/32 or 0/128)
+              */
+             /*
+              * Advertised 0/32 and 0/128 (indexed by ethernet address)
+              */
+             sl = rfd->advertised.ip0_by_ether;
+             for (cursor = NULL,
+                  rc = skiplist_next (sl, NULL, (void **) &adb, &cursor);
+                  !rc; rc = skiplist_next (sl, NULL, (void **) &adb, &cursor))
+               {
+                 if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR))
+                   {
+                     if (memcmp (cda->l2o.o.macaddr.octet,
+                                 adb->prefix_eth.u.prefix_eth.octet,
+                                 ETHER_ADDR_LEN))
+                       {
+                         continue;
+                       }
+                   }
+                 if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_LNI))
+                   {
+                     if (cda->l2o.o.logical_net_id != adb->l2o.logical_net_id)
+                       {
+                         continue;
+                       }
+                   }
+ #if DEBUG_L2_EXTRA
+                 zlog_debug ("%s: ip0 adding adb %p to delete list",
+                             __func__, adb);
+ #endif
+                 listnode_add (adb_delete_list, adb);
+               }
+             for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb))
+               {
+                 struct rfapi_vn_option vn;
+                 rfapiQprefix2Rprefix (&adb->prefix_ip, &rp);
+                 memset (&vn, 0, sizeof (vn));
+                 vn.type = RFAPI_VN_OPTION_TYPE_L2ADDR;
+                 vn.v.l2addr = adb->l2o;
+ #if DEBUG_L2_EXTRA
+                 zlog_debug ("%s: ip0 killing reg from adb %p ",
+                             __func__, adb);
+ #endif
+                 rc = rfapi_register (rfd, &rp, 0, NULL, &vn,
+                                      RFAPI_REGISTER_KILL);
+                 if (!rc)
+                   {
+                     cda->pfx_count += 1;
+                     cda->reg_count += 1;
+                     deleted_from_this_nve = 1;
+                   }
+                 if (h->rfp_methods.local_cb)
+                   {
+                     struct rfapi_vn_option *vn_opt_new;
+                     vn_opt_new = rfapi_vn_options_dup (&vn);
+                     rfapiAddDeleteLocalRfpPrefix (&rfd->un_addr,
+                                                   &rfd->vn_addr, &rp, 0, 0,
+                                                   vn_opt_new, &head, &tail);
+                   }
+               }
+             list_delete_all_node (adb_delete_list);
+           }
+         list_delete (adb_delete_list);
+       }
+       if (head)
+         {                       /* should not be set if (NULL == rfapi_cfg->local_cb) */
+           h->flags |= RFAPI_INCALLBACK;
+           (*h->rfp_methods.local_cb) (head, rfd->cookie);
+           h->flags &= ~RFAPI_INCALLBACK;
+           head = tail = NULL;
+         }
+       if (deleted_from_this_nve)
+         {
+           /*
+            * track unique NVEs seen
+            */
+           memset (&ha, 0, sizeof (ha));
+           ha.un = rfd->un_addr;
+           ha.vn = rfd->vn_addr;
+           if (!cda->nves)
+             cda->nves = skiplist_new (0, nve_addr_cmp, nve_addr_free);
+           if (skiplist_search (cda->nves, &ha, (void **) &hap))
+             {
+               hap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, sizeof (struct nve_addr));
+               assert (hap);
+               ha.cda = cda;
+               *hap = ha;
+               skiplist_insert (cda->nves, hap, hap);
+             }
+         }
+     }
+   return 0;
+ }
+ /*
+  * clear_vnc_prefix
+  *
+  * Deletes local and remote prefixes that match
+  */
+ static void
+ clear_vnc_prefix (struct rfapi_local_reg_delete_arg *cda)
+ {
+   struct prefix pfx_un;
+   struct prefix pfx_vn;
+   struct prefix *pUN = NULL;
+   struct prefix *pVN = NULL;
+   struct prefix *pPrefix = NULL;
+   /*
+    * Delete matching remote prefixes in holddown
+    */
+   if (cda->vn_address.addr_family)
+     {
+       if (!rfapiRaddr2Qprefix (&cda->vn_address, &pfx_vn))
+         pVN = &pfx_vn;
+     }
+   if (cda->un_address.addr_family)
+     {
+       if (!rfapiRaddr2Qprefix (&cda->un_address, &pfx_un))
+         pUN = &pfx_un;
+     }
+   if (cda->prefix.family)
+     {
+       pPrefix = &cda->prefix;
+     }
+   rfapiDeleteRemotePrefixes (pUN, pVN, pPrefix,
+                              0, 1, &cda->remote_active_pfx_count,
+                              &cda->remote_active_nve_count,
+                              &cda->remote_holddown_pfx_count,
+                              &cda->remote_holddown_nve_count);
+   /*
+    * Now do local prefixes
+    */
+   rfapiDeleteLocalPrefixes (cda);
+ }
+ static void
+ print_cleared_stats (struct rfapi_local_reg_delete_arg *cda)
+ {
+   struct vty *vty = cda->vty;   /* for benefit of VTY_NEWLINE */
+   /* Our special element-deleting function counts nves */
+   if (cda->nves)
+     {
+       skiplist_free (cda->nves);
+       cda->nves = NULL;
+     }
+   if (cda->failed_pfx_count)
+       vty_out (vty, "Failed to delete %d prefixes%s",
+                cda->failed_pfx_count, VTY_NEWLINE);
+   /* left as "prefixes" even in single case for ease of machine parsing */
+   vty_out (vty,
+            "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs%s",
+            cda->reg_count, cda->pfx_count, cda->query_count, cda->nve_count,
+            VTY_NEWLINE);
+ /*
+  * We don't currently allow deletion of active remote prefixes from
+  * the command line
+  */
+   vty_out (vty, "[Holddown] Cleared %u prefixes from %u NVEs%s",
+            cda->remote_holddown_pfx_count, cda->remote_holddown_nve_count,
+            VTY_NEWLINE);
+ }
+ /* 
+  * Caller has already deleted registrations and queries for this/these
+  * NVEs. Now we just have to close their descriptors.
+  */
+ static void
+ clear_vnc_nve_closer (struct rfapi_local_reg_delete_arg *cda)
+ {
+   struct skiplist *sl = cda->nves;      /* contains affected NVEs */
+   struct nve_addr *pKey;
+   struct nve_addr *pValue;
+   void *cursor = NULL;
+   int rc;
+   if (!sl)
+       return;
+   for (rc = skiplist_next (sl, (void **) &pKey, (void **) &pValue, &cursor);
+        !rc;
+        rc = skiplist_next (sl, (void **) &pKey, (void **) &pValue, &cursor))
+     {
+       if (pValue->rfd)
+         {
+           ((struct rfapi_descriptor *) pValue->rfd)->flags |=
+             RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY;
+           rfapi_close (pValue->rfd);
+         }
+     }
+ }
+ DEFUN (clear_vnc_nve_all,
+        clear_vnc_nve_all_cmd,
+        "clear vnc nve *",
+        "clear\n"
+        "VNC Information\n" "Clear per NVE information\n" "For all NVEs\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   if ((rc = parse_deleter_args (vty, NULL, NULL, NULL, NULL, NULL, &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_responses (&cda);
+   clear_vnc_prefix (&cda);
+   clear_vnc_nve_closer (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_nve_vn_un,
+        clear_vnc_nve_vn_un_cmd,
 -       "clear vnc nve un (*|A.B.C.D|X:X::X:X) vn (*|A.B.C.D|X:X::X:X)",
++       "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear prefix registration infomation\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n" "UN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   if ((rc =
+        parse_deleter_args (vty, NULL, argv[0], argv[1], NULL, NULL, &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_responses (&cda);
+   clear_vnc_prefix (&cda);
+   clear_vnc_nve_closer (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_nve_un_vn,
+        clear_vnc_nve_un_vn_cmd,
 -       "clear vnc nve vn (*|A.B.C.D|X:X::X:X)",
++       "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear prefix registration infomation\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n" "VN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   if ((rc =
+        parse_deleter_args (vty, NULL, argv[1], argv[0], NULL, NULL, &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_responses (&cda);
+   clear_vnc_prefix (&cda);
+   clear_vnc_nve_closer (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_nve_vn,
+        clear_vnc_nve_vn_cmd,
 -       "clear vnc nve un (*|A.B.C.D|X:X::X:X)",
++       "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear prefix registration infomation\n"
+        "VN address of NVE\n"
+        "VN IPv4 interface address\n" "VN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   if ((rc = parse_deleter_args (vty, NULL, argv[0], NULL, NULL, NULL, &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_responses (&cda);
+   clear_vnc_prefix (&cda);
+   clear_vnc_nve_closer (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_nve_un,
+        clear_vnc_nve_un_cmd,
 -       "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) vn (*|A.B.C.D|X:X::X:X) un (*|A.B.C.D|X:X::X:X)",
++       "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear prefix registration infomation\n"
+        "UN address of NVE\n"
+        "UN IPv4 interface address\n" "UN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   if ((rc = parse_deleter_args (vty, NULL, NULL, argv[0], NULL, NULL, &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_responses (&cda);
+   clear_vnc_prefix (&cda);
+   clear_vnc_nve_closer (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ /*-------------------------------------------------
+  *            Clear VNC Prefix
+  *-------------------------------------------------*/
+ /*
+  * This function is defined in this file (rather than in rfp_registration.c)
+  * because here we have access to all the task handles.
+  */
+ DEFUN (clear_vnc_prefix_vn_un,
+        clear_vnc_prefix_vn_un_cmd,
 -       "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) un (*|A.B.C.D|X:X::X:X) vn (*|A.B.C.D|X:X::X:X)",
++       "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear prefix registration infomation\n"
+        "All prefixes\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "VN address of NVE\n"
+        "All VN addresses\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "All UN addresses\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   if ((rc =
+        parse_deleter_args (vty, argv[0], argv[1], argv[2], NULL, NULL, &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_prefix_un_vn,
+        clear_vnc_prefix_un_vn_cmd,
 -       "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) un (*|A.B.C.D|X:X::X:X)",
++       "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear prefix registration infomation\n"
+        "All prefixes\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "UN address of NVE\n"
+        "All UN addresses\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "VN address of NVE\n"
+        "All VN addresses\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   if ((rc =
+        parse_deleter_args (vty, argv[0], argv[2], argv[1], NULL, NULL, &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_prefix_un,
+        clear_vnc_prefix_un_cmd,
 -       "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) vn (*|A.B.C.D|X:X::X:X)",
++       "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear prefix registration infomation\n"
+        "All prefixes\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "UN address of NVE\n"
+        "All UN addresses\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   if ((rc =
+        parse_deleter_args (vty, argv[0], NULL, argv[1], NULL, NULL, &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_prefix_vn,
+        clear_vnc_prefix_vn_cmd,
 -       "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) *",
++       "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear prefix registration infomation\n"
+        "All prefixes\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "UN address of NVE\n"
+        "All VN addresses\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   if ((rc =
+        parse_deleter_args (vty, argv[0], argv[1], NULL, NULL, NULL, &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_prefix_all,
+        clear_vnc_prefix_all_cmd,
 -       "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) vn (*|A.B.C.D|X:X::X:X) un (*|A.B.C.D|X:X::X:X)",
++       "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
+        "clear\n"
+        "VNC Information\n"
+        "Clear prefix registration infomation\n"
+        "All prefixes\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n"
+        "From any NVE\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   if ((rc = parse_deleter_args (vty, argv[0], NULL, NULL, NULL, NULL, &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ /*-------------------------------------------------
+  *            Clear VNC MAC
+  *-------------------------------------------------*/
+ /*
+  * This function is defined in this file (rather than in rfp_registration.c)
+  * because here we have access to all the task handles.
+  */
+ DEFUN (clear_vnc_mac_vn_un,
+        clear_vnc_mac_vn_un_cmd,
 -       "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) un (*|A.B.C.D|X:X::X:X) vn (*|A.B.C.D|X:X::X:X)",
++       "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear mac registration infomation\n"
+        "All macs\n"
+        "MAC address\n"
+        "VNI keyword\n"
+        "Any virtual network identifier\n"
+        "Virtual network identifier\n"
+        "Virtual network identifier\n"
+        "VN address of NVE\n"
+        "All VN addresses\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "All UN addresses\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   /* pfx vn un L2 VNI */
+   if ((rc =
+        parse_deleter_args (vty, NULL, argv[2], argv[3], argv[0], argv[1],
+                            &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_mac_un_vn,
+        clear_vnc_mac_un_vn_cmd,
 -       "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) un (*|A.B.C.D|X:X::X:X)",
++       "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear mac registration infomation\n"
+        "All macs\n"
+        "MAC address\n"
+        "VNI keyword\n"
+        "Any virtual network identifier\n"
+        "Virtual network identifier\n"
+        "UN address of NVE\n"
+        "All UN addresses\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "VN address of NVE\n"
+        "All VN addresses\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   /* pfx vn un L2 VNI */
+   if ((rc =
+        parse_deleter_args (vty, NULL, argv[3], argv[2], argv[0], argv[1],
+                            &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_mac_un,
+        clear_vnc_mac_un_cmd,
 -       "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) vn (*|A.B.C.D|X:X::X:X)",
++       "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear mac registration infomation\n"
+        "All macs\n"
+        "MAC address\n"
+        "VNI keyword\n"
+        "Any virtual network identifier\n"
+        "Virtual network identifier\n"
+        "UN address of NVE\n"
+        "All UN addresses\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   /* pfx vn un L2 VNI */
+   if ((rc =
+        parse_deleter_args (vty, NULL, NULL, argv[2], argv[0], argv[1], &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_mac_vn,
+        clear_vnc_mac_vn_cmd,
 -       "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) *",
++       "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear mac registration infomation\n"
+        "All macs\n"
+        "MAC address\n"
+        "VNI keyword\n"
+        "Any virtual network identifier\n"
+        "Virtual network identifier\n"
+        "UN address of NVE\n"
+        "All VN addresses\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   /* pfx vn un L2 VNI */
+   if ((rc =
+        parse_deleter_args (vty, NULL, argv[2], NULL, argv[0], argv[1], &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_mac_all,
+        clear_vnc_mac_all_cmd,
 -       "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) vn (*|A.B.C.D|X:X::X:X) un (*|A.B.C.D|X:X::X:X) prefix (*|A.B.C.D/M|X:X::X:X/M)",
++       "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *",
+        "clear\n"
+        "VNC Information\n"
+        "Clear mac registration infomation\n"
+        "All macs\n"
+        "MAC address\n"
+        "VNI keyword\n"
+        "Any virtual network identifier\n"
+        "Virtual network identifier\n"
+        "From any NVE\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   /* pfx vn un L2 VNI */
+   if ((rc =
+        parse_deleter_args (vty, NULL, NULL, NULL, argv[0], argv[1], &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ /*-------------------------------------------------
+  *            Clear VNC MAC PREFIX
+  *-------------------------------------------------*/
+ DEFUN (clear_vnc_mac_vn_un_prefix,
+        clear_vnc_mac_vn_un_prefix_cmd,
 -       "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) un (*|A.B.C.D|X:X::X:X) vn (*|A.B.C.D|X:X::X:X) prefix (*|A.B.C.D/M|X:X::X:X/M) prefix (*|A.B.C.D/M|X:X::X:X/M)",
++       "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear mac registration infomation\n"
+        "All macs\n"
+        "MAC address\n"
+        "VNI keyword\n"
+        "Any virtual network identifier\n"
+        "Virtual network identifier\n"
+        "Virtual network identifier\n"
+        "VN address of NVE\n"
+        "All VN addresses\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n"
+        "UN address of NVE\n"
+        "All UN addresses\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "Clear prefix registration infomation\n"
+        "All prefixes\n"
+        "IPv4 prefix\n"
+        "IPv6 prefix\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   /* pfx vn un L2 VNI */
+   if ((rc =
+        parse_deleter_args (vty, argv[4], argv[2], argv[3], argv[0], argv[1],
+                            &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_mac_un_vn_prefix,
+        clear_vnc_mac_un_vn_prefix_cmd,
 -       "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) un (*|A.B.C.D|X:X::X:X) prefix (*|A.B.C.D/M|X:X::X:X/M)",
++       "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M> prefix <*|A.B.C.D/M|X:X::X:X/M>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear mac registration infomation\n"
+        "All macs\n"
+        "MAC address\n"
+        "VNI keyword\n"
+        "Any virtual network identifier\n"
+        "Virtual network identifier\n"
+        "UN address of NVE\n"
+        "All UN addresses\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n"
+        "VN address of NVE\n"
+        "All VN addresses\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   /* pfx vn un L2 VNI */
+   if ((rc =
+        parse_deleter_args (vty, argv[4], argv[3], argv[2], argv[0], argv[1],
+                            &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_mac_un_prefix,
+        clear_vnc_mac_un_prefix_cmd,
 -       "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) vn (*|A.B.C.D|X:X::X:X) prefix (*|A.B.C.D/M|X:X::X:X/M)",
++       "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear mac registration infomation\n"
+        "All macs\n"
+        "MAC address\n"
+        "VNI keyword\n"
+        "Any virtual network identifier\n"
+        "Virtual network identifier\n"
+        "UN address of NVE\n"
+        "All UN addresses\n"
+        "UN IPv4 interface address\n"
+        "UN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   /* pfx vn un L2 VNI */
+   if ((rc =
+        parse_deleter_args (vty, argv[3], NULL, argv[2], argv[0], argv[1],
+                            &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_mac_vn_prefix,
+        clear_vnc_mac_vn_prefix_cmd,
 -       "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) prefix (*|A.B.C.D/M|X:X::X:X/M)",
++       "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear mac registration infomation\n"
+        "All macs\n"
+        "MAC address\n"
+        "VNI keyword\n"
+        "Any virtual network identifier\n"
+        "Virtual network identifier\n"
+        "UN address of NVE\n"
+        "All VN addresses\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   /* pfx vn un L2 VNI */
+   if ((rc =
+        parse_deleter_args (vty, argv[3], argv[2], NULL, argv[0], argv[1],
+                            &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ DEFUN (clear_vnc_mac_all_prefix,
+        clear_vnc_mac_all_prefix_cmd,
 -       "show vnc nves (vn|un) (A.B.C.D|X:X::X:X)",
++       "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> prefix <*|A.B.C.D/M|X:X::X:X/M>",
+        "clear\n"
+        "VNC Information\n"
+        "Clear mac registration infomation\n"
+        "All macs\n"
+        "MAC address\n"
+        "VNI keyword\n"
+        "Any virtual network identifier\n"
+        "Virtual network identifier\n"
+        "UN address of NVE\n"
+        "All VN addresses\n"
+        "VN IPv4 interface address\n"
+        "VN IPv6 interface address\n")
+ {
+   struct rfapi_local_reg_delete_arg cda;
+   int rc;
+   /* pfx vn un L2 VNI */
+   if ((rc =
+        parse_deleter_args (vty, argv[2], NULL, NULL, argv[0], argv[1], &cda)))
+     return rc;
+   cda.vty = vty;
+   clear_vnc_prefix (&cda);
+   print_cleared_stats (&cda);
+   return 0;
+ }
+ /************************************************************************
+  *                    Show commands
+  ************************************************************************/
+ /* copied from rfp_vty.c */
+ static int
+ check_and_display_is_vnc_running (struct vty *vty)
+ {
+   if (!bgp_rfapi_is_vnc_configured (NULL))
+     return 1;                   /* is running */
+   if (vty)
+     {
+       vty_out (vty,
+                "VNC is not configured. (There are no configured BGP VPN SAFI peers.)%s",
+                VTY_NEWLINE);
+     }
+   return 0;                     /* not running */
+ }
+ static int
+ rfapi_vty_show_nve_summary (struct vty *vty, show_nve_summary_t show_type)
+ {
+   struct bgp *bgp_default = bgp_get_default ();
+   struct rfapi *h;
+   int is_vnc_running = !bgp_rfapi_is_vnc_configured (bgp_default);
+   int active_local_routes;
+   int active_remote_routes;
+   int holddown_remote_routes;
+   int imported_remote_routes;
+   if (!bgp_default)
+       goto notcfg;
+     h = bgp_default->rfapi;
+   if (!h)
+       goto notcfg;
+   /* don't show local info if not running RFP */
+   if (is_vnc_running || show_type == SHOW_NVE_SUMMARY_REGISTERED)
+     {
+       switch (show_type)
+         {
+         case SHOW_NVE_SUMMARY_ACTIVE_NVES:
+           vty_out (vty, "%-24s ", "NVEs:");
+           vty_out (vty, "%-8s %-8u ", "Active:", h->descriptors.count);
+           vty_out (vty, "%-8s %-8u ", "Maximum:", h->stat.max_descriptors);
+           vty_out (vty, "%-8s %-8u", "Unknown:", h->stat.count_unknown_nves);
+           break;
+           case SHOW_NVE_SUMMARY_REGISTERED:
+             /*
+              * NB: With the introduction of L2 route support, we no
+              * longer have a one-to-one correspondence between
+              * locally-originated route advertisements and routes in
+              * the import tables that have local origin. This
+              * discrepancy arises because a single advertisement
+              * may contain both an IP prefix and a MAC address.
+              * Such an advertisement results in two import table
+              * entries: one indexed by IP prefix, the other indexed
+              * by MAC address.
+              *
+              * TBD: update computation and display of registration
+              * statistics to reflect the underlying semantics.
+              */
+           if (is_vnc_running)
+             {
+               vty_out (vty, "%-24s ", "Registrations:");
+               vty_out (vty, "%-8s %-8u ", "Active:",
+                        rfapiApCountAll (bgp_default));
+               vty_out (vty, "%-8s %-8u ", "Failed:",
+                        h->stat.count_registrations_failed);
+               vty_out (vty, "%-8s %-8u", "Total:",
+                        h->stat.count_registrations);
+               vty_out (vty, "%s", VTY_NEWLINE);
+             }
+           vty_out (vty, "%-24s ", "Prefixes registered:");
+           vty_out (vty, "%s", VTY_NEWLINE);
+           rfapiCountAllItRoutes (&active_local_routes,
+                                  &active_remote_routes,
+                                  &holddown_remote_routes,
+                                  &imported_remote_routes);
+           /* local */
+           if (is_vnc_running)
+             {
+               vty_out (vty, "    %-20s ", "Locally:");
+               vty_out (vty, "%-8s %-8u ", "Active:", active_local_routes);
+               vty_out (vty, "%s", VTY_NEWLINE);
+             }
+           vty_out (vty, "    %-20s ", "Remotely:");
+           vty_out (vty, "%-8s %-8u", "Active:", active_remote_routes);
+           vty_out (vty, "%s", VTY_NEWLINE);
+           vty_out (vty, "    %-20s ", "In Holddown:");
+           vty_out (vty, "%-8s %-8u", "Active:", holddown_remote_routes);
+           vty_out (vty, "%s", VTY_NEWLINE);
+           vty_out (vty, "    %-20s ", "Imported:");
+           vty_out (vty, "%-8s %-8u", "Active:", imported_remote_routes);
+           break;
+         case SHOW_NVE_SUMMARY_QUERIES:
+           vty_out (vty, "%-24s ", "Queries:");
+           vty_out (vty, "%-8s %-8u ", "Active:", rfapi_monitor_count (NULL));
+           vty_out (vty, "%-8s %-8u ", "Failed:",
+                    h->stat.count_queries_failed);
+           vty_out (vty, "%-8s %-8u", "Total:", h->stat.count_queries);
+           break;
+         case SHOW_NVE_SUMMARY_RESPONSES:
+           rfapiRibShowResponsesSummary (vty);
+         default:
+           break;
+         }
+       vty_out (vty, "%s", VTY_NEWLINE);
+     }
+   return 0;
+ notcfg:
+   vty_out (vty, "VNC is not configured.%s", VTY_NEWLINE);
+   return CMD_WARNING;
+ }
+ static int
+ rfapi_show_nves (
+   struct vty  *vty,
+   struct prefix       *vn_prefix,
+   struct prefix       *un_prefix)
+ {
+   //struct hash                      *rfds;
+   //struct rfp_rfapi_descriptor_param param;
+   struct bgp *bgp_default = bgp_get_default ();
+   struct rfapi *h;
+   struct listnode *node;
+   struct rfapi_descriptor *rfd;
+   int total = 0;
+   int printed = 0;
+   int rc;
+   if (!bgp_default)
+       goto notcfg;
+     h = bgp_default->rfapi;
+   if (!h)
+       goto notcfg;
+     rc = rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_ACTIVE_NVES);
+   if (rc)
+       return rc;
+   for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
+     {
+       struct prefix pfx;
+       char vn_addr_buf[INET6_ADDRSTRLEN] =
+       {
+       0,};
+       char un_addr_buf[INET6_ADDRSTRLEN] =
+       {
+       0,};
+       char age[10];
+       ++total;
+       if (vn_prefix)
+         {
+           assert (!rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx));
+           if (!prefix_match (vn_prefix, &pfx))
+             continue;
+         }
+       if (un_prefix)
+         {
+           assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx));
+           if (!prefix_match (un_prefix, &pfx))
+             continue;
+         }
+       rfapiRfapiIpAddr2Str (&rfd->vn_addr, vn_addr_buf, INET6_ADDRSTRLEN);
+       rfapiRfapiIpAddr2Str (&rfd->un_addr, un_addr_buf, INET6_ADDRSTRLEN);
+       if (!printed)
+         {
+           /* print out a header */
+           vty_out (vty, "                                "
+                    "Active      Next Hops%s", VTY_NEWLINE);
+           vty_out (vty, "%-15s %-15s %-5s %-5s %-6s %-6s %s%s",
+                    "VN Address",
+                    "UN Address",
+                    "Regis", "Resps", "Reach", "Remove", "Age", VTY_NEWLINE);
+         }
+       ++printed;
+       vty_out (vty, "%-15s %-15s %-5u %-5u %-6u %-6u %s%s",
+                vn_addr_buf,
+                un_addr_buf,
+                rfapiApCount (rfd),
+                rfapi_monitor_count (rfd),
+                rfd->stat_count_nh_reachable,
+                rfd->stat_count_nh_removal,
+                rfapiFormatAge (rfd->open_time, age, 10), VTY_NEWLINE);
+     }
+   if (printed > 0 || vn_prefix || un_prefix)
+     vty_out (vty, "Displayed %d out of %d active NVEs%s",
+              printed, total, VTY_NEWLINE);
+   return 0;
+ notcfg:
+   vty_out (vty, "VNC is not configured.%s", VTY_NEWLINE);
+   return CMD_WARNING;
+ }
+ DEFUN (vnc_show_summary,
+        vnc_show_summary_cmd,
+        "show vnc summary",
+        SHOW_STR
+        VNC_SHOW_STR
+        "Display VNC status summary\n")
+ {
+   if (!check_and_display_is_vnc_running (vty))
+     return CMD_SUCCESS;
+   bgp_rfapi_show_summary (bgp_get_default (), vty);
+   vty_out (vty, "%s", VTY_NEWLINE);
+   rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_ACTIVE_NVES);
+   rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES);
+   rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_RESPONSES);
+   rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_REGISTERED);
+   return CMD_SUCCESS;
+ }
+ DEFUN (vnc_show_nves,
+        vnc_show_nves_cmd,
+        "show vnc nves",
+        SHOW_STR
+        VNC_SHOW_STR
+        "List known NVEs\n")
+ {
+   rfapi_show_nves (vty, NULL, NULL);
+   return CMD_SUCCESS;
+ }
+ DEFUN (vnc_show_nves_ptct,
+        vnc_show_nves_ptct_cmd,
 -       "show vnc registrations ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])",
++       "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
+        SHOW_STR
+        VNC_SHOW_STR
+        "List known NVEs\n"
+        "VN address of NVE\n"
+        "UN address of NVE\n"
+        "IPv4 interface address\n"
+        "IPv6 interface address\n")
+ {
+   struct prefix pfx;
+   if (!check_and_display_is_vnc_running (vty))
+     return CMD_SUCCESS;
+   if (!str2prefix (argv[1], &pfx))
+     {
+       vty_out (vty, "Malformed address \"%s\"%s", argv[1], VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   if (pfx.family != AF_INET && pfx.family != AF_INET6)
+     {
+       vty_out (vty, "Invalid address \"%s\"%s", argv[1], VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   if (*(argv[0]) == 'u')
+     {
+       rfapi_show_nves (vty, NULL, &pfx);
+     }
+   else
+     {
+       rfapi_show_nves (vty, &pfx, NULL);
+     }
+   return CMD_SUCCESS;
+ }
+ /* adapted from rfp_registration_cache_log() */
+ static void
+ rfapi_show_registrations (
+   struct vty  *vty,
+   struct prefix       *restrict_to,
+   int         show_local,
+   int         show_remote,
+   int         show_holddown,
+   int         show_imported)
+ {
+   int printed = 0;
+   if (!vty)
+       return;
+     rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_REGISTERED);
+   if (show_local)
+     {
+       /* non-expiring, local */
+       printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 1, 0, 0);
+     }
+   if (show_remote)
+     {
+       /* non-expiring, non-local */
+       printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 0, 1, 0);
+     }
+   if (show_holddown)
+     {
+       /* expiring, including local */
+       printed += rfapiShowRemoteRegistrations (vty, restrict_to, 1, 1, 1, 0);
+     }
+   if (show_imported)
+     {
+       /* non-expiring, non-local */
+       printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 0, 1, 1);
+     }
+   if (!printed)
+     {
+       vty_out (vty, "%s", VTY_NEWLINE);
+     }
+ }
+ DEFUN (vnc_show_registrations_pfx,
+        vnc_show_registrations_pfx_cmd,
 -         vnc_show_responses_pfx_cmd,
 -         "show vnc responses ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])",
++       "show vnc registrations <[A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY]>",
+        SHOW_STR
+        VNC_SHOW_STR
+        "List active prefix registrations\n"
+        "Limit output to a particular prefix or address\n"
+        "Limit output to a particular prefix or address\n")
+ {
+   struct prefix p;
+   struct prefix *p_addr = NULL;
+   if (argc == 1)
+     {
+       if (!str2prefix (argv[0], &p))
+         {
+           vty_out (vty, "Invalid prefix: %s%s", argv[0], VTY_NEWLINE);
+           return CMD_SUCCESS;
+         }
+       else
+         {
+           p_addr = &p;
+         }
+     }
+   rfapi_show_registrations (vty, p_addr, 1, 1, 1, 1);
+   return CMD_SUCCESS;
+ }
+ ALIAS (vnc_show_registrations_pfx,
+        vnc_show_registrations_cmd,
+        "show vnc registrations",
+        SHOW_STR
+        VNC_SHOW_STR
+        "List active prefix registrations\n")
+   DEFUN (vnc_show_registrations_some_pfx,
+          vnc_show_registrations_some_pfx_cmd,
+          "show vnc registrations (all|holddown|imported|local|remote) ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])",
+          SHOW_STR
+          VNC_SHOW_STR
+          "List active prefix registrations\n"
+          "show all registrations\n"
+          "show only registrations in holddown\n"
+          "show only imported prefixes\n"
+          "show only local registrations\n"
+          "show only remote registrations\n"
+          "Limit output to a particular prefix or address\n"
+          "Limit output to a particular prefix or address\n")
+ {
+   struct prefix p;
+   struct prefix *p_addr = NULL;
+   int show_local = 0;
+   int show_remote = 0;
+   int show_holddown = 0;
+   int show_imported = 0;
+   if (argc == 2)
+     {
+       if (!str2prefix (argv[1], &p))
+         {
+           vty_out (vty, "Invalid prefix: %s%s", argv[1], VTY_NEWLINE);
+           return CMD_SUCCESS;
+         }
+       else
+         {
+           p_addr = &p;
+         }
+     }
+   switch (*argv[0])
+     {
+     case 'a':
+       show_local = 1;
+       show_remote = 1;
+       show_holddown = 1;
+       show_imported = 1;
+       break;
+     case 'h':
+       show_holddown = 1;
+       break;
+     case 'i':
+       show_imported = 1;
+       break;
+     case 'l':
+       show_local = 1;
+       break;
+     case 'r':
+       show_remote = 1;
+       break;
+     }
+   rfapi_show_registrations (vty, p_addr,
+                             show_local, show_remote, show_holddown,
+                             show_imported);
+   return CMD_SUCCESS;
+ }
+ ALIAS (vnc_show_registrations_some_pfx,
+        vnc_show_registrations_some_cmd,
+        "show vnc registrations (all|holddown|imported|local|remote)",
+        SHOW_STR
+        VNC_SHOW_STR
+        "List active prefix registrations\n"
+        "show all registrations\n"
+        "show only registrations in holddown\n"
+        "show only imported prefixes\n"
+        "show only local registrations\n"
+        "show only remote registrations\n")
+ DEFUN (vnc_show_responses_pfx,
 -         vnc_show_responses_some_pfx_cmd,
 -         "show vnc responses (active|removed) ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])",
++       vnc_show_responses_pfx_cmd,
++         "show vnc responses <[A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY]>",
+          SHOW_STR
+          VNC_SHOW_STR
+          "List recent query responses\n"
+          "Limit output to a particular prefix or address\n"
+          "Limit output to a particular prefix or address\n")
+ {
+   struct prefix p;
+   struct prefix *p_addr = NULL;
+   if (argc == 1)
+     {
+       if (!str2prefix (argv[0], &p))
+         {
+           vty_out (vty, "Invalid prefix: %s%s", argv[0], VTY_NEWLINE);
+           return CMD_SUCCESS;
+         }
+       else
+         {
+           p_addr = &p;
+         }
+     }
+   rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES);
+   rfapiRibShowResponsesSummary (vty);
+   rfapiRibShowResponses (vty, p_addr, 0);
+   rfapiRibShowResponses (vty, p_addr, 1);
+   return CMD_SUCCESS;
+ }
+ ALIAS (vnc_show_responses_pfx,
+        vnc_show_responses_cmd,
+        "show vnc responses",
+        SHOW_STR
+        VNC_SHOW_STR
+        "List recent query responses\n")
+ DEFUN (vnc_show_responses_some_pfx,
 -       "show vnc queries ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])",
++       vnc_show_responses_some_pfx_cmd,
++         "show vnc responses <active|removed> <[A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY]>",
+          SHOW_STR
+          VNC_SHOW_STR
+          "List recent query responses\n"
+          "show only active query responses\n"
+          "show only removed query responses\n"
+          "Limit output to a particular prefix or address\n"
+          "Limit output to a particular prefix or address\n")
+ {
+   struct prefix p;
+   struct prefix *p_addr = NULL;
+   int show_active = 0;
+   int show_removed = 0;
+   if (!check_and_display_is_vnc_running (vty))
+     return CMD_SUCCESS;
+   if (argc == 2)
+     {
+       if (!str2prefix (argv[1], &p))
+         {
+           vty_out (vty, "Invalid prefix: %s%s", argv[1], VTY_NEWLINE);
+           return CMD_SUCCESS;
+         }
+       else
+         {
+           p_addr = &p;
+         }
+     }
+   switch (*argv[0])
+     {
+     case 'a':
+       show_active = 1;
+       break;
+     case 'r':
+       show_removed = 1;
+       break;
+     }
+   rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES);
+   rfapiRibShowResponsesSummary (vty);
+   if (show_active)
+     rfapiRibShowResponses (vty, p_addr, 0);
+   if (show_removed)
+     rfapiRibShowResponses (vty, p_addr, 1);
+   return CMD_SUCCESS;
+ }
+ ALIAS (vnc_show_responses_some_pfx,
+        vnc_show_responses_some_cmd,
+        "show vnc responses (active|removed)",
+        SHOW_STR
+        VNC_SHOW_STR
+        "List recent query responses\n"
+        "show only active query responses\n"
+        "show only removed query responses\n")
+ DEFUN (show_vnc_queries_pfx,
+        show_vnc_queries_pfx_cmd,
++       "show vnc queries <[A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY]>",
+        SHOW_STR
+        VNC_SHOW_STR
+        "List active queries\n"
+        "Limit output to a particular IPv4 prefix or address\n"
+        "Limit output to a particular IPv6 prefix or address\n")
+ {
+   struct prefix pfx;
+   struct prefix *p = NULL;
+   if (argc == 1)
+     {
+       if (!str2prefix (argv[0], &pfx))
+         {
+           vty_out (vty, "Invalid prefix: %s%s", argv[0], VTY_NEWLINE);
+           return CMD_WARNING;
+         }
+       p = &pfx;
+     }
+   rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES);
+   return rfapiShowVncQueries (vty, p);
+ }
+ ALIAS (show_vnc_queries_pfx,
+        show_vnc_queries_cmd,
+        "show vnc queries",
+        SHOW_STR
+        VNC_SHOW_STR
+        "List active queries\n")
+ DEFUN (vnc_clear_counters,
+        vnc_clear_counters_cmd,
+        "clear vnc counters",
+        CLEAR_STR
+        VNC_SHOW_STR
+        "Reset VNC counters\n")
+ {
+   struct bgp *bgp_default = bgp_get_default ();
+   struct rfapi *h;
+   struct listnode *node;
+   struct rfapi_descriptor *rfd;
+   if (!bgp_default)
+     goto notcfg;
+   h = bgp_default->rfapi;
+   if (!h)
+     goto notcfg;
+   /* per-rfd */
+   for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
+     {
+       rfd->stat_count_nh_reachable = 0;
+       rfd->stat_count_nh_removal = 0;
+     }
+   /* global */
+   memset (&h->stat, 0, sizeof (h->stat));
+   /*
+    * 151122 per bug 103, set count_registrations = number active.
+    * Do same for queries
+    */
+   h->stat.count_registrations = rfapiApCountAll (bgp_default);
+   h->stat.count_queries = rfapi_monitor_count (NULL);
+   rfapiRibShowResponsesSummaryClear ();
+   return CMD_SUCCESS;
+ notcfg:
+   vty_out (vty, "VNC is not configured.%s", VTY_NEWLINE);
+   return CMD_WARNING;
+ }
+ void rfapi_vty_init ()
+ {
+   install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_lnh_cmd);
+   install_element (ENABLE_NODE, &add_vnc_prefix_life_cost_lnh_cmd);
+   install_element (ENABLE_NODE, &add_vnc_prefix_cost_lnh_cmd);
+   install_element (ENABLE_NODE, &add_vnc_prefix_life_lnh_cmd);
+   install_element (ENABLE_NODE, &add_vnc_prefix_lnh_cmd);
+   install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_cmd);
+   install_element (ENABLE_NODE, &add_vnc_prefix_life_cost_cmd);
+   install_element (ENABLE_NODE, &add_vnc_prefix_cost_cmd);
+   install_element (ENABLE_NODE, &add_vnc_prefix_life_cmd);
+   install_element (ENABLE_NODE, &add_vnc_prefix_cmd);
+   install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_life_cmd);
+   install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_life_cmd);
+   install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_cmd);
+   install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cmd);
+   install_element (ENABLE_NODE, &add_vnc_mac_vni_cost_life_cmd);
+   install_element (ENABLE_NODE, &add_vnc_mac_vni_cost_cmd);
+   install_element (ENABLE_NODE, &add_vnc_mac_vni_life_cmd);
+   install_element (ENABLE_NODE, &add_vnc_mac_vni_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_nve_all_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_nve_vn_un_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_nve_un_vn_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_nve_vn_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_nve_un_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_prefix_vn_un_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_prefix_un_vn_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_prefix_un_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_prefix_vn_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_prefix_all_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_mac_vn_un_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_mac_un_vn_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_mac_un_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_mac_vn_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_mac_all_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_mac_vn_un_prefix_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_mac_un_vn_prefix_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_mac_un_prefix_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_mac_vn_prefix_cmd);
+   install_element (ENABLE_NODE, &clear_vnc_mac_all_prefix_cmd);
+   install_element (ENABLE_NODE, &vnc_clear_counters_cmd);
+   install_element (VIEW_NODE, &vnc_show_summary_cmd);
+   install_element (ENABLE_NODE, &vnc_show_summary_cmd);
+   install_element (VIEW_NODE, &vnc_show_nves_cmd);
+   install_element (ENABLE_NODE, &vnc_show_nves_cmd);
+   install_element (VIEW_NODE, &vnc_show_nves_ptct_cmd);
+   install_element (ENABLE_NODE, &vnc_show_nves_ptct_cmd);
+   install_element (VIEW_NODE, &vnc_show_registrations_cmd);
+   install_element (ENABLE_NODE, &vnc_show_registrations_cmd);
+   install_element (VIEW_NODE, &vnc_show_registrations_pfx_cmd);
+   install_element (ENABLE_NODE, &vnc_show_registrations_pfx_cmd);
+   install_element (VIEW_NODE, &vnc_show_registrations_some_cmd);
+   install_element (ENABLE_NODE, &vnc_show_registrations_some_cmd);
+   install_element (VIEW_NODE, &vnc_show_registrations_some_pfx_cmd);
+   install_element (ENABLE_NODE, &vnc_show_registrations_some_pfx_cmd);
+   install_element (VIEW_NODE, &vnc_show_responses_cmd);
+   install_element (ENABLE_NODE, &vnc_show_responses_cmd);
+   install_element (VIEW_NODE, &vnc_show_responses_pfx_cmd);
+   install_element (ENABLE_NODE, &vnc_show_responses_pfx_cmd);
+   install_element (VIEW_NODE, &vnc_show_responses_some_cmd);
+   install_element (ENABLE_NODE, &vnc_show_responses_some_cmd);
+   install_element (VIEW_NODE, &vnc_show_responses_some_pfx_cmd);
+   install_element (ENABLE_NODE, &vnc_show_responses_some_pfx_cmd);
+   install_element (ENABLE_NODE, &show_vnc_queries_cmd);
+   install_element (VIEW_NODE, &show_vnc_queries_cmd);
+   install_element (ENABLE_NODE, &show_vnc_queries_pfx_cmd);
+   install_element (VIEW_NODE, &show_vnc_queries_pfx_cmd);
+ }
index 0000000000000000000000000000000000000000,eaa8c56ee98d49f952ae85f8d1208cd46e53f862..5db6f558b8d75c5cd30bb071bf8194c1d7ea5fe5
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,230 +1,230 @@@
 -       "debug bgp vnc (rfapi-query|import-bi-attach|import-del-remote)",
+ /* 
+  *
+  * Copyright 2016, LabN Consulting, L.L.C.
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version 2
+  * of the License, or (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+  *
+  */
+ #include "lib/zebra.h"
+ #include <lib/version.h>
+ #include "lib/prefix.h"
+ #include "lib/linklist.h"
+ #include "lib/stream.h"
+ #include "lib/command.h"
+ #include "lib/str.h"
+ #include "lib/log.h"
+ #include "bgpd/rfapi/vnc_debug.h"
+ /*
+  * debug state storage
+  */
+ unsigned long conf_vnc_debug;
+ unsigned long term_vnc_debug;
+ struct vnc_debug {
+     unsigned long     bit;
+     const char                *name;
+ };
+ struct vnc_debug      vncdebug[] =
+ {
+     {VNC_DEBUG_RFAPI_QUERY,           "rfapi-query"},
+     {VNC_DEBUG_IMPORT_BI_ATTACH,      "import-bi-attach"},
+     {VNC_DEBUG_IMPORT_DEL_REMOTE,     "import-del-remote"},
+     {VNC_DEBUG_EXPORT_BGP_GETCE,      "export-bgp-getce"},
+     {VNC_DEBUG_EXPORT_BGP_DIRECT_ADD, "export-bgp-direct-add"},
+     {VNC_DEBUG_IMPORT_BGP_ADD_ROUTE,  "import-bgp-add-route"},
+ };
+ #define VNC_STR "VNC information\n"
+ /***********************************************************************
+  *    debug bgp vnc <foo>
+  ***********************************************************************/
+ DEFUN (debug_bgp_vnc,
+        debug_bgp_vnc_cmd,
 -       "no debug bgp vnc (rfapi-query|import-bi-attach|import-del-remote)",
++       "debug bgp vnc <rfapi-query|import-bi-attach|import-del-remote>",
+        DEBUG_STR
+        BGP_STR
+        VNC_STR
+        "rfapi query handling\n"
+        "import BI atachment\n"
+        "import delete remote routes\n")
+ {
+   size_t      i;
+   for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
+     {
+       if (!strcmp(argv[0], vncdebug[i].name))
+       {
+         if (vty->node == CONFIG_NODE)
+           {
+             conf_vnc_debug |= vncdebug[i].bit;
+             term_vnc_debug |= vncdebug[i].bit;
+           }
+         else
+           {
+             term_vnc_debug |= vncdebug[i].bit;
+             vty_out (vty, "BGP vnc %s debugging is on%s",
+               vncdebug[i].name, VTY_NEWLINE);
+           }
+         return CMD_SUCCESS;
+       }
+     }
+   vty_out (vty, "Unknown debug flag: %s%s", argv[0], VTY_NEWLINE);
+   return CMD_WARNING;
+ }
+ DEFUN (no_debug_bgp_vnc,
+        no_debug_bgp_vnc_cmd,
++       "no debug bgp vnc <rfapi-query|import-bi-attach|import-del-remote>",
+        NO_STR
+        DEBUG_STR
+        BGP_STR
+        VNC_STR
+        "rfapi query handling\n"
+        "import BI atachment\n"
+        "import delete remote routes\n")
+ {
+   size_t      i;
+   for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
+     {
+       if (!strcmp(argv[0], vncdebug[i].name))
+       {
+         if (vty->node == CONFIG_NODE)
+           {
+             conf_vnc_debug &= ~vncdebug[i].bit;
+             term_vnc_debug &= ~vncdebug[i].bit;
+           }
+         else
+           {
+             term_vnc_debug &= ~vncdebug[i].bit;
+             vty_out (vty, "BGP vnc %s debugging is off%s",
+               vncdebug[i].name, VTY_NEWLINE);
+           }
+         return CMD_SUCCESS;
+       }
+     }
+   vty_out (vty, "Unknown debug flag: %s%s", argv[0], VTY_NEWLINE);
+   return CMD_WARNING;
+ }
+ ALIAS (no_debug_bgp_vnc,
+        undebug_bgp_vnc_cmd,
+        "undebug bgp vnc (rfapi-query|import-bi-attach|import-del-remote)",
+        UNDEBUG_STR
+        BGP_STR
+        VNC_STR
+        "rfapi query handling\n"
+        "import BI atachment\n"
+        "import delete remote routes\n")
+ /***********************************************************************
+  *    no debug bgp vnc all
+  ***********************************************************************/
+ DEFUN (no_debug_bgp_vnc_all,
+        no_debug_bgp_vnc_all_cmd,
+        "no debug all bgp vnc",
+        NO_STR
+        DEBUG_STR
+        "Disable all VNC debugging\n"
+        BGP_STR
+        VNC_STR)
+ {
+   term_vnc_debug = 0;
+   vty_out (vty, "All possible VNC debugging has been turned off%s", VTY_NEWLINE);
+       
+   return CMD_SUCCESS;
+ }
+ ALIAS (no_debug_bgp_vnc_all,
+        undebug_bgp_vnc_all_cmd,
+        "undebug all bgp vnc",
+        UNDEBUG_STR
+        "Disable all VNC debugging\n"
+        BGP_STR
+        VNC_STR)
+ /***********************************************************************
+  *    show/save
+  ***********************************************************************/
+ DEFUN (show_debugging_bgp_vnc,
+        show_debugging_bgp_vnc_cmd,
+        "show debugging bgp vnc",
+        SHOW_STR
+        DEBUG_STR
+        BGP_STR
+        VNC_STR)
+ {
+   size_t      i;
+   vty_out (vty, "BGP VNC debugging status:%s", VTY_NEWLINE);
+   for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
+     {
+       if (term_vnc_debug & vncdebug[i].bit)
+       {
+         vty_out (vty, "  BGP VNC %s debugging is on%s",
+           vncdebug[i].name, VTY_NEWLINE);
+       }
+     }
+   vty_out (vty, "%s", VTY_NEWLINE);
+   return CMD_SUCCESS;
+ }
+ static int
+ bgp_vnc_config_write_debug (struct vty *vty)
+ {
+   int write = 0;
+   size_t      i;
+   for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
+     {
+       if (conf_vnc_debug & vncdebug[i].bit)
+       {
+         vty_out (vty, "debug bgp vnc %s%s", vncdebug[i].name, VTY_NEWLINE);
+         write++;
+       }
+     }
+   return write;
+ }
+ static struct cmd_node debug_node =
+ {
+   DEBUG_VNC_NODE,
+   "",
+   1
+ };
+ void
+ vnc_debug_init (void)
+ {
+   install_node (&debug_node, bgp_vnc_config_write_debug);
+   install_element (ENABLE_NODE, &show_debugging_bgp_vnc_cmd);
+   install_element (ENABLE_NODE, &debug_bgp_vnc_cmd);
+   install_element (CONFIG_NODE, &debug_bgp_vnc_cmd);
+   install_element (ENABLE_NODE, &no_debug_bgp_vnc_cmd);
+   install_element (ENABLE_NODE, &undebug_bgp_vnc_cmd);
+   install_element (ENABLE_NODE, &no_debug_bgp_vnc_all_cmd);
+   install_element (ENABLE_NODE, &undebug_bgp_vnc_all_cmd);
+ }
diff --cc configure.ac
Simple merge
index 384eb3572bc38120afaeb7d62abed3babdbadfe0,21daaa7794dcd3cea155d90f378b7d373d489f20..045c7daa32b4c3b71a86d2300339e81e88424170
@@@ -551,11 -553,7 +552,11 @@@ DEFUN (isis_redistribute
         "Route map reference\n"
         "Pointer to route-map entries\n")
  {
-   struct isis_area *area = vty->index;
 +  int idx_afi = 1;
 +  int idx_protocol = 2;
 +  int idx_level = 3;
 +  int idx_metric_rmap = 4;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    int family;
    int afi;
    int type;
@@@ -618,10 -619,7 +619,10 @@@ DEFUN (no_isis_redistribute
         "Redistribute into level-1\n"
         "Redistribute into level-2\n")
  {
-   struct isis_area *area = vty->index;
 +  int idx_afi = 2;
 +  int idx_protocol = 3;
 +  int idx_level = 4;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    int type;
    int level;
    int family;
@@@ -660,17 -667,17 +661,17 @@@ DEFUN (isis_default_originate
         "Route map reference\n"
         "Pointer to route-map entries\n")
  {
-   struct isis_area *area = vty->index;
 +  int idx_afi = 2;
 +  int idx_level = 3;
 +  int idx_metric_rmap = 4;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    int family;
 -  int originate_type;
 +  int originate_type = DEFAULT_ORIGINATE;
    int level;
 -  unsigned long metric;
 -  const char *routemap;
 -
 -  if (argc < 5)
 -    return CMD_WARNING;
 +  unsigned long metric = 0xffffffff;
 +  const char *routemap = NULL;
  
 -  family = str2family(argv[0]);
 +  family = str2family(argv[idx_afi]->text);
    if (family < 0)
      return CMD_WARNING;
  
@@@ -713,10 -734,7 +714,9 @@@ DEFUN (no_isis_default_originate
         "Distribute default route into level-1\n"
         "Distribute default route into level-2\n")
  {
-   struct isis_area *area = vty->index;
 +  int idx_afi = 3;
 +  int idx_level = 4;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    int family;
    int level;
  
diff --cc isisd/isis_te.c
Simple merge
index 7fe65e6ca77573a06466de06e50291c4e0641acc,12ef682c173295315a3ccec4206369913fe94356..492572bddf50dda26e82d275ad190345b0d5e0f1
@@@ -61,17 -60,12 +60,14 @@@ DEFUN (ip_router_isis
         "IS-IS Routing for IP\n"
         "Routing process tag\n")
  {
-   struct interface *ifp;
 +  int idx_afi = 0;
 +  int idx_word = 3;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct isis_circuit *circuit;
    struct isis_area *area;
 -  const char *af = argv[0];
 -  const char *area_tag = argv[1];
 +  const char *af = argv[idx_afi]->arg;
 +  const char *area_tag = argv[idx_word]->arg;
  
-   ifp = (struct interface *) vty->index;
-   assert (ifp);
    /* Prevent more than one area per circuit */
    circuit = circuit_scan_by_ifp (ifp);
    if (circuit && circuit->area)
@@@ -128,21 -111,12 +124,14 @@@ DEFUN (no_ip_router_isis
         "IS-IS Routing for IP\n"
         "Routing process tag\n")
  {
-   struct interface *ifp;
 +  int idx_afi = 1;
 +  int idx_word = 4;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct isis_area *area;
    struct isis_circuit *circuit;
 -  const char *af = argv[0];
 -  const char *area_tag = argv[1];
 +  const char *af = argv[idx_afi]->arg;
 +  const char *area_tag = argv[idx_word]->arg;
  
-   ifp = (struct interface *) vty->index;
-   if (!ifp)
-     {
-       vty_out (vty, "Invalid interface %s", VTY_NEWLINE);
-       return CMD_ERR_NO_MATCH;
-     }
    area = isis_area_lookup (area_tag);
    if (!area)
      {
@@@ -1326,13 -1393,10 +1315,11 @@@ DEFUN (metric_style
         "Send and accept both styles of TLVs during transition\n"
         "Use new style of TLVs to carry wider metric\n")
  {
-   struct isis_area *area = vty->index;
 +  int idx_metric_style = 1;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    int ret;
  
-   assert(area);
 -  if (strncmp (argv[0], "w", 1) == 0)
 +  if (strncmp (argv[idx_metric_style]->arg, "w", 1) == 0)
      {
        isis_area_metricstyle_set(area, false, true);
        return CMD_SUCCESS;
@@@ -1510,19 -1564,10 +1484,11 @@@ DEFUN (is_type
         "Act as both a station router and an area router\n"
         "Act as an area router only\n")
  {
-   struct isis_area *area;
 +  int idx_level = 1;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    int type;
  
-   area = vty->index;
-   if (!area)
-     {
-       vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE);
-       return CMD_ERR_NO_MATCH;
-     }
 -  type = string2circuit_t (argv[0]);
 +  type = string2circuit_t (argv[idx_level]->arg);
    if (!type)
      {
        vty_out (vty, "Unknown IS level %s", VTY_NEWLINE);
@@@ -1600,25 -1642,22 +1563,24 @@@ DEFUN (lsp_gen_interval
         "Minimum interval between regenerating same LSP\n"
         "Minimum interval in seconds\n")
  {
-   struct isis_area *area;
 +  int idx_number = 1;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    uint16_t interval;
    int level;
  
-   area = vty->index;
 -  interval = atoi (argv[0]);
 +  interval = atoi (argv[idx_number]->arg);
    level = IS_LEVEL_1 | IS_LEVEL_2;
    return set_lsp_gen_interval (vty, area, interval, level);
  }
  
  DEFUN (no_lsp_gen_interval,
         no_lsp_gen_interval_cmd,
 -       "no lsp-gen-interval",
 +       "no lsp-gen-interval [(1-120)]",
         NO_STR
 -       "Minimum interval between regenerating same LSP\n")
 +       "Minimum interval between regenerating same LSP\n"
 +       "Minimum interval in seconds\n")
  {
-   struct isis_area *area;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    uint16_t interval;
    int level;
  
@@@ -1636,13 -1680,11 +1597,12 @@@ DEFUN (lsp_gen_interval_l1
         "Set interval for level 1 only\n"
         "Minimum interval in seconds\n")
  {
-   struct isis_area *area;
 +  int idx_number = 2;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    uint16_t interval;
    int level;
  
-   area = vty->index;
 -  interval = atoi (argv[0]);
 +  interval = atoi (argv[idx_number]->arg);
    level = IS_LEVEL_1;
    return set_lsp_gen_interval (vty, area, interval, level);
  }
@@@ -1672,26 -1720,23 +1631,25 @@@ DEFUN (lsp_gen_interval_l2
         "Set interval for level 2 only\n"
         "Minimum interval in seconds\n")
  {
-   struct isis_area *area;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
 +  int idx_number = 2;
    uint16_t interval;
    int level;
  
-   area = vty->index;
 -  interval = atoi (argv[0]);
 +  interval = atoi (argv[idx_number]->arg);
    level = IS_LEVEL_2;
    return set_lsp_gen_interval (vty, area, interval, level);
  }
  
  DEFUN (no_lsp_gen_interval_l2,
         no_lsp_gen_interval_l2_cmd,
 -       "no lsp-gen-interval level-2",
 +       "no lsp-gen-interval level-2 [(1-120)]",
         NO_STR
         "Minimum interval between regenerating same LSP\n"
 -       "Set interval for level 2 only\n")
 +       "Set interval for level 2 only\n"
 +       "Minimum interval in seconds\n")
  {
-   struct isis_area *area;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    uint16_t interval;
    int level;
  
@@@ -1708,31 -1759,23 +1665,28 @@@ DEFUN (spf_interval
         "Minimum interval between SPF calculations\n"
         "Minimum interval between consecutive SPFs in seconds\n")
  {
-   struct isis_area *area;
 +  int idx_number = 1;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    u_int16_t interval;
  
-   area = vty->index;
 -  interval = atoi (argv[0]);
 +  interval = atoi (argv[idx_number]->arg);
    area->min_spf_interval[0] = interval;
    area->min_spf_interval[1] = interval;
  
    return CMD_SUCCESS;
  }
  
 +
  DEFUN (no_spf_interval,
         no_spf_interval_cmd,
 -       "no spf-interval",
 +       "no spf-interval [[<level-1|level-2>] (1-120)]",
         NO_STR
 -       "Minimum interval between SPF calculations\n")
 +       "Minimum interval between SPF calculations\n"
 +       "Set interval for level 1 only\n"
 +       "Set interval for level 2 only\n"
 +       "Minimum interval between consecutive SPFs in seconds\n")
  {
-   struct isis_area *area;
-   area = vty->index;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
  
    area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL;
    area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL;
@@@ -1748,12 -1797,10 +1702,11 @@@ DEFUN (spf_interval_l1
         "Set interval for level 1 only\n"
         "Minimum interval between consecutive SPFs in seconds\n")
  {
-   struct isis_area *area;
 +  int idx_number = 2;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    u_int16_t interval;
  
-   area = vty->index;
 -  interval = atoi (argv[0]);
 +  interval = atoi (argv[idx_number]->arg);
    area->min_spf_interval[0] = interval;
  
    return CMD_SUCCESS;
@@@ -1783,12 -1835,10 +1734,11 @@@ DEFUN (spf_interval_l2
         "Set interval for level 2 only\n"
         "Minimum interval between consecutive SPFs in seconds\n")
  {
-   struct isis_area *area;
 +  int idx_number = 2;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
    u_int16_t interval;
  
-   area = vty->index;
 -  interval = atoi (argv[0]);
 +  interval = atoi (argv[idx_number]->arg);
    area->min_spf_interval[1] = interval;
  
    return CMD_SUCCESS;
@@@ -2157,15 -2197,8 +2087,9 @@@ DEFUN (no_area_passwd
         "Configure the authentication password for an area\n"
         "Set the authentication password for a routing domain\n")
  {
-   struct isis_area *area = vty->index;
-   if (!area)
-     {
-       vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE);
-       return CMD_ERR_NO_MATCH;
-     }
 +  int idx_password = 1;
 +  int level = strmatch (argv[idx_password]->text, "domain-password") ? IS_LEVEL_2 : IS_LEVEL_1;
 -  int level = (argv[0][0] == 'd') ? IS_LEVEL_2 : IS_LEVEL_1;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
  
    return isis_area_passwd_unset (area, level);
  }
diff --cc isisd/isisd.c
index ffe17b3643f9dd51f25b42821c3922a3d7743f99,d6ce627b93225c8589ccf0e145b1d4ff143f59d8..143e380016bd073a22f5675f15f20bccc833f255
@@@ -1976,15 -1963,11 +1972,12 @@@ DEFUN (topology_baseis
         "A Network IS Base for this topology\n"
         "XXXX.XXXX.XXXX Network entity title (NET)\n")
  {
-   struct isis_area *area;
 +  int idx_word = 2;
    u_char buff[ISIS_SYS_ID_LEN];
-   area = vty->index;
-   assert (area);
+   VTY_DECLVAR_CONTEXT (isis_area, area);
  
 -  if (sysid2buff (buff, argv[0]))
 -    sysid2buff (area->topology_baseis, argv[0]);
 +  if (sysid2buff (buff, argv[idx_word]->arg))
 +    sysid2buff (area->topology_baseis, argv[idx_word]->arg);
  
    return CMD_SUCCESS;
  }
@@@ -2014,14 -2000,10 +2004,11 @@@ DEFUN (topology_basedynh
         "Dynamic hostname base for this topology\n"
         "Dynamic hostname base\n")
  {
-   struct isis_area *area;
-   area = vty->index;
-   assert (area);
 +  int idx_word = 2;
+   VTY_DECLVAR_CONTEXT (isis_area, area);
  
    /* I hope that it's enough. */
 -  area->topology_basedynh = strndup (argv[0], 16); 
 +  area->topology_basedynh = strndup (argv[idx_word]->arg, 16); 
    return CMD_SUCCESS;
  }
  
@@@ -2424,7 -2388,7 +2393,6 @@@ isis_init (
    install_element (ISIS_NODE, &topology_baseis_cmd);
    install_element (ISIS_NODE, &topology_basedynh_cmd);
    install_element (ISIS_NODE, &no_topology_baseis_cmd);
 -  install_element (ISIS_NODE, &no_topology_baseis_noid_cmd);
    install_element (VIEW_NODE, &show_isis_generated_topology_cmd);
-   install_element (ENABLE_NODE, &show_isis_generated_topology_cmd);
  #endif /* TOPOLOGY_GENERATE */
  }
index 0000000000000000000000000000000000000000,b55c7fc8a9fec2192eb65101823203ca7770248a..64715999f27ac8ef7f53678d1f5cb1f13057071b
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1726 +1,1726 @@@
 -       "discovery hello holdtime <1-65535>",
+ /* Auto-generated from ldp_vty.xml. */
+ /* Do not edit! */
+ #include <zebra.h>
+ #include "command.h"
+ #include "vty.h"
+ #include "ldp_vty.h"
+ DEFUN (ldp_mpls_ldp,
+        ldp_mpls_ldp_cmd,
+        "mpls ldp",
+        "Global MPLS configuration subcommands\n"
+        "Label Distribution Protocol\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_mpls_ldp (vty, args);
+ }
+ DEFUN (ldp_l2vpn_word_type_vpls,
+        ldp_l2vpn_word_type_vpls_cmd,
+        "l2vpn WORD type vpls",
+        "Configure l2vpn commands\n"
+        "L2VPN name\n"
+        "L2VPN type\n"
+        "Virtual Private LAN Service\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "name", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn (vty, args);
+ }
+ DEFUN (ldp_no_mpls_ldp,
+        ldp_no_mpls_ldp_cmd,
+        "no mpls ldp",
+        "Negate a command or set its defaults\n"
+        "Global MPLS configuration subcommands\n"
+        "Label Distribution Protocol\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       NULL
+     };
+   return ldp_vty_mpls_ldp (vty, args);
+ }
+ DEFUN (ldp_no_l2vpn_word_type_vpls,
+        ldp_no_l2vpn_word_type_vpls_cmd,
+        "no l2vpn WORD type vpls",
+        "Negate a command or set its defaults\n"
+        "Configure l2vpn commands\n"
+        "L2VPN name\n"
+        "L2VPN type\n"
+        "Virtual Private LAN Service\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "name", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn (vty, args);
+ }
+ DEFUN (ldp_address_family_ipv4,
+        ldp_address_family_ipv4_cmd,
+        "address-family ipv4",
+        "Configure Address Family and its parameters\n"
+        "IPv4\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "address-family", .value = "ipv4" },
+       NULL
+     };
+   return ldp_vty_address_family (vty, args);
+ }
+ DEFUN (ldp_address_family_ipv6,
+        ldp_address_family_ipv6_cmd,
+        "address-family ipv6",
+        "Configure Address Family and its parameters\n"
+        "IPv6\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "address-family", .value = "ipv6" },
+       NULL
+     };
+   return ldp_vty_address_family (vty, args);
+ }
+ DEFUN (ldp_discovery_hello_holdtime_disc_time,
+        ldp_discovery_hello_holdtime_disc_time_cmd,
 -       "discovery hello interval <1-65535>",
++       "discovery hello holdtime (1-65535)",
+        "Configure discovery parameters\n"
+        "LDP Link Hellos\n"
+        "Hello holdtime\n"
+        "Time (seconds) - 65535 implies infinite\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "hello_type", .value = "hello" },
+       &(struct vty_arg) { .name = "seconds", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_disc_holdtime (vty, args);
+ }
+ DEFUN (ldp_discovery_hello_interval_disc_time,
+        ldp_discovery_hello_interval_disc_time_cmd,
 -       "discovery targeted-hello holdtime <1-65535>",
++       "discovery hello interval (1-65535)",
+        "Configure discovery parameters\n"
+        "LDP Link Hellos\n"
+        "Hello interval\n"
+        "Time (seconds)\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "hello_type", .value = "hello" },
+       &(struct vty_arg) { .name = "seconds", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_disc_interval (vty, args);
+ }
+ DEFUN (ldp_discovery_targeted_hello_holdtime_disc_time,
+        ldp_discovery_targeted_hello_holdtime_disc_time_cmd,
 -       "discovery targeted-hello interval <1-65535>",
++       "discovery targeted-hello holdtime (1-65535)",
+        "Configure discovery parameters\n"
+        "LDP Targeted Hellos\n"
+        "Targeted hello holdtime\n"
+        "Time (seconds) - 65535 implies infinite\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" },
+       &(struct vty_arg) { .name = "seconds", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_disc_holdtime (vty, args);
+ }
+ DEFUN (ldp_discovery_targeted_hello_interval_disc_time,
+        ldp_discovery_targeted_hello_interval_disc_time_cmd,
 -       "neighbor A.B.C.D session holdtime <15-65535>",
++       "discovery targeted-hello interval (1-65535)",
+        "Configure discovery parameters\n"
+        "LDP Targeted Hellos\n"
+        "Targeted hello interval\n"
+        "Time (seconds)\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" },
+       &(struct vty_arg) { .name = "seconds", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_disc_interval (vty, args);
+ }
+ DEFUN (ldp_dual_stack_transport_connection_prefer_ipv4,
+        ldp_dual_stack_transport_connection_prefer_ipv4_cmd,
+        "dual-stack transport-connection prefer ipv4",
+        "Configure dual stack parameters\n"
+        "Configure TCP transport parameters\n"
+        "Configure prefered address family for TCP transport connection with neighbor\n"
+        "IPv4\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_trans_pref_ipv4 (vty, args);
+ }
+ DEFUN (ldp_dual_stack_cisco_interop,
+        ldp_dual_stack_cisco_interop_cmd,
+        "dual-stack cisco-interop",
+        "Configure dual stack parameters\n"
+        "Use Cisco non-compliant format to send and interpret the Dual-Stack capability TLV\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_ds_cisco_interop (vty, args);
+ }
+ DEFUN (ldp_neighbor_ipv4_password_word,
+        ldp_neighbor_ipv4_password_word_cmd,
+        "neighbor A.B.C.D password WORD",
+        "Configure neighbor parameters\n"
+        "LDP Id of neighbor\n"
+        "Configure password for MD5 authentication\n"
+        "The password\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
+       &(struct vty_arg) { .name = "password", .value = argv[1] },
+       NULL
+     };
+   return ldp_vty_neighbor_password (vty, args);
+ }
+ DEFUN (ldp_neighbor_ipv4_session_holdtime_session_time,
+        ldp_neighbor_ipv4_session_holdtime_session_time_cmd,
 -       "neighbor A.B.C.D ttl-security hops <1-254>",
++       "neighbor A.B.C.D session holdtime (15-65535)",
+        "Configure neighbor parameters\n"
+        "LDP Id of neighbor\n"
+        "Configure session parameters\n"
+        "Configure session holdtime\n"
+        "Time (seconds)\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
+       &(struct vty_arg) { .name = "seconds", .value = argv[1] },
+       NULL
+     };
+   return ldp_vty_session_holdtime (vty, args);
+ }
+ DEFUN (ldp_neighbor_ipv4_ttl_security_disable,
+        ldp_neighbor_ipv4_ttl_security_disable_cmd,
+        "neighbor A.B.C.D ttl-security disable",
+        "Configure neighbor parameters\n"
+        "LDP Id of neighbor\n"
+        "LDP ttl security check\n"
+        "Disable ttl security\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_neighbor_ttl_security (vty, args);
+ }
+ DEFUN (ldp_neighbor_ipv4_ttl_security_hops_hops,
+        ldp_neighbor_ipv4_ttl_security_hops_hops_cmd,
 -       "no discovery hello holdtime <1-65535>",
++       "neighbor A.B.C.D ttl-security hops (1-254)",
+        "Configure neighbor parameters\n"
+        "LDP Id of neighbor\n"
+        "LDP ttl security check\n"
+        "IP hops\n"
+        "maximum number of hops\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
+       &(struct vty_arg) { .name = "hops", .value = argv[1] },
+       NULL
+     };
+   return ldp_vty_neighbor_ttl_security (vty, args);
+ }
+ DEFUN (ldp_router_id_ipv4,
+        ldp_router_id_ipv4_cmd,
+        "router-id A.B.C.D",
+        "Configure router Id\n"
+        "LSR Id (in form of an IPv4 address)\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_router_id (vty, args);
+ }
+ DEFUN (ldp_no_address_family_ipv4,
+        ldp_no_address_family_ipv4_cmd,
+        "no address-family ipv4",
+        "Negate a command or set its defaults\n"
+        "Configure Address Family and its parameters\n"
+        "IPv4\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "address-family", .value = "ipv4" },
+       NULL
+     };
+   return ldp_vty_address_family (vty, args);
+ }
+ DEFUN (ldp_no_address_family_ipv6,
+        ldp_no_address_family_ipv6_cmd,
+        "no address-family ipv6",
+        "Negate a command or set its defaults\n"
+        "Configure Address Family and its parameters\n"
+        "IPv6\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "address-family", .value = "ipv6" },
+       NULL
+     };
+   return ldp_vty_address_family (vty, args);
+ }
+ DEFUN (ldp_no_discovery_hello_holdtime_disc_time,
+        ldp_no_discovery_hello_holdtime_disc_time_cmd,
 -       "no discovery hello interval <1-65535>",
++       "no discovery hello holdtime (1-65535)",
+        "Negate a command or set its defaults\n"
+        "Configure discovery parameters\n"
+        "LDP Link Hellos\n"
+        "Hello holdtime\n"
+        "Time (seconds) - 65535 implies infinite\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "hello_type", .value = "hello" },
+       &(struct vty_arg) { .name = "seconds", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_disc_holdtime (vty, args);
+ }
+ DEFUN (ldp_no_discovery_hello_interval_disc_time,
+        ldp_no_discovery_hello_interval_disc_time_cmd,
 -       "no discovery targeted-hello holdtime <1-65535>",
++       "no discovery hello interval (1-65535)",
+        "Negate a command or set its defaults\n"
+        "Configure discovery parameters\n"
+        "LDP Link Hellos\n"
+        "Hello interval\n"
+        "Time (seconds)\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "hello_type", .value = "hello" },
+       &(struct vty_arg) { .name = "seconds", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_disc_interval (vty, args);
+ }
+ DEFUN (ldp_no_discovery_targeted_hello_holdtime_disc_time,
+        ldp_no_discovery_targeted_hello_holdtime_disc_time_cmd,
 -       "no discovery targeted-hello interval <1-65535>",
++       "no discovery targeted-hello holdtime (1-65535)",
+        "Negate a command or set its defaults\n"
+        "Configure discovery parameters\n"
+        "LDP Targeted Hellos\n"
+        "Targeted hello holdtime\n"
+        "Time (seconds) - 65535 implies infinite\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" },
+       &(struct vty_arg) { .name = "seconds", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_disc_holdtime (vty, args);
+ }
+ DEFUN (ldp_no_discovery_targeted_hello_interval_disc_time,
+        ldp_no_discovery_targeted_hello_interval_disc_time_cmd,
 -       "no neighbor A.B.C.D session holdtime <15-65535>",
++       "no discovery targeted-hello interval (1-65535)",
+        "Negate a command or set its defaults\n"
+        "Configure discovery parameters\n"
+        "LDP Targeted Hellos\n"
+        "Targeted hello interval\n"
+        "Time (seconds)\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" },
+       &(struct vty_arg) { .name = "seconds", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_disc_interval (vty, args);
+ }
+ DEFUN (ldp_no_dual_stack_transport_connection_prefer_ipv4,
+        ldp_no_dual_stack_transport_connection_prefer_ipv4_cmd,
+        "no dual-stack transport-connection prefer ipv4",
+        "Negate a command or set its defaults\n"
+        "Configure dual stack parameters\n"
+        "Configure TCP transport parameters\n"
+        "Configure prefered address family for TCP transport connection with neighbor\n"
+        "IPv4\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       NULL
+     };
+   return ldp_vty_trans_pref_ipv4 (vty, args);
+ }
+ DEFUN (ldp_no_dual_stack_cisco_interop,
+        ldp_no_dual_stack_cisco_interop_cmd,
+        "no dual-stack cisco-interop",
+        "Negate a command or set its defaults\n"
+        "Configure dual stack parameters\n"
+        "Use Cisco non-compliant format to send and interpret the Dual-Stack capability TLV\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       NULL
+     };
+   return ldp_vty_ds_cisco_interop (vty, args);
+ }
+ DEFUN (ldp_no_neighbor_ipv4_password_word,
+        ldp_no_neighbor_ipv4_password_word_cmd,
+        "no neighbor A.B.C.D password WORD",
+        "Negate a command or set its defaults\n"
+        "Configure neighbor parameters\n"
+        "LDP Id of neighbor\n"
+        "Configure password for MD5 authentication\n"
+        "The password\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
+       &(struct vty_arg) { .name = "password", .value = argv[1] },
+       NULL
+     };
+   return ldp_vty_neighbor_password (vty, args);
+ }
+ DEFUN (ldp_no_neighbor_ipv4_session_holdtime_session_time,
+        ldp_no_neighbor_ipv4_session_holdtime_session_time_cmd,
 -       "no neighbor A.B.C.D ttl-security hops <1-254>",
++       "no neighbor A.B.C.D session holdtime (15-65535)",
+        "Negate a command or set its defaults\n"
+        "Configure neighbor parameters\n"
+        "LDP Id of neighbor\n"
+        "Configure session parameters\n"
+        "Configure session holdtime\n"
+        "Time (seconds)\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
+       &(struct vty_arg) { .name = "seconds", .value = argv[1] },
+       NULL
+     };
+   return ldp_vty_session_holdtime (vty, args);
+ }
+ DEFUN (ldp_no_neighbor_ipv4_ttl_security_disable,
+        ldp_no_neighbor_ipv4_ttl_security_disable_cmd,
+        "no neighbor A.B.C.D ttl-security disable",
+        "Negate a command or set its defaults\n"
+        "Configure neighbor parameters\n"
+        "LDP Id of neighbor\n"
+        "LDP ttl security check\n"
+        "Disable ttl security\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_neighbor_ttl_security (vty, args);
+ }
+ DEFUN (ldp_no_neighbor_ipv4_ttl_security_hops_hops,
+        ldp_no_neighbor_ipv4_ttl_security_hops_hops_cmd,
 -       "session holdtime <15-65535>",
++       "no neighbor A.B.C.D ttl-security hops (1-254)",
+        "Negate a command or set its defaults\n"
+        "Configure neighbor parameters\n"
+        "LDP Id of neighbor\n"
+        "LDP ttl security check\n"
+        "IP hops\n"
+        "maximum number of hops\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "lsr_id", .value = argv[0] },
+       &(struct vty_arg) { .name = "hops", .value = argv[1] },
+       NULL
+     };
+   return ldp_vty_neighbor_ttl_security (vty, args);
+ }
+ DEFUN (ldp_no_router_id_ipv4,
+        ldp_no_router_id_ipv4_cmd,
+        "no router-id A.B.C.D",
+        "Negate a command or set its defaults\n"
+        "Configure router Id\n"
+        "LSR Id (in form of an IPv4 address)\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_router_id (vty, args);
+ }
+ DEFUN (ldp_discovery_targeted_hello_accept,
+        ldp_discovery_targeted_hello_accept_cmd,
+        "discovery targeted-hello accept",
+        "Configure discovery parameters\n"
+        "LDP Targeted Hellos\n"
+        "Accept and respond to targeted hellos\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" },
+       NULL
+     };
+   return ldp_vty_targeted_hello_accept (vty, args);
+ }
+ DEFUN (ldp_label_local_advertise_explicit_null,
+        ldp_label_local_advertise_explicit_null_cmd,
+        "label local advertise explicit-null",
+        "Configure label control and policies\n"
+        "Configure local label control and policies\n"
+        "Configure outbound label advertisement control\n"
+        "Configure explicit-null advertisement\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_explicit_null (vty, args);
+ }
+ DEFUN (ldp_ttl_security_disable,
+        ldp_ttl_security_disable_cmd,
+        "ttl-security disable",
+        "LDP ttl security check\n"
+        "Disable ttl security\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_ttl_security (vty, args);
+ }
+ DEFUN (ldp_session_holdtime_session_time,
+        ldp_session_holdtime_session_time_cmd,
 -       "no session holdtime <15-65535>",
++       "session holdtime (15-65535)",
+        "Configure session parameters\n"
+        "Configure session holdtime\n"
+        "Time (seconds)\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "seconds", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_session_holdtime (vty, args);
+ }
+ DEFUN (ldp_interface_ifname,
+        ldp_interface_ifname_cmd,
+        "interface IFNAME",
+        "Enable LDP on an interface and enter interface submode\n"
+        "Interface's name\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "ifname", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_interface (vty, args);
+ }
+ DEFUN (ldp_discovery_transport_address_ipv4,
+        ldp_discovery_transport_address_ipv4_cmd,
+        "discovery transport-address A.B.C.D",
+        "Configure discovery parameters\n"
+        "Specify transport address for TCP connection\n"
+        "IP address to be used as transport address\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_trans_addr (vty, args);
+ }
+ DEFUN (ldp_neighbor_ipv4_targeted,
+        ldp_neighbor_ipv4_targeted_cmd,
+        "neighbor A.B.C.D targeted",
+        "Configure neighbor parameters\n"
+        "IP address of neighbor\n"
+        "Establish targeted session\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_neighbor_targeted (vty, args);
+ }
+ DEFUN (ldp_no_discovery_targeted_hello_accept,
+        ldp_no_discovery_targeted_hello_accept_cmd,
+        "no discovery targeted-hello accept",
+        "Negate a command or set its defaults\n"
+        "Configure discovery parameters\n"
+        "LDP Targeted Hellos\n"
+        "Accept and respond to targeted hellos\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" },
+       NULL
+     };
+   return ldp_vty_targeted_hello_accept (vty, args);
+ }
+ DEFUN (ldp_no_label_local_advertise_explicit_null,
+        ldp_no_label_local_advertise_explicit_null_cmd,
+        "no label local advertise explicit-null",
+        "Negate a command or set its defaults\n"
+        "Configure label control and policies\n"
+        "Configure local label control and policies\n"
+        "Configure outbound label advertisement control\n"
+        "Configure explicit-null advertisement\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       NULL
+     };
+   return ldp_vty_explicit_null (vty, args);
+ }
+ DEFUN (ldp_no_ttl_security_disable,
+        ldp_no_ttl_security_disable_cmd,
+        "no ttl-security disable",
+        "Negate a command or set its defaults\n"
+        "LDP ttl security check\n"
+        "Disable ttl security\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       NULL
+     };
+   return ldp_vty_ttl_security (vty, args);
+ }
+ DEFUN (ldp_no_session_holdtime_session_time,
+        ldp_no_session_holdtime_session_time_cmd,
 -       "mtu <1500-9180>",
++       "no session holdtime (15-65535)",
+        "Negate a command or set its defaults\n"
+        "Configure session parameters\n"
+        "Configure session holdtime\n"
+        "Time (seconds)\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "seconds", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_session_holdtime (vty, args);
+ }
+ DEFUN (ldp_no_interface_ifname,
+        ldp_no_interface_ifname_cmd,
+        "no interface IFNAME",
+        "Negate a command or set its defaults\n"
+        "Enable LDP on an interface and enter interface submode\n"
+        "Interface's name\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "ifname", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_interface (vty, args);
+ }
+ DEFUN (ldp_no_discovery_transport_address_ipv4,
+        ldp_no_discovery_transport_address_ipv4_cmd,
+        "no discovery transport-address A.B.C.D",
+        "Negate a command or set its defaults\n"
+        "Configure discovery parameters\n"
+        "Specify transport address for TCP connection\n"
+        "IP address to be used as transport address\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_trans_addr (vty, args);
+ }
+ DEFUN (ldp_no_neighbor_ipv4_targeted,
+        ldp_no_neighbor_ipv4_targeted_cmd,
+        "no neighbor A.B.C.D targeted",
+        "Negate a command or set its defaults\n"
+        "Configure neighbor parameters\n"
+        "IP address of neighbor\n"
+        "Establish targeted session\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_neighbor_targeted (vty, args);
+ }
+ DEFUN (ldp_discovery_transport_address_ipv6,
+        ldp_discovery_transport_address_ipv6_cmd,
+        "discovery transport-address X:X::X:X",
+        "Configure discovery parameters\n"
+        "Specify transport address for TCP connection\n"
+        "IPv6 address to be used as transport address\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_trans_addr (vty, args);
+ }
+ DEFUN (ldp_neighbor_ipv6_targeted,
+        ldp_neighbor_ipv6_targeted_cmd,
+        "neighbor X:X::X:X targeted",
+        "Configure neighbor parameters\n"
+        "IPv6 address of neighbor\n"
+        "Establish targeted session\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_neighbor_targeted (vty, args);
+ }
+ DEFUN (ldp_no_discovery_transport_address_ipv6,
+        ldp_no_discovery_transport_address_ipv6_cmd,
+        "no discovery transport-address X:X::X:X",
+        "Negate a command or set its defaults\n"
+        "Configure discovery parameters\n"
+        "Specify transport address for TCP connection\n"
+        "IPv6 address to be used as transport address\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_trans_addr (vty, args);
+ }
+ DEFUN (ldp_no_neighbor_ipv6_targeted,
+        ldp_no_neighbor_ipv6_targeted_cmd,
+        "no neighbor X:X::X:X targeted",
+        "Negate a command or set its defaults\n"
+        "Configure neighbor parameters\n"
+        "IPv6 address of neighbor\n"
+        "Establish targeted session\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_neighbor_targeted (vty, args);
+ }
+ DEFUN (ldp_bridge_ifname,
+        ldp_bridge_ifname_cmd,
+        "bridge IFNAME",
+        "Bridge interface\n"
+        "Interface's name\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "ifname", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_bridge (vty, args);
+ }
+ DEFUN (ldp_mtu_mtu,
+        ldp_mtu_mtu_cmd,
 -       "vc type (ethernet|ethernet-tagged)",
++       "mtu (1500-9180)",
+        "set Maximum Transmission Unit\n"
+        "Maximum Transmission Unit value\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "mtu", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_mtu (vty, args);
+ }
+ DEFUN (ldp_member_interface_ifname,
+        ldp_member_interface_ifname_cmd,
+        "member interface IFNAME",
+        "L2VPN member configuration\n"
+        "Local interface\n"
+        "Interface's name\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "ifname", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_interface (vty, args);
+ }
+ DEFUN (ldp_member_pseudowire_ifname,
+        ldp_member_pseudowire_ifname_cmd,
+        "member pseudowire IFNAME",
+        "L2VPN member configuration\n"
+        "Pseudowire interface\n"
+        "Interface's name\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "ifname", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_pseudowire (vty, args);
+ }
+ DEFUN (ldp_vc_type_pwtype,
+        ldp_vc_type_pwtype_cmd,
 -       "no mtu <1500-9180>",
++       "vc type <ethernet|ethernet-tagged>",
+        "Virtual Circuit options\n"
+        "Virtual Circuit type to use\n"
+        "Ethernet (type 5)\n"
+        "Ethernet-tagged (type 4)\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "type", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_pwtype (vty, args);
+ }
+ DEFUN (ldp_no_bridge_ifname,
+        ldp_no_bridge_ifname_cmd,
+        "no bridge IFNAME",
+        "Negate a command or set its defaults\n"
+        "Bridge interface\n"
+        "Interface's name\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "ifname", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_bridge (vty, args);
+ }
+ DEFUN (ldp_no_mtu_mtu,
+        ldp_no_mtu_mtu_cmd,
 -       "no vc type (ethernet|ethernet-tagged)",
++       "no mtu (1500-9180)",
+        "Negate a command or set its defaults\n"
+        "set Maximum Transmission Unit\n"
+        "Maximum Transmission Unit value\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "mtu", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_mtu (vty, args);
+ }
+ DEFUN (ldp_no_member_interface_ifname,
+        ldp_no_member_interface_ifname_cmd,
+        "no member interface IFNAME",
+        "Negate a command or set its defaults\n"
+        "L2VPN member configuration\n"
+        "Local interface\n"
+        "Interface's name\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "ifname", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_interface (vty, args);
+ }
+ DEFUN (ldp_no_member_pseudowire_ifname,
+        ldp_no_member_pseudowire_ifname_cmd,
+        "no member pseudowire IFNAME",
+        "Negate a command or set its defaults\n"
+        "L2VPN member configuration\n"
+        "Pseudowire interface\n"
+        "Interface's name\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "ifname", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_pseudowire (vty, args);
+ }
+ DEFUN (ldp_no_vc_type_pwtype,
+        ldp_no_vc_type_pwtype_cmd,
 -       "control-word (exclude|include)",
++       "no vc type <ethernet|ethernet-tagged>",
+        "Negate a command or set its defaults\n"
+        "Virtual Circuit options\n"
+        "Virtual Circuit type to use\n"
+        "Ethernet (type 5)\n"
+        "Ethernet-tagged (type 4)\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "type", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_pwtype (vty, args);
+ }
+ DEFUN (ldp_control_word_cword,
+        ldp_control_word_cword_cmd,
 -       "neighbor address (A.B.C.D|X:X::X:X)",
++       "control-word <exclude|include>",
+        "Control-word options\n"
+        "Exclude control-word in pseudowire packets\n"
+        "Include control-word in pseudowire packets\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "preference", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_pw_cword (vty, args);
+ }
+ DEFUN (ldp_neighbor_address_addr,
+        ldp_neighbor_address_addr_cmd,
 -       "pw-id <1-4294967295>",
++       "neighbor address <A.B.C.D|X:X::X:X>",
+        "Remote endpoint configuration\n"
+        "Specify the IPv4 or IPv6 address of the remote endpoint\n"
+        "IPv4 address\n"
+        "IPv6 address\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_pw_nbr_addr (vty, args);
+ }
+ DEFUN (ldp_neighbor_lsr_id_ipv4,
+        ldp_neighbor_lsr_id_ipv4_cmd,
+        "neighbor lsr-id A.B.C.D",
+        "Remote endpoint configuration\n"
+        "Specify the LSR-ID of the remote endpoint\n"
+        "IPv4 address\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "lsr-id", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_pw_nbr_id (vty, args);
+ }
+ DEFUN (ldp_pw_id_pwid,
+        ldp_pw_id_pwid_cmd,
 -       "no control-word (exclude|include)",
++       "pw-id (1-4294967295)",
+        "Set the Virtual Circuit ID\n"
+        "Virtual Circuit ID value\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "pwid", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_pw_pwid (vty, args);
+ }
+ DEFUN (ldp_pw_status_disable,
+        ldp_pw_status_disable_cmd,
+        "pw-status disable",
+        "Configure PW status\n"
+        "Disable PW status\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_l2vpn_pw_pwstatus (vty, args);
+ }
+ DEFUN (ldp_no_control_word_cword,
+        ldp_no_control_word_cword_cmd,
 -       "no neighbor address (A.B.C.D|X:X::X:X)",
++       "no control-word <exclude|include>",
+        "Negate a command or set its defaults\n"
+        "Control-word options\n"
+        "Exclude control-word in pseudowire packets\n"
+        "Include control-word in pseudowire packets\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "preference", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_pw_cword (vty, args);
+ }
+ DEFUN (ldp_no_neighbor_address_addr,
+        ldp_no_neighbor_address_addr_cmd,
 -       "no pw-id <1-4294967295>",
++       "no neighbor address <A.B.C.D|X:X::X:X>",
+        "Negate a command or set its defaults\n"
+        "Remote endpoint configuration\n"
+        "Specify the IPv4 or IPv6 address of the remote endpoint\n"
+        "IPv4 address\n"
+        "IPv6 address\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_pw_nbr_addr (vty, args);
+ }
+ DEFUN (ldp_no_neighbor_lsr_id_ipv4,
+        ldp_no_neighbor_lsr_id_ipv4_cmd,
+        "no neighbor lsr-id A.B.C.D",
+        "Negate a command or set its defaults\n"
+        "Remote endpoint configuration\n"
+        "Specify the LSR-ID of the remote endpoint\n"
+        "IPv4 address\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "lsr-id", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_pw_nbr_id (vty, args);
+ }
+ DEFUN (ldp_no_pw_id_pwid,
+        ldp_no_pw_id_pwid_cmd,
 -       "show mpls ldp (ipv4|ipv6) binding",
++       "no pw-id (1-4294967295)",
+        "Negate a command or set its defaults\n"
+        "Set the Virtual Circuit ID\n"
+        "Virtual Circuit ID value\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "pwid", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_l2vpn_pw_pwid (vty, args);
+ }
+ DEFUN (ldp_no_pw_status_disable,
+        ldp_no_pw_status_disable_cmd,
+        "no pw-status disable",
+        "Negate a command or set its defaults\n"
+        "Configure PW status\n"
+        "Disable PW status\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       NULL
+     };
+   return ldp_vty_l2vpn_pw_pwstatus (vty, args);
+ }
+ DEFUN (ldp_show_mpls_ldp_neighbor,
+        ldp_show_mpls_ldp_neighbor_cmd,
+        "show mpls ldp neighbor",
+        "Show running system information\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Neighbor information\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_show_neighbor (vty, args);
+ }
+ DEFUN (ldp_show_mpls_ldp_binding,
+        ldp_show_mpls_ldp_binding_cmd,
+        "show mpls ldp binding",
+        "Show running system information\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Label Information Base (LIB) information\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_show_binding (vty, args);
+ }
+ DEFUN (ldp_show_mpls_ldp_discovery,
+        ldp_show_mpls_ldp_discovery_cmd,
+        "show mpls ldp discovery",
+        "Show running system information\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Discovery Hello Information\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_show_discovery (vty, args);
+ }
+ DEFUN (ldp_show_mpls_ldp_interface,
+        ldp_show_mpls_ldp_interface_cmd,
+        "show mpls ldp interface",
+        "Show running system information\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "interface information\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_show_interface (vty, args);
+ }
+ DEFUN (ldp_show_mpls_ldp_address_family_binding,
+        ldp_show_mpls_ldp_address_family_binding_cmd,
 -       "show mpls ldp (ipv4|ipv6) discovery",
++       "show mpls ldp <ipv4|ipv6> binding",
+        "Show running system information\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "IPv4 Address Family\n"
+        "IPv6 Address Family\n"
+        "Label Information Base (LIB) information\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "address-family", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_show_binding (vty, args);
+ }
+ DEFUN (ldp_show_mpls_ldp_address_family_discovery,
+        ldp_show_mpls_ldp_address_family_discovery_cmd,
 -       "show mpls ldp (ipv4|ipv6) interface",
++       "show mpls ldp <ipv4|ipv6> discovery",
+        "Show running system information\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "IPv4 Address Family\n"
+        "IPv6 Address Family\n"
+        "Discovery Hello Information\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "address-family", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_show_discovery (vty, args);
+ }
+ DEFUN (ldp_show_mpls_ldp_address_family_interface,
+        ldp_show_mpls_ldp_address_family_interface_cmd,
 -       "clear mpls ldp neighbor (A.B.C.D|X:X::X:X)",
++       "show mpls ldp <ipv4|ipv6> interface",
+        "Show running system information\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "IPv4 Address Family\n"
+        "IPv6 Address Family\n"
+        "interface information\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "address-family", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_show_interface (vty, args);
+ }
+ DEFUN (ldp_show_l2vpn_atom_binding,
+        ldp_show_l2vpn_atom_binding_cmd,
+        "show l2vpn atom binding",
+        "Show running system information\n"
+        "Show information about Layer2 VPN\n"
+        "Show Any Transport over MPLS information\n"
+        "Show AToM label binding information\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_show_atom_binding (vty, args);
+ }
+ DEFUN (ldp_show_l2vpn_atom_vc,
+        ldp_show_l2vpn_atom_vc_cmd,
+        "show l2vpn atom vc",
+        "Show running system information\n"
+        "Show information about Layer2 VPN\n"
+        "Show Any Transport over MPLS information\n"
+        "Show AToM virtual circuit information\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_show_atom_vc (vty, args);
+ }
+ DEFUN (ldp_show_debugging_mpls_ldp,
+        ldp_show_debugging_mpls_ldp_cmd,
+        "show debugging mpls ldp",
+        "Show running system information\n"
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_show_debugging (vty, args);
+ }
+ DEFUN (ldp_clear_mpls_ldp_neighbor,
+        ldp_clear_mpls_ldp_neighbor_cmd,
+        "clear mpls ldp neighbor",
+        "Reset functions\n"
+        "Reset MPLS statistical information\n"
+        "Clear LDP state\n"
+        "Clear LDP neighbor sessions\n")
+ {
+   struct vty_arg *args[] = { NULL };
+   return ldp_vty_clear_nbr (vty, args);
+ }
+ DEFUN (ldp_clear_mpls_ldp_neighbor_addr,
+        ldp_clear_mpls_ldp_neighbor_addr_cmd,
 -       "debug mpls ldp discovery hello (recv|sent)",
++       "clear mpls ldp neighbor <A.B.C.D|X:X::X:X>",
+        "Reset functions\n"
+        "Reset MPLS statistical information\n"
+        "Clear LDP state\n"
+        "Clear LDP neighbor sessions\n"
+        "IPv4 address\n"
+        "IPv6 address\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "addr", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_clear_nbr (vty, args);
+ }
+ DEFUN (ldp_debug_mpls_ldp_discovery_hello_dir,
+        ldp_debug_mpls_ldp_discovery_hello_dir_cmd,
 -       "no debug mpls ldp discovery hello (recv|sent)",
++       "debug mpls ldp discovery hello <recv|sent>",
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Discovery messages\n"
+        "Discovery hello message\n"
+        "Received messages\n"
+        "Sent messages\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "type", .value = "discovery" },
+       &(struct vty_arg) { .name = "dir", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_debug_mpls_ldp_errors,
+        ldp_debug_mpls_ldp_errors_cmd,
+        "debug mpls ldp errors",
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Errors\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "type", .value = "errors" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_debug_mpls_ldp_event,
+        ldp_debug_mpls_ldp_event_cmd,
+        "debug mpls ldp event",
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "LDP event information\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "type", .value = "event" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_debug_mpls_ldp_messages_recv,
+        ldp_debug_mpls_ldp_messages_recv_cmd,
+        "debug mpls ldp messages recv",
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Messages\n"
+        "Received messages, excluding periodic Keep Alives\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "type", .value = "messages" },
+       &(struct vty_arg) { .name = "dir", .value = "recv" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_debug_mpls_ldp_messages_recv_all,
+        ldp_debug_mpls_ldp_messages_recv_all_cmd,
+        "debug mpls ldp messages recv all",
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Messages\n"
+        "Received messages, excluding periodic Keep Alives\n"
+        "Received messages, including periodic Keep Alives\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "type", .value = "messages" },
+       &(struct vty_arg) { .name = "dir", .value = "recv" },
+       &(struct vty_arg) { .name = "all", .value = "all" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_debug_mpls_ldp_messages_sent,
+        ldp_debug_mpls_ldp_messages_sent_cmd,
+        "debug mpls ldp messages sent",
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Messages\n"
+        "Sent messages, excluding periodic Keep Alives\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "type", .value = "messages" },
+       &(struct vty_arg) { .name = "dir", .value = "sent" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_debug_mpls_ldp_messages_sent_all,
+        ldp_debug_mpls_ldp_messages_sent_all_cmd,
+        "debug mpls ldp messages sent all",
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Messages\n"
+        "Sent messages, excluding periodic Keep Alives\n"
+        "Sent messages, including periodic Keep Alives\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "type", .value = "messages" },
+       &(struct vty_arg) { .name = "dir", .value = "sent" },
+       &(struct vty_arg) { .name = "all", .value = "all" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_debug_mpls_ldp_zebra,
+        ldp_debug_mpls_ldp_zebra_cmd,
+        "debug mpls ldp zebra",
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "LDP zebra information\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "type", .value = "zebra" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_no_debug_mpls_ldp_discovery_hello_dir,
+        ldp_no_debug_mpls_ldp_discovery_hello_dir_cmd,
++       "no debug mpls ldp discovery hello <recv|sent>",
+        "Negate a command or set its defaults\n"
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Discovery messages\n"
+        "Discovery hello message\n"
+        "Received messages\n"
+        "Sent messages\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "type", .value = "discovery" },
+       &(struct vty_arg) { .name = "dir", .value = argv[0] },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_no_debug_mpls_ldp_errors,
+        ldp_no_debug_mpls_ldp_errors_cmd,
+        "no debug mpls ldp errors",
+        "Negate a command or set its defaults\n"
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Errors\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "type", .value = "errors" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_no_debug_mpls_ldp_event,
+        ldp_no_debug_mpls_ldp_event_cmd,
+        "no debug mpls ldp event",
+        "Negate a command or set its defaults\n"
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "LDP event information\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "type", .value = "event" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_no_debug_mpls_ldp_messages_recv,
+        ldp_no_debug_mpls_ldp_messages_recv_cmd,
+        "no debug mpls ldp messages recv",
+        "Negate a command or set its defaults\n"
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Messages\n"
+        "Received messages, excluding periodic Keep Alives\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "type", .value = "messages" },
+       &(struct vty_arg) { .name = "dir", .value = "recv" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_no_debug_mpls_ldp_messages_recv_all,
+        ldp_no_debug_mpls_ldp_messages_recv_all_cmd,
+        "no debug mpls ldp messages recv all",
+        "Negate a command or set its defaults\n"
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Messages\n"
+        "Received messages, excluding periodic Keep Alives\n"
+        "Received messages, including periodic Keep Alives\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "type", .value = "messages" },
+       &(struct vty_arg) { .name = "dir", .value = "recv" },
+       &(struct vty_arg) { .name = "all", .value = "all" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_no_debug_mpls_ldp_messages_sent,
+        ldp_no_debug_mpls_ldp_messages_sent_cmd,
+        "no debug mpls ldp messages sent",
+        "Negate a command or set its defaults\n"
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Messages\n"
+        "Sent messages, excluding periodic Keep Alives\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "type", .value = "messages" },
+       &(struct vty_arg) { .name = "dir", .value = "sent" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_no_debug_mpls_ldp_messages_sent_all,
+        ldp_no_debug_mpls_ldp_messages_sent_all_cmd,
+        "no debug mpls ldp messages sent all",
+        "Negate a command or set its defaults\n"
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "Messages\n"
+        "Sent messages, excluding periodic Keep Alives\n"
+        "Sent messages, including periodic Keep Alives\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "type", .value = "messages" },
+       &(struct vty_arg) { .name = "dir", .value = "sent" },
+       &(struct vty_arg) { .name = "all", .value = "all" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ DEFUN (ldp_no_debug_mpls_ldp_zebra,
+        ldp_no_debug_mpls_ldp_zebra_cmd,
+        "no debug mpls ldp zebra",
+        "Negate a command or set its defaults\n"
+        "Debugging functions\n"
+        "MPLS information\n"
+        "Label Distribution Protocol\n"
+        "LDP zebra information\n")
+ {
+   struct vty_arg *args[] =
+     {
+       &(struct vty_arg) { .name = "no", .value = "no" },
+       &(struct vty_arg) { .name = "type", .value = "zebra" },
+       NULL
+     };
+   return ldp_vty_debug (vty, args);
+ }
+ void
+ ldp_vty_init (void)
+ {
+   install_element (CONFIG_NODE, &ldp_mpls_ldp_cmd);
+   install_element (CONFIG_NODE, &ldp_l2vpn_word_type_vpls_cmd);
+   install_element (CONFIG_NODE, &ldp_no_mpls_ldp_cmd);
+   install_element (CONFIG_NODE, &ldp_no_l2vpn_word_type_vpls_cmd);
+   install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_discovery_hello_dir_cmd);
+   install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_errors_cmd);
+   install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_event_cmd);
+   install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_messages_recv_cmd);
+   install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_messages_recv_all_cmd);
+   install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_messages_sent_cmd);
+   install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_messages_sent_all_cmd);
+   install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_zebra_cmd);
+   install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_discovery_hello_dir_cmd);
+   install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_errors_cmd);
+   install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_event_cmd);
+   install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_messages_recv_cmd);
+   install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_messages_recv_all_cmd);
+   install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_messages_sent_cmd);
+   install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_messages_sent_all_cmd);
+   install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_zebra_cmd);
+   install_node (&ldp_node, ldp_config_write);
+   install_default (LDP_NODE);
+   install_element (LDP_NODE, &ldp_address_family_ipv4_cmd);
+   install_element (LDP_NODE, &ldp_address_family_ipv6_cmd);
+   install_element (LDP_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd);
+   install_element (LDP_NODE, &ldp_discovery_hello_interval_disc_time_cmd);
+   install_element (LDP_NODE, &ldp_discovery_targeted_hello_holdtime_disc_time_cmd);
+   install_element (LDP_NODE, &ldp_discovery_targeted_hello_interval_disc_time_cmd);
+   install_element (LDP_NODE, &ldp_dual_stack_transport_connection_prefer_ipv4_cmd);
+   install_element (LDP_NODE, &ldp_dual_stack_cisco_interop_cmd);
+   install_element (LDP_NODE, &ldp_neighbor_ipv4_password_word_cmd);
+   install_element (LDP_NODE, &ldp_neighbor_ipv4_session_holdtime_session_time_cmd);
+   install_element (LDP_NODE, &ldp_neighbor_ipv4_ttl_security_disable_cmd);
+   install_element (LDP_NODE, &ldp_neighbor_ipv4_ttl_security_hops_hops_cmd);
+   install_element (LDP_NODE, &ldp_router_id_ipv4_cmd);
+   install_element (LDP_NODE, &ldp_no_address_family_ipv4_cmd);
+   install_element (LDP_NODE, &ldp_no_address_family_ipv6_cmd);
+   install_element (LDP_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd);
+   install_element (LDP_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd);
+   install_element (LDP_NODE, &ldp_no_discovery_targeted_hello_holdtime_disc_time_cmd);
+   install_element (LDP_NODE, &ldp_no_discovery_targeted_hello_interval_disc_time_cmd);
+   install_element (LDP_NODE, &ldp_no_dual_stack_transport_connection_prefer_ipv4_cmd);
+   install_element (LDP_NODE, &ldp_no_dual_stack_cisco_interop_cmd);
+   install_element (LDP_NODE, &ldp_no_neighbor_ipv4_password_word_cmd);
+   install_element (LDP_NODE, &ldp_no_neighbor_ipv4_session_holdtime_session_time_cmd);
+   install_element (LDP_NODE, &ldp_no_neighbor_ipv4_ttl_security_disable_cmd);
+   install_element (LDP_NODE, &ldp_no_neighbor_ipv4_ttl_security_hops_hops_cmd);
+   install_element (LDP_NODE, &ldp_no_router_id_ipv4_cmd);
+   install_node (&ldp_ipv4_node, NULL);
+   install_default (LDP_IPV4_NODE);
+   install_element (LDP_IPV4_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_discovery_hello_interval_disc_time_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_discovery_targeted_hello_holdtime_disc_time_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_discovery_targeted_hello_interval_disc_time_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_discovery_targeted_hello_accept_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_label_local_advertise_explicit_null_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_ttl_security_disable_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_session_holdtime_session_time_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_interface_ifname_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_discovery_transport_address_ipv4_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_neighbor_ipv4_targeted_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_no_discovery_targeted_hello_holdtime_disc_time_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_no_discovery_targeted_hello_interval_disc_time_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_no_discovery_targeted_hello_accept_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_no_label_local_advertise_explicit_null_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_no_ttl_security_disable_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_no_session_holdtime_session_time_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_no_interface_ifname_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_no_discovery_transport_address_ipv4_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_no_neighbor_ipv4_targeted_cmd);
+   install_node (&ldp_ipv6_node, NULL);
+   install_default (LDP_IPV6_NODE);
+   install_element (LDP_IPV6_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_discovery_hello_interval_disc_time_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_discovery_targeted_hello_holdtime_disc_time_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_discovery_targeted_hello_interval_disc_time_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_discovery_targeted_hello_accept_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_label_local_advertise_explicit_null_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_ttl_security_disable_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_session_holdtime_session_time_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_interface_ifname_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_discovery_transport_address_ipv6_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_neighbor_ipv6_targeted_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_no_discovery_targeted_hello_holdtime_disc_time_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_no_discovery_targeted_hello_interval_disc_time_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_no_discovery_targeted_hello_accept_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_no_label_local_advertise_explicit_null_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_no_ttl_security_disable_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_no_session_holdtime_session_time_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_no_interface_ifname_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_no_discovery_transport_address_ipv6_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_no_neighbor_ipv6_targeted_cmd);
+   install_node (&ldp_ipv4_iface_node, NULL);
+   install_default (LDP_IPV4_IFACE_NODE);
+   install_element (LDP_IPV4_IFACE_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd);
+   install_element (LDP_IPV4_IFACE_NODE, &ldp_discovery_hello_interval_disc_time_cmd);
+   install_element (LDP_IPV4_IFACE_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd);
+   install_element (LDP_IPV4_IFACE_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd);
+   install_node (&ldp_ipv6_iface_node, NULL);
+   install_default (LDP_IPV6_IFACE_NODE);
+   install_element (LDP_IPV6_IFACE_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd);
+   install_element (LDP_IPV6_IFACE_NODE, &ldp_discovery_hello_interval_disc_time_cmd);
+   install_element (LDP_IPV6_IFACE_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd);
+   install_element (LDP_IPV6_IFACE_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd);
+   install_node (&ldp_l2vpn_node, ldp_l2vpn_config_write);
+   install_default (LDP_L2VPN_NODE);
+   install_element (LDP_L2VPN_NODE, &ldp_bridge_ifname_cmd);
+   install_element (LDP_L2VPN_NODE, &ldp_mtu_mtu_cmd);
+   install_element (LDP_L2VPN_NODE, &ldp_member_interface_ifname_cmd);
+   install_element (LDP_L2VPN_NODE, &ldp_member_pseudowire_ifname_cmd);
+   install_element (LDP_L2VPN_NODE, &ldp_vc_type_pwtype_cmd);
+   install_element (LDP_L2VPN_NODE, &ldp_no_bridge_ifname_cmd);
+   install_element (LDP_L2VPN_NODE, &ldp_no_mtu_mtu_cmd);
+   install_element (LDP_L2VPN_NODE, &ldp_no_member_interface_ifname_cmd);
+   install_element (LDP_L2VPN_NODE, &ldp_no_member_pseudowire_ifname_cmd);
+   install_element (LDP_L2VPN_NODE, &ldp_no_vc_type_pwtype_cmd);
+   install_node (&ldp_pseudowire_node, NULL);
+   install_default (LDP_PSEUDOWIRE_NODE);
+   install_element (LDP_PSEUDOWIRE_NODE, &ldp_control_word_cword_cmd);
+   install_element (LDP_PSEUDOWIRE_NODE, &ldp_neighbor_address_addr_cmd);
+   install_element (LDP_PSEUDOWIRE_NODE, &ldp_neighbor_lsr_id_ipv4_cmd);
+   install_element (LDP_PSEUDOWIRE_NODE, &ldp_pw_id_pwid_cmd);
+   install_element (LDP_PSEUDOWIRE_NODE, &ldp_pw_status_disable_cmd);
+   install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_control_word_cword_cmd);
+   install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_neighbor_address_addr_cmd);
+   install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_neighbor_lsr_id_ipv4_cmd);
+   install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_pw_id_pwid_cmd);
+   install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_pw_status_disable_cmd);
+   install_node (&ldp_debug_node, ldp_debug_config_write);
+   install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_discovery_hello_dir_cmd);
+   install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_errors_cmd);
+   install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_event_cmd);
+   install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_messages_recv_cmd);
+   install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_messages_recv_all_cmd);
+   install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_messages_sent_cmd);
+   install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_messages_sent_all_cmd);
+   install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_zebra_cmd);
+   install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_discovery_hello_dir_cmd);
+   install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_errors_cmd);
+   install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_event_cmd);
+   install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_messages_recv_cmd);
+   install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_messages_recv_all_cmd);
+   install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_messages_sent_cmd);
+   install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_messages_sent_all_cmd);
+   install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_zebra_cmd);
+   install_element (VIEW_NODE, &ldp_show_mpls_ldp_neighbor_cmd);
+   install_element (VIEW_NODE, &ldp_show_mpls_ldp_binding_cmd);
+   install_element (VIEW_NODE, &ldp_show_mpls_ldp_discovery_cmd);
+   install_element (VIEW_NODE, &ldp_show_mpls_ldp_interface_cmd);
+   install_element (VIEW_NODE, &ldp_show_mpls_ldp_address_family_binding_cmd);
+   install_element (VIEW_NODE, &ldp_show_mpls_ldp_address_family_discovery_cmd);
+   install_element (VIEW_NODE, &ldp_show_mpls_ldp_address_family_interface_cmd);
+   install_element (VIEW_NODE, &ldp_show_l2vpn_atom_binding_cmd);
+   install_element (VIEW_NODE, &ldp_show_l2vpn_atom_vc_cmd);
+   install_element (VIEW_NODE, &ldp_show_debugging_mpls_ldp_cmd);
+   install_element (VIEW_NODE, &ldp_clear_mpls_ldp_neighbor_cmd);
+   install_element (VIEW_NODE, &ldp_clear_mpls_ldp_neighbor_addr_cmd);
+ }
diff --cc lib/Makefile.am
index acaf7e674415a2a9ed3bb89ae8c1ad3a7838b5a7,e95e6f34b7ba119cf6ca362fc7bfb933ef6ba6da..dbf1a82be28a32d82ff7f8e11f615a3276cf8b5a
@@@ -1,9 -1,9 +1,10 @@@
  ## Process this file with automake to produce Makefile.in.
  
- AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
+ AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \
+             -DVTY_DEPRECATE_INDEX
  AM_CFLAGS = $(WERROR)
  DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 +AM_YFLAGS = -d
  
  lib_LTLIBRARIES = libzebra.la
  libzebra_la_LDFLAGS = -version-info 0:0:0 
@@@ -17,9 -15,11 +18,11 @@@ libzebra_la_SOURCES = 
        filter.c routemap.c distribute.c stream.c str.c log.c plist.c \
        zclient.c sockopt.c smux.c agentx.c snmp.c md5.c if_rmap.c keychain.c privs.c \
        sigevent.c pqueue.c jhash.c workqueue.c nexthop.c json.c \
-       ptm_lib.c csv.c bfd.c vrf.c systemd.c ns.c memory.c memory_vty.c
+       ptm_lib.c csv.c bfd.c vrf.c systemd.c ns.c memory.c memory_vty.c \
+       imsg-buffer.c imsg.c skiplist.c \
+       qobj.c
  
 -BUILT_SOURCES = route_types.h gitversion.h
 +BUILT_SOURCES = route_types.h gitversion.h command_parse.h
  
  libzebra_la_DEPENDENCIES = @LIB_REGEX@
  
diff --cc lib/command.c
index 2f83a7fa5e66b9eda475ebcfb9759c289c5ef954,fd4b2e242780980839c273ab2c01a9f8ea5017d3..63cfc695dccc5dba586059e4a1e1eba4e20dc5b0
@@@ -38,8 -33,7 +38,9 @@@
  #include "command.h"
  #include "workqueue.h"
  #include "vrf.h"
 +#include "command_match.h"
 +#include "command_parse.h"
+ #include "qobj.h"
  
  DEFINE_MTYPE(       LIB, HOST,       "Host config")
  DEFINE_MTYPE(       LIB, STRVEC,     "String vector")
@@@ -318,30 -705,22 +313,33 @@@ install_element (enum node_type ntype, 
    /* cmd_init hasn't been called */
    if (!cmdvec)
      return;
 -  
 +
    cnode = vector_slot (cmdvec, ntype);
  
 -  if (cnode == NULL) 
 +  if (cnode == NULL)
      {
        fprintf (stderr, "Command node %d doesn't exist, please check it\n",
 -             ntype);
 -      exit (1);
 +               ntype);
 +      exit (EXIT_FAILURE);
 +    }
 +
 +  // add node to command graph and command vector
 +  // idiotic O(n) deduplication logic, should just use a merkle tree
 +  for (unsigned int i = 0; i < vector_active (cnode->cmd_vector); i++)
 +  {
 +    struct cmd_element *existing = vector_slot (cnode->cmd_vector, i);
 +    if (strmatch (existing->string, cmd->string))
 +    {
 +      zlog_warn ("Duplicate command: %s\n", cmd->string);
 +      return;
      }
 +  }
  
 +  command_parse_format (cnode->cmdgraph, cmd);
    vector_set (cnode->cmd_vector, cmd);
 -  if (cmd->tokens == NULL)
 -    cmd->tokens = cmd_parse_format(cmd->string, cmd->doc);
+   if (ntype == VIEW_NODE)
+     install_element (ENABLE_NODE, cmd);
  }
  
  static const unsigned char itoa64[] =
@@@ -465,217 -844,1678 +463,216 @@@ config_write_host (struct vty *vty
    return 1;
  }
  
 -/* Utility function for getting command vector. */
 -static vector
 -cmd_node_vector (vector v, enum node_type ntype)
 +/* Utility function for getting command graph. */
 +static struct graph *
 +cmd_node_graph (vector v, enum node_type ntype)
  {
    struct cmd_node *cnode = vector_slot (v, ntype);
 -  return cnode->cmd_vector;
 +  return cnode->cmdgraph;
 +}
 +
 +static int
 +cmd_try_do_shortcut (enum node_type node, char* first_word) {
 +  if ( first_word != NULL &&
 +       node != AUTH_NODE &&
 +       node != VIEW_NODE &&
 +       node != AUTH_ENABLE_NODE &&
 +       node != ENABLE_NODE &&
-        node != RESTRICTED_NODE &&
 +       0 == strcmp( "do", first_word ) )
 +    return 1;
 +  return 0;
  }
  
 -/* Completion match types. */
 -enum match_type 
 +/**
 + * Compare function for cmd_token.
 + * Used with qsort to sort command completions.
 + */
 +static int
 +compare_completions (const void *fst, const void *snd)
  {
 -  no_match,
 -  extend_match,
 -  ipv4_prefix_match,
 -  ipv4_match,
 -  ipv6_prefix_match,
 -  ipv6_match,
 -  range_match,
 -  vararg_match,
 -  partly_match,
 -  exact_match 
 -};
 +  struct cmd_token *first = *(struct cmd_token **) fst,
 +                     *secnd = *(struct cmd_token **) snd;
 +  return strcmp (first->text, secnd->text);
 +}
  
 -static enum match_type
 -cmd_ipv4_match (const char *str)
 +/**
 + * Takes a list of completions returned by command_complete,
 + * dedeuplicates them based on both text and description,
 + * sorts them, and returns them as a vector.
 + *
 + * @param completions linked list of cmd_token
 + * @return deduplicated and sorted vector with
 + */
 +static vector
 +completions_to_vec (struct list *completions)
  {
 -  const char *sp;
 -  int dots = 0, nums = 0;
 -  char buf[4];
 +  vector comps = vector_init (VECTOR_MIN_SIZE);
  
 -  if (str == NULL)
 -    return partly_match;
 +  struct listnode *ln;
 +  struct cmd_token *token, *cr = NULL;
 +  unsigned int i, exists;
 +  for (ALL_LIST_ELEMENTS_RO(completions,ln,token))
 +  {
 +    if (token->type == END_TKN && (cr = token))
 +      continue;
  
 -  for (;;)
 +    // linear search for token in completions vector
 +    exists = 0;
 +    for (i = 0; i < vector_active (comps) && !exists; i++)
      {
 -      memset (buf, 0, sizeof (buf));
 -      sp = str;
 -      while (*str != '\0')
 -      {
 -        if (*str == '.')
 -          {
 -            if (dots >= 3)
 -              return no_match;
 -
 -            if (*(str + 1) == '.')
 -              return no_match;
 -
 -            if (*(str + 1) == '\0')
 -              return partly_match;
 -
 -            dots++;
 -            break;
 -          }
 -        if (!isdigit ((int) *str))
 -          return no_match;
 -
 -        str++;
 -      }
 -
 -      if (str - sp > 3)
 -      return no_match;
 -
 -      strncpy (buf, sp, str - sp);
 -      if (atoi (buf) > 255)
 -      return no_match;
 -
 -      nums++;
 +      struct cmd_token *curr = vector_slot (comps, i);
 +      exists = !strcmp (curr->text, token->text) &&
 +               !strcmp (curr->desc, token->desc);
 +    }
  
 -      if (*str == '\0')
 -      break;
 +    if (!exists)
 +      vector_set (comps, copy_cmd_token (token));
 +  }
  
 -      str++;
 -    }
 +  // sort completions
 +  qsort (comps->index,
 +         vector_active (comps),
 +         sizeof (void *),
 +         &compare_completions);
  
 -  if (nums < 4)
 -    return partly_match;
 +  if (cr)
 +  {
 +    vector_set_index (comps, vector_active (comps), NULL);
 +    memmove (comps->index + 1, comps->index, (comps->alloced - 1) * sizeof (void *));
 +    vector_set_index (comps, 0, copy_cmd_token (cr));
 +  }
  
 -  return exact_match;
 +  return comps;
  }
 -
 -static enum match_type
 -cmd_ipv4_prefix_match (const char *str)
 +/**
 + * Generates a vector of cmd_token representing possible completions
 + * on the current input.
 + *
 + * @param vline the vectorized input line
 + * @param vty the vty with the node to match on
 + * @param status pointer to matcher status code
 + */
 +static vector
 +cmd_complete_command_real (vector vline, struct vty *vty, int *status)
  {
 -  const char *sp;
 -  int dots = 0;
 -  char buf[4];
 +  struct list *completions;
 +  struct graph *cmdgraph = cmd_node_graph (cmdvec, vty->node);
  
 -  if (str == NULL)
 -    return partly_match;
 +  enum matcher_rv rv = command_complete (cmdgraph, vline, &completions);
  
 -  for (;;)
 +  if (MATCHER_ERROR(rv))
 +  {
 +    switch (rv)
      {
 -      memset (buf, 0, sizeof (buf));
 -      sp = str;
 -      while (*str != '\0' && *str != '/')
 -      {
 -        if (*str == '.')
 -          {
 -            if (dots == 3)
 -              return no_match;
 -
 -            if (*(str + 1) == '.' || *(str + 1) == '/')
 -              return no_match;
 -
 -            if (*(str + 1) == '\0')
 -              return partly_match;
 -
 -            dots++;
 -            break;
 -          }
 -
 -        if (!isdigit ((int) *str))
 -          return no_match;
 -
 -        str++;
 -      }
 -
 -      if (str - sp > 3)
 -      return no_match;
 -
 -      strncpy (buf, sp, str - sp);
 -      if (atoi (buf) > 255)
 -      return no_match;
 -
 -      if (dots == 3)
 -      {
 -        if (*str == '/')
 -          {
 -            if (*(str + 1) == '\0')
 -              return partly_match;
 -
 -            str++;
 -            break;
 -          }
 -        else if (*str == '\0')
 -          return partly_match;
 -      }
 -
 -      if (*str == '\0')
 -      return partly_match;
 -
 -      str++;
 +      case MATCHER_AMBIGUOUS:
 +        *status = CMD_ERR_AMBIGUOUS;
 +      default:
 +        *status = CMD_ERR_NO_MATCH;
      }
 +    return NULL;
 +  }
  
 -  sp = str;
 -  while (*str != '\0')
 -    {
 -      if (!isdigit ((int) *str))
 -      return no_match;
 -
 -      str++;
 -    }
 +  vector comps = completions_to_vec (completions);
 +  list_delete (completions);
  
 -  if (atoi (sp) > 32)
 -    return no_match;
 +  // set status code appropriately
 +  switch (vector_active (comps))
 +  {
 +    case 0:
 +      *status = CMD_ERR_NO_MATCH;
 +      break;
 +    case 1:
 +      *status = CMD_COMPLETE_FULL_MATCH;
 +      break;
 +    default:
 +      *status = CMD_COMPLETE_LIST_MATCH;
 +  }
  
 -  return exact_match;
 +  return comps;
  }
  
 -#define IPV6_ADDR_STR       "0123456789abcdefABCDEF:."
 -#define IPV6_PREFIX_STR     "0123456789abcdefABCDEF:./"
 +vector
 +cmd_describe_command (vector vline, struct vty *vty, int *status)
 +{
 +  vector ret;
  
 -#ifdef HAVE_IPV6
 +  if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) )
 +    {
 +      enum node_type onode;
 +      vector shifted_vline;
 +      unsigned int index;
  
 -static enum match_type
 -cmd_ipv6_match (const char *str)
 -{
 -  struct sockaddr_in6 sin6_dummy;
 -  int ret;
 +      onode = vty->node;
 +      vty->node = ENABLE_NODE;
 +      /* We can try it on enable node, cos' the vty is authenticated */
  
 -  if (str == NULL)
 -    return partly_match;
 +      shifted_vline = vector_init (vector_count(vline));
 +      /* use memcpy? */
 +      for (index = 1; index < vector_active (vline); index++)
 +        {
 +          vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
 +        }
  
 -  if (strspn (str, IPV6_ADDR_STR) != strlen (str))
 -    return no_match;
 +      ret = cmd_complete_command_real (shifted_vline, vty, status);
  
 -  /* use inet_pton that has a better support,
 -   * for example inet_pton can support the automatic addresses:
 -   *  ::1.2.3.4
 -   */
 -  ret = inet_pton(AF_INET6, str, &sin6_dummy.sin6_addr);
 -   
 -  if (ret == 1)
 -    return exact_match;
 +      vector_free(shifted_vline);
 +      vty->node = onode;
 +      return ret;
 +  }
  
 -  return no_match;
 +  return cmd_complete_command_real (vline, vty, status);
  }
  
 -static enum match_type
 -cmd_ipv6_prefix_match (const char *str)
 +char **
 +cmd_complete_command_lib (vector vline, struct vty *vty, int *status, int islib)
  {
 -  struct sockaddr_in6 sin6_dummy;
 -  const char *delim = "/\0";
 -  char *dupe, *prefix, *mask, *context, *endptr;
 -  int nmask = -1;
 -
 -  if (str == NULL)
 -    return partly_match;
 +  char **ret = NULL;
 +  int original_node = vty->node;
 +  vector input_line = vector_init (vector_count (vline));
  
 -  if (strspn (str, IPV6_PREFIX_STR) != strlen (str))
 -    return no_match;
 +  // if the first token is 'do' we'll want to execute the command in the enable node
 +  int do_shortcut = cmd_try_do_shortcut (vty->node, vector_slot (vline, 0));
 +  vty->node = do_shortcut ? ENABLE_NODE : original_node;
  
 -  /* tokenize to address + mask */
 -  dupe = XMALLOC(MTYPE_TMP, strlen(str)+1);
 -  strncpy(dupe, str, strlen(str)+1);
 -  prefix = strtok_r(dupe, delim, &context);
 -  mask   = strtok_r(NULL, delim, &context);
 +  // construct the input line we'll be matching on
 +  unsigned int offset = (do_shortcut) ? 1 : 0;
 +  for (unsigned index = 0; index + offset < vector_active (vline); index++)
 +    vector_set_index (input_line, index + offset, vector_lookup (vline, index));
  
 -  if (!mask)
 -    return partly_match;
 +  // get token completions -- this is a copying operation
 +  vector comps = cmd_complete_command_real (input_line, vty, status);
 +  if (!MATCHER_ERROR (*status))
 +  {
 +    // copy completions text into an array of char*
 +    ret = XMALLOC (MTYPE_TMP, vector_active (comps) * sizeof (char *) + 1);
 +    unsigned int i;
 +    for (i = 0; i < vector_active (comps); i++)
 +      {
 +        struct cmd_token *token = vector_slot (comps, i);
 +        ret[i] = XSTRDUP (MTYPE_TMP, token->text);
 +        vector_unset (comps, i);
 +        del_cmd_token (token);
 +      }
 +    // set the last element to NULL, which vty/vtysh uses as a sentinel value
 +    ret[i] = NULL;
 +    vector_free (comps);
 +    comps = NULL;
 +  }
  
 -  /* validate prefix */
 -  if (inet_pton(AF_INET6, prefix, &sin6_dummy.sin6_addr) != 1)
 -    return no_match;
 +  // comps should always be null here
 +  assert (!comps);
  
 -  /* validate mask */
 -  nmask = strtol (mask, &endptr, 10);
 -  if (*endptr != '\0' || nmask < 0 || nmask > 128)
 -    return no_match;
 +  // free the adjusted input line
 +  vector_free (input_line);
  
 -  XFREE(MTYPE_TMP, dupe);
 +  // reset vty->node to its original value
 +  vty->node = original_node;
  
 -  return exact_match;
 +  return ret;
  }
  
 -#endif /* HAVE_IPV6  */
 -
 -#define DECIMAL_STRLEN_MAX 20
 -
 -static int
 -cmd_range_match (const char *range, const char *str)
 -{
 -  char *p;
 -  char buf[DECIMAL_STRLEN_MAX + 1];
 -  char *endptr = NULL;
 -  signed long long min, max, val;
 -
 -  if (str == NULL)
 -    return 1;
 -
 -  val = strtoll (str, &endptr, 10);
 -  if (*endptr != '\0')
 -    return 0;
 -  val = llabs(val);
 -
 -  range++;
 -  p = strchr (range, '-');
 -  if (p == NULL)
 -    return 0;
 -  if (p - range > DECIMAL_STRLEN_MAX)
 -    return 0;
 -  strncpy (buf, range, p - range);
 -  buf[p - range] = '\0';
 -  min = strtoll (buf, &endptr, 10);
 -  if (*endptr != '\0')
 -    return 0;
 -
 -  range = p + 1;
 -  p = strchr (range, '>');
 -  if (p == NULL)
 -    return 0;
 -  if (p - range > DECIMAL_STRLEN_MAX)
 -    return 0;
 -  strncpy (buf, range, p - range);
 -  buf[p - range] = '\0';
 -  max = strtoll (buf, &endptr, 10);
 -  if (*endptr != '\0')
 -    return 0;
 -
 -  if (val < min || val > max)
 -    return 0;
 -
 -  return 1;
 -}
 -
 -static enum match_type
 -cmd_word_match(struct cmd_token *token,
 -               enum filter_type filter,
 -               const char *word)
 -{
 -  const char *str;
 -  enum match_type match_type;
 -
 -  str = token->cmd;
 -
 -  if (filter == FILTER_RELAXED)
 -    if (!word || !strlen(word))
 -      return partly_match;
 -
 -  if (!word)
 -    return no_match;
 -
 -  switch (token->terminal)
 -    {
 -      case TERMINAL_VARARG:
 -        return vararg_match;
 -
 -      case TERMINAL_RANGE:
 -        if (cmd_range_match(str, word))
 -          return range_match;
 -        break;
 -
 -      case TERMINAL_IPV6:
 -        match_type = cmd_ipv6_match(word);
 -        if ((filter == FILTER_RELAXED && match_type != no_match)
 -          || (filter == FILTER_STRICT && match_type == exact_match))
 -          return ipv6_match;
 -        break;
 -
 -      case TERMINAL_IPV6_PREFIX:
 -        match_type = cmd_ipv6_prefix_match(word);
 -        if ((filter == FILTER_RELAXED && match_type != no_match)
 -            || (filter == FILTER_STRICT && match_type == exact_match))
 -          return ipv6_prefix_match;
 -        break;
 -
 -      case TERMINAL_IPV4:
 -        match_type = cmd_ipv4_match(word);
 -        if ((filter == FILTER_RELAXED && match_type != no_match)
 -            || (filter == FILTER_STRICT && match_type == exact_match))
 -          return ipv4_match;
 -        break;
 -
 -      case TERMINAL_IPV4_PREFIX:
 -        match_type = cmd_ipv4_prefix_match(word);
 -        if ((filter == FILTER_RELAXED && match_type != no_match)
 -            || (filter == FILTER_STRICT && match_type == exact_match))
 -          return ipv4_prefix_match;
 -        break;
 -
 -      case TERMINAL_OPTION:
 -      case TERMINAL_VARIABLE:
 -        return extend_match;
 -
 -      case TERMINAL_LITERAL:
 -        if (filter == FILTER_RELAXED && !strncmp(str, word, strlen(word)))
 -          {
 -            if (!strcmp(str, word))
 -              return exact_match;
 -            return partly_match;
 -          }
 -        if (filter == FILTER_STRICT && !strcmp(str, word))
 -          return exact_match;
 -        break;
 -
 -      default:
 -        assert (0);
 -    }
 -
 -  return no_match;
 -}
 -
 -struct cmd_matcher
 -{
 -  struct cmd_element *cmd; /* The command element the matcher is using */
 -  enum filter_type filter; /* Whether to use strict or relaxed matching */
 -  vector vline; /* The tokenized commandline which is to be matched */
 -  unsigned int index; /* The index up to which matching should be done */
 -
 -  /* If set, construct a list of matches at the position given by index */
 -  enum match_type *match_type;
 -  vector *match;
 -
 -  unsigned int word_index; /* iterating over vline */
 -};
 -
 -static int
 -push_argument(int *argc, const char **argv, const char *arg)
 -{
 -  if (!arg || !strlen(arg))
 -    arg = NULL;
 -
 -  if (!argc || !argv)
 -    return 0;
 -
 -  if (*argc >= CMD_ARGC_MAX)
 -    return -1;
 -
 -  argv[(*argc)++] = arg;
 -  return 0;
 -}
 -
 -static void
 -cmd_matcher_record_match(struct cmd_matcher *matcher,
 -                         enum match_type match_type,
 -                         struct cmd_token *token)
 -{
 -  if (matcher->word_index != matcher->index)
 -    return;
 -
 -  if (matcher->match)
 -    {
 -      if (!*matcher->match)
 -        *matcher->match = vector_init(VECTOR_MIN_SIZE);
 -      vector_set(*matcher->match, token);
 -    }
 -
 -  if (matcher->match_type)
 -    {
 -      if (match_type > *matcher->match_type)
 -        *matcher->match_type = match_type;
 -    }
 -}
 -
 -static int
 -cmd_matcher_words_left(struct cmd_matcher *matcher)
 -{
 -  return matcher->word_index < vector_active(matcher->vline);
 -}
 -
 -static const char*
 -cmd_matcher_get_word(struct cmd_matcher *matcher)
 -{
 -  assert(cmd_matcher_words_left(matcher));
 -
 -  return vector_slot(matcher->vline, matcher->word_index);
 -}
 -
 -static enum matcher_rv
 -cmd_matcher_match_terminal(struct cmd_matcher *matcher,
 -                           struct cmd_token *token,
 -                           int *argc, const char **argv)
 -{
 -  const char *word;
 -  enum match_type word_match;
 -
 -  assert(token->type == TOKEN_TERMINAL);
 -
 -  if (!cmd_matcher_words_left(matcher))
 -    {
 -      if (token->terminal == TERMINAL_OPTION)
 -        return MATCHER_OK; /* missing optional args are NOT pushed as NULL */
 -      else
 -        return MATCHER_INCOMPLETE;
 -    }
 -
 -  word = cmd_matcher_get_word(matcher);
 -  word_match = cmd_word_match(token, matcher->filter, word);
 -  if (word_match == no_match)
 -    return MATCHER_NO_MATCH;
 -
 -  /* We have to record the input word as argument if it matched
 -   * against a variable. */
 -  if (TERMINAL_RECORD (token->terminal))
 -    {
 -      if (push_argument(argc, argv, word))
 -        return MATCHER_EXCEED_ARGC_MAX;
 -    }
 -
 -  cmd_matcher_record_match(matcher, word_match, token);
 -
 -  matcher->word_index++;
 -
 -  /* A vararg token should consume all left over words as arguments */
 -  if (token->terminal == TERMINAL_VARARG)
 -    while (cmd_matcher_words_left(matcher))
 -      {
 -        word = cmd_matcher_get_word(matcher);
 -        if (word && strlen(word))
 -          push_argument(argc, argv, word);
 -        matcher->word_index++;
 -      }
 -
 -  return MATCHER_OK;
 -}
 -
 -static enum matcher_rv
 -cmd_matcher_match_multiple(struct cmd_matcher *matcher,
 -                           struct cmd_token *token,
 -                           int *argc, const char **argv)
 -{
 -  enum match_type multiple_match;
 -  unsigned int multiple_index;
 -  const char *word;
 -  const char *arg = NULL;
 -  struct cmd_token *word_token;
 -  enum match_type word_match;
 -
 -  assert(token->type == TOKEN_MULTIPLE);
 -
 -  multiple_match = no_match;
 -
 -  if (!cmd_matcher_words_left(matcher))
 -    return MATCHER_INCOMPLETE;
 -
 -  word = cmd_matcher_get_word(matcher);
 -  for (multiple_index = 0;
 -       multiple_index < vector_active(token->multiple);
 -       multiple_index++)
 -    {
 -      word_token = vector_slot(token->multiple, multiple_index);
 -
 -      word_match = cmd_word_match(word_token, matcher->filter, word);
 -      if (word_match == no_match)
 -        continue;
 -
 -      cmd_matcher_record_match(matcher, word_match, word_token);
 -
 -      if (word_match > multiple_match)
 -        {
 -          multiple_match = word_match;
 -          arg = word;
 -        }
 -      /* To mimic the behavior of the old command implementation, we
 -       * tolerate any ambiguities here :/ */
 -    }
 -
 -  matcher->word_index++;
 -
 -  if (multiple_match == no_match)
 -    return MATCHER_NO_MATCH;
 -
 -  if (push_argument(argc, argv, arg))
 -    return MATCHER_EXCEED_ARGC_MAX;
 -
 -  return MATCHER_OK;
 -}
 -
 -static enum matcher_rv
 -cmd_matcher_read_keywords(struct cmd_matcher *matcher,
 -                          struct cmd_token *token,
 -                          vector args_vector)
 -{
 -  unsigned int i;
 -  unsigned long keyword_mask;
 -  unsigned int keyword_found;
 -  enum match_type keyword_match;
 -  enum match_type word_match;
 -  vector keyword_vector;
 -  struct cmd_token *word_token;
 -  const char *word;
 -  int keyword_argc;
 -  const char **keyword_argv;
 -  enum matcher_rv rv = MATCHER_OK;
 -
 -  keyword_mask = 0;
 -  while (1)
 -    {
 -      if (!cmd_matcher_words_left(matcher))
 -        return MATCHER_OK;
 -
 -      word = cmd_matcher_get_word(matcher);
 -
 -      keyword_found = -1;
 -      keyword_match = no_match;
 -      for (i = 0; i < vector_active(token->keyword); i++)
 -        {
 -          if (keyword_mask & (1 << i))
 -            continue;
 -
 -          keyword_vector = vector_slot(token->keyword, i);
 -          word_token = vector_slot(keyword_vector, 0);
 -
 -          word_match = cmd_word_match(word_token, matcher->filter, word);
 -          if (word_match == no_match)
 -            continue;
 -
 -          cmd_matcher_record_match(matcher, word_match, word_token);
 -
 -          if (word_match > keyword_match)
 -            {
 -              keyword_match = word_match;
 -              keyword_found = i;
 -            }
 -          else if (word_match == keyword_match)
 -            {
 -              if (matcher->word_index != matcher->index || args_vector)
 -                return MATCHER_AMBIGUOUS;
 -            }
 -        }
 -
 -      if (keyword_found == (unsigned int)-1)
 -        return MATCHER_NO_MATCH;
 -
 -      matcher->word_index++;
 -
 -      if (matcher->word_index > matcher->index)
 -        return MATCHER_OK;
 -
 -      keyword_mask |= (1 << keyword_found);
 -
 -      if (args_vector)
 -        {
 -          keyword_argc = 0;
 -          keyword_argv = XMALLOC(MTYPE_TMP, (CMD_ARGC_MAX + 1) * sizeof(char*));
 -          /* We use -1 as a marker for unused fields as NULL might be a valid value */
 -          for (i = 0; i < CMD_ARGC_MAX + 1; i++)
 -            keyword_argv[i] = (void*)-1;
 -          vector_set_index(args_vector, keyword_found, keyword_argv);
 -        }
 -      else
 -        {
 -          keyword_argv = NULL;
 -        }
 -
 -      keyword_vector = vector_slot(token->keyword, keyword_found);
 -      /* the keyword itself is at 0. We are only interested in the arguments,
 -       * so start counting at 1. */
 -      for (i = 1; i < vector_active(keyword_vector); i++)
 -        {
 -          word_token = vector_slot(keyword_vector, i);
 -
 -          switch (word_token->type)
 -            {
 -            case TOKEN_TERMINAL:
 -              rv = cmd_matcher_match_terminal(matcher, word_token,
 -                                              &keyword_argc, keyword_argv);
 -              break;
 -            case TOKEN_MULTIPLE:
 -              rv = cmd_matcher_match_multiple(matcher, word_token,
 -                                              &keyword_argc, keyword_argv);
 -              break;
 -            case TOKEN_KEYWORD:
 -              assert(!"Keywords should never be nested.");
 -              break;
 -            }
 -
 -          if (MATCHER_ERROR(rv))
 -            return rv;
 -
 -          if (matcher->word_index > matcher->index)
 -            return MATCHER_OK;
 -        }
 -    }
 -  /* not reached */
 -}
 -
 -static enum matcher_rv
 -cmd_matcher_build_keyword_args(struct cmd_matcher *matcher,
 -                               struct cmd_token *token,
 -                               int *argc, const char **argv,
 -                               vector keyword_args_vector)
 -{
 -  unsigned int i, j;
 -  const char **keyword_args;
 -  vector keyword_vector;
 -  struct cmd_token *word_token;
 -  const char *arg;
 -  enum matcher_rv rv;
 -
 -  rv = MATCHER_OK;
 -
 -  if (keyword_args_vector == NULL)
 -    return rv;
 -
 -  for (i = 0; i < vector_active(token->keyword); i++)
 -    {
 -      keyword_vector = vector_slot(token->keyword, i);
 -      keyword_args = vector_lookup(keyword_args_vector, i);
 -
 -      if (vector_active(keyword_vector) == 1)
 -        {
 -          /* this is a keyword without arguments */
 -          if (keyword_args)
 -            {
 -              word_token = vector_slot(keyword_vector, 0);
 -              arg = word_token->cmd;
 -              XFREE (MTYPE_TMP, keyword_args);
 -            }
 -          else
 -            {
 -              arg = NULL;
 -            }
 -
 -          if (push_argument(argc, argv, arg))
 -            rv = MATCHER_EXCEED_ARGC_MAX;
 -        }
 -      else
 -        {
 -          /* this is a keyword with arguments */
 -          if (keyword_args)
 -            {
 -              /* the keyword was present, so just fill in the arguments */
 -              for (j = 0; keyword_args[j] != (void*)-1; j++)
 -                if (push_argument(argc, argv, keyword_args[j]))
 -                  rv = MATCHER_EXCEED_ARGC_MAX;
 -              XFREE(MTYPE_TMP, keyword_args);
 -            }
 -          else
 -            {
 -              /* the keyword was not present, insert NULL for the arguments
 -               * the keyword would have taken. */
 -              for (j = 1; j < vector_active(keyword_vector); j++)
 -                {
 -                  word_token = vector_slot(keyword_vector, j);
 -                  if ((word_token->type == TOKEN_TERMINAL
 -                       && TERMINAL_RECORD (word_token->terminal))
 -                      || word_token->type == TOKEN_MULTIPLE)
 -                    {
 -                      if (push_argument(argc, argv, NULL))
 -                        rv = MATCHER_EXCEED_ARGC_MAX;
 -                    }
 -                }
 -            }
 -        }
 -    }
 -  vector_free(keyword_args_vector);
 -  return rv;
 -}
 -
 -static enum matcher_rv
 -cmd_matcher_match_keyword(struct cmd_matcher *matcher,
 -                          struct cmd_token *token,
 -                          int *argc, const char **argv)
 -{
 -  vector keyword_args_vector;
 -  enum matcher_rv reader_rv;
 -  enum matcher_rv builder_rv;
 -
 -  assert(token->type == TOKEN_KEYWORD);
 -
 -  if (argc && argv)
 -    keyword_args_vector = vector_init(VECTOR_MIN_SIZE);
 -  else
 -    keyword_args_vector = NULL;
 -
 -  reader_rv = cmd_matcher_read_keywords(matcher, token, keyword_args_vector);
 -  builder_rv = cmd_matcher_build_keyword_args(matcher, token, argc,
 -                                              argv, keyword_args_vector);
 -  /* keyword_args_vector is consumed by cmd_matcher_build_keyword_args */
 -
 -  if (!MATCHER_ERROR(reader_rv) && MATCHER_ERROR(builder_rv))
 -    return builder_rv;
 -
 -  return reader_rv;
 -}
 -
 -static void
 -cmd_matcher_init(struct cmd_matcher *matcher,
 -                 struct cmd_element *cmd,
 -                 enum filter_type filter,
 -                 vector vline,
 -                 unsigned int index,
 -                 enum match_type *match_type,
 -                 vector *match)
 -{
 -  memset(matcher, 0, sizeof(*matcher));
 -
 -  matcher->cmd = cmd;
 -  matcher->filter = filter;
 -  matcher->vline = vline;
 -  matcher->index = index;
 -
 -  matcher->match_type = match_type;
 -  if (matcher->match_type)
 -    *matcher->match_type = no_match;
 -  matcher->match = match;
 -
 -  matcher->word_index = 0;
 -}
 -
 -static enum matcher_rv
 -cmd_element_match(struct cmd_element *cmd_element,
 -                  enum filter_type filter,
 -                  vector vline,
 -                  unsigned int index,
 -                  enum match_type *match_type,
 -                  vector *match,
 -                  int *argc,
 -                  const char **argv)
 -{
 -  struct cmd_matcher matcher;
 -  unsigned int token_index;
 -  enum matcher_rv rv = MATCHER_OK;
 -
 -  cmd_matcher_init(&matcher, cmd_element, filter,
 -                   vline, index, match_type, match);
 -
 -  if (argc != NULL)
 -    *argc = 0;
 -
 -  for (token_index = 0;
 -       token_index < vector_active(cmd_element->tokens);
 -       token_index++)
 -    {
 -      struct cmd_token *token = vector_slot(cmd_element->tokens, token_index);
 -
 -      switch (token->type)
 -        {
 -        case TOKEN_TERMINAL:
 -          rv = cmd_matcher_match_terminal(&matcher, token, argc, argv);
 -          break;
 -        case TOKEN_MULTIPLE:
 -          rv = cmd_matcher_match_multiple(&matcher, token, argc, argv);
 -          break;
 -        case TOKEN_KEYWORD:
 -          rv = cmd_matcher_match_keyword(&matcher, token, argc, argv);
 -        }
 -
 -      if (MATCHER_ERROR(rv))
 -        return rv;
 -
 -      if (matcher.word_index > index)
 -        return MATCHER_OK;
 -    }
 -
 -  /* return MATCHER_COMPLETE if all words were consumed */
 -  if (matcher.word_index >= vector_active(vline))
 -    return MATCHER_COMPLETE;
 -
 -  /* return MATCHER_COMPLETE also if only an empty word is left. */
 -  if (matcher.word_index == vector_active(vline) - 1
 -      && (!vector_slot(vline, matcher.word_index)
 -          || !strlen((char*)vector_slot(vline, matcher.word_index))))
 -    return MATCHER_COMPLETE;
 -
 -  return MATCHER_NO_MATCH; /* command is too long to match */
 -}
 -
 -/**
 - * Filter a given vector of commands against a given commandline and
 - * calculate possible completions.
 - *
 - * @param commands A vector of struct cmd_element*. Commands that don't
 - *                 match against the given command line will be overwritten
 - *                 with NULL in that vector.
 - * @param filter Either FILTER_RELAXED or FILTER_STRICT. This basically
 - *               determines how incomplete commands are handled, compare with
 - *               cmd_word_match for details.
 - * @param vline A vector of char* containing the tokenized commandline.
 - * @param index Only match up to the given token of the commandline.
 - * @param match_type Record the type of the best match here.
 - * @param matches Record the matches here. For each cmd_element in the commands
 - *                vector, a match vector will be created in the matches vector.
 - *                That vector will contain all struct command_token* of the
 - *                cmd_element which matched against the given vline at the given
 - *                index.
 - * @return A code specifying if an error occured. If all went right, it's
 - *         CMD_SUCCESS.
 - */
 -static int
 -cmd_vector_filter(vector commands,
 -                  enum filter_type filter,
 -                  vector vline,
 -                  unsigned int index,
 -                  enum match_type *match_type,
 -                  vector *matches)
 -{
 -  unsigned int i;
 -  struct cmd_element *cmd_element;
 -  enum match_type best_match;
 -  enum match_type element_match;
 -  enum matcher_rv matcher_rv;
 -
 -  best_match = no_match;
 -  *matches = vector_init(VECTOR_MIN_SIZE);
 -
 -  for (i = 0; i < vector_active (commands); i++)
 -    if ((cmd_element = vector_slot (commands, i)) != NULL)
 -      {
 -        vector_set_index(*matches, i, NULL);
 -        matcher_rv = cmd_element_match(cmd_element, filter,
 -                                       vline, index,
 -                                       &element_match,
 -                                       (vector*)&vector_slot(*matches, i),
 -                                       NULL, NULL);
 -        if (MATCHER_ERROR(matcher_rv))
 -          {
 -            vector_slot(commands, i) = NULL;
 -            if (matcher_rv == MATCHER_AMBIGUOUS)
 -              return CMD_ERR_AMBIGUOUS;
 -            if (matcher_rv == MATCHER_EXCEED_ARGC_MAX)
 -              return CMD_ERR_EXEED_ARGC_MAX;
 -          }
 -        else if (element_match > best_match)
 -          {
 -            best_match = element_match;
 -          }
 -      }
 -  *match_type = best_match;
 -  return CMD_SUCCESS;
 -}
 -
 -/**
 - * Check whether a given commandline is complete if used for a specific
 - * cmd_element.
 - *
 - * @param cmd_element A cmd_element against which the commandline should be
 - *                    checked.
 - * @param vline The tokenized commandline.
 - * @return 1 if the given commandline is complete, 0 otherwise.
 - */
 -static int
 -cmd_is_complete(struct cmd_element *cmd_element,
 -                vector vline)
 -{
 -  enum matcher_rv rv;
 -
 -  rv = cmd_element_match(cmd_element,
 -                         FILTER_RELAXED,
 -                         vline, -1,
 -                         NULL, NULL,
 -                         NULL, NULL);
 -  return (rv == MATCHER_COMPLETE);
 -}
 -
 -/**
 - * Parse a given commandline and construct a list of arguments for the
 - * given command_element.
 - *
 - * @param cmd_element The cmd_element for which we want to construct arguments.
 - * @param vline The tokenized commandline.
 - * @param argc Where to store the argument count.
 - * @param argv Where to store the argument list. Should be at least
 - *             CMD_ARGC_MAX elements long.
 - * @return CMD_SUCCESS if everything went alright, an error otherwise.
 - */
 -static int
 -cmd_parse(struct cmd_element *cmd_element,
 -          vector vline,
 -          int *argc, const char **argv)
 -{
 -  enum matcher_rv rv = cmd_element_match(cmd_element,
 -                                         FILTER_RELAXED,
 -                                         vline, -1,
 -                                         NULL, NULL,
 -                                         argc, argv);
 -  switch (rv)
 -    {
 -    case MATCHER_COMPLETE:
 -      return CMD_SUCCESS;
 -
 -    case MATCHER_NO_MATCH:
 -      return CMD_ERR_NO_MATCH;
 -
 -    case MATCHER_AMBIGUOUS:
 -      return CMD_ERR_AMBIGUOUS;
 -
 -    case MATCHER_EXCEED_ARGC_MAX:
 -      return CMD_ERR_EXEED_ARGC_MAX;
 -
 -    default:
 -      return CMD_ERR_INCOMPLETE;
 -    }
 -}
 -
 -/* Check ambiguous match */
 -static int
 -is_cmd_ambiguous (vector cmd_vector,
 -                  const char *command,
 -                  vector matches,
 -                  enum match_type type)
 -{
 -  unsigned int i;
 -  unsigned int j;
 -  const char *str = NULL;
 -  const char *matched = NULL;
 -  vector match_vector;
 -  struct cmd_token *cmd_token;
 -
 -  if (command == NULL)
 -    command = "";
 -
 -  for (i = 0; i < vector_active (matches); i++)
 -    if ((match_vector = vector_slot (matches, i)) != NULL)
 -      {
 -      int match = 0;
 -
 -      for (j = 0; j < vector_active (match_vector); j++)
 -        if ((cmd_token = vector_slot (match_vector, j)) != NULL)
 -          {
 -            enum match_type ret;
 -
 -            assert(cmd_token->type == TOKEN_TERMINAL);
 -            if (cmd_token->type != TOKEN_TERMINAL)
 -              continue;
 -
 -            str = cmd_token->cmd;
 -
 -            switch (type)
 -              {
 -              case exact_match:
 -                if (!TERMINAL_RECORD (cmd_token->terminal)
 -                    && strcmp (command, str) == 0)
 -                  match++;
 -                break;
 -              case partly_match:
 -                if (!TERMINAL_RECORD (cmd_token->terminal)
 -                    && strncmp (command, str, strlen (command)) == 0)
 -                  {
 -                    if (matched && strcmp (matched, str) != 0)
 -                      return 1;       /* There is ambiguous match. */
 -                    else
 -                      matched = str;
 -                    match++;
 -                  }
 -                break;
 -              case range_match:
 -                if (cmd_range_match (str, command))
 -                  {
 -                    if (matched && strcmp (matched, str) != 0)
 -                      return 1;
 -                    else
 -                      matched = str;
 -                    match++;
 -                  }
 -                break;
 -#ifdef HAVE_IPV6
 -              case ipv6_match:
 -                if (cmd_token->terminal == TERMINAL_IPV6)
 -                  match++;
 -                break;
 -              case ipv6_prefix_match:
 -                if ((ret = cmd_ipv6_prefix_match (command)) != no_match)
 -                  {
 -                    if (ret == partly_match)
 -                      return 2;       /* There is incomplete match. */
 -
 -                    match++;
 -                  }
 -                break;
 -#endif /* HAVE_IPV6 */
 -              case ipv4_match:
 -                if (cmd_token->terminal == TERMINAL_IPV4)
 -                  match++;
 -                break;
 -              case ipv4_prefix_match:
 -                if ((ret = cmd_ipv4_prefix_match (command)) != no_match)
 -                  {
 -                    if (ret == partly_match)
 -                      return 2;       /* There is incomplete match. */
 -
 -                    match++;
 -                  }
 -                break;
 -              case extend_match:
 -                if (TERMINAL_RECORD (cmd_token->terminal))
 -                  match++;
 -                break;
 -              case no_match:
 -              default:
 -                break;
 -              }
 -          }
 -      if (!match)
 -        vector_slot (cmd_vector, i) = NULL;
 -      }
 -  return 0;
 -}
 -
 -/* If src matches dst return dst string, otherwise return NULL */
 -static const char *
 -cmd_entry_function (const char *src, struct cmd_token *token)
 -{
 -  const char *dst = token->cmd;
 -
 -  /* Skip variable arguments. */
 -  if (TERMINAL_RECORD (token->terminal))
 -    return NULL;
 -
 -  /* In case of 'command \t', given src is NULL string. */
 -  if (src == NULL)
 -    return dst;
 -
 -  /* Matched with input string. */
 -  if (strncmp (src, dst, strlen (src)) == 0)
 -    return dst;
 -
 -  return NULL;
 -}
 -
 -/* If src matches dst return dst string, otherwise return NULL */
 -/* This version will return the dst string always if it is
 -   CMD_VARIABLE for '?' key processing */
 -static const char *
 -cmd_entry_function_desc (const char *src, struct cmd_token *token)
 -{
 -  const char *dst = token->cmd;
 -
 -  switch (token->terminal)
 -    {
 -      case TERMINAL_VARARG:
 -        return dst;
 -
 -      case TERMINAL_RANGE:
 -        if (cmd_range_match (dst, src))
 -          return dst;
 -        else
 -          return NULL;
 -
 -      case TERMINAL_IPV6:
 -        if (cmd_ipv6_match (src))
 -          return dst;
 -        else
 -          return NULL;
 -
 -      case TERMINAL_IPV6_PREFIX:
 -        if (cmd_ipv6_prefix_match (src))
 -          return dst;
 -        else
 -          return NULL;
 -
 -      case TERMINAL_IPV4:
 -        if (cmd_ipv4_match (src))
 -          return dst;
 -        else
 -          return NULL;
 -
 -      case TERMINAL_IPV4_PREFIX:
 -        if (cmd_ipv4_prefix_match (src))
 -          return dst;
 -        else
 -          return NULL;
 -
 -      /* Optional or variable commands always match on '?' */
 -      case TERMINAL_OPTION:
 -      case TERMINAL_VARIABLE:
 -        return dst;
 -
 -      case TERMINAL_LITERAL:
 -        /* In case of 'command \t', given src is NULL string. */
 -        if (src == NULL)
 -          return dst;
 -
 -        if (strncmp (src, dst, strlen (src)) == 0)
 -          return dst;
 -        else
 -          return NULL;
 -
 -      default:
 -        assert(0);
 -        return NULL;
 -    }
 -}
 -
 -/**
 - * Check whether a string is already present in a vector of strings.
 - * @param v A vector of char*.
 - * @param str A char*.
 - * @return 0 if str is already present in the vector, 1 otherwise.
 - */
 -static int
 -cmd_unique_string (vector v, const char *str)
 -{
 -  unsigned int i;
 -  char *match;
 -
 -  for (i = 0; i < vector_active (v); i++)
 -    if ((match = vector_slot (v, i)) != NULL)
 -      if (strcmp (match, str) == 0)
 -      return 0;
 -  return 1;
 -}
 -
 -/**
 - * Check whether a struct cmd_token matching a given string is already
 - * present in a vector of struct cmd_token.
 - * @param v A vector of struct cmd_token*.
 - * @param str A char* which should be searched for.
 - * @return 0 if there is a struct cmd_token* with its cmd matching str,
 - *         1 otherwise.
 - */
 -static int
 -desc_unique_string (vector v, const char *str)
 -{
 -  unsigned int i;
 -  struct cmd_token *token;
 -
 -  for (i = 0; i < vector_active (v); i++)
 -    if ((token = vector_slot (v, i)) != NULL)
 -      if (strcmp (token->cmd, str) == 0)
 -      return 0;
 -  return 1;
 -}
 -
 -static int 
 -cmd_try_do_shortcut (enum node_type node, char* first_word) {
 -  if ( first_word != NULL &&
 -       node != AUTH_NODE &&
 -       node != VIEW_NODE &&
 -       node != AUTH_ENABLE_NODE &&
 -       node != ENABLE_NODE &&
 -       0 == strcmp( "do", first_word ) )
 -    return 1;
 -  return 0;
 -}
 -
 -static void
 -cmd_matches_free(vector *matches)
 -{
 -  unsigned int i;
 -  vector cmd_matches;
 -
 -  for (i = 0; i < vector_active(*matches); i++)
 -    if ((cmd_matches = vector_slot(*matches, i)) != NULL)
 -      vector_free(cmd_matches);
 -  vector_free(*matches);
 -  *matches = NULL;
 -}
 -
 -static int
 -cmd_describe_cmp(const void *a, const void *b)
 -{
 -  const struct cmd_token *first = *(struct cmd_token * const *)a;
 -  const struct cmd_token *second = *(struct cmd_token * const *)b;
 -
 -  return strcmp(first->cmd, second->cmd);
 -}
 -
 -static void
 -cmd_describe_sort(vector matchvec)
 -{
 -  qsort(matchvec->index, vector_active(matchvec),
 -        sizeof(void*), cmd_describe_cmp);
 -}
 -
 -/* '?' describe command support. */
 -static vector
 -cmd_describe_command_real (vector vline, struct vty *vty, int *status)
 -{
 -  unsigned int i;
 -  vector cmd_vector;
 -#define INIT_MATCHVEC_SIZE 10
 -  vector matchvec;
 -  struct cmd_element *cmd_element;
 -  unsigned int index;
 -  int ret;
 -  enum match_type match;
 -  char *command;
 -  vector matches = NULL;
 -  vector match_vector;
 -  uint32_t command_found = 0;
 -  const char *last_word;
 -
 -  /* Set index. */
 -  if (vector_active (vline) == 0)
 -    {
 -      *status = CMD_ERR_NO_MATCH;
 -      return NULL;
 -    }
 -
 -  index = vector_active (vline) - 1;
 -
 -  /* Make copy vector of current node's command vector. */
 -  cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node));
 -
 -  /* Prepare match vector */
 -  matchvec = vector_init (INIT_MATCHVEC_SIZE);
 -
 -  /* Filter commands and build a list how they could possibly continue. */
 -  for (i = 0; i <= index; i++)
 -    {
 -      command = vector_slot (vline, i);
 -
 -      if (matches)
 -      cmd_matches_free(&matches);
 -
 -      ret = cmd_vector_filter(cmd_vector,
 -                            FILTER_RELAXED,
 -                            vline, i,
 -                            &match,
 -                            &matches);
 -
 -      if (ret != CMD_SUCCESS)
 -      {
 -        vector_free (cmd_vector);
 -        vector_free (matchvec);
 -        cmd_matches_free(&matches);
 -        *status = ret;
 -        return NULL;
 -      }
 -
 -      /* The last match may well be ambigious, so break here */
 -      if (i == index)
 -      break;
 -
 -      if (match == vararg_match)
 -      {
 -        /* We found a vararg match - so we can throw out the current matches here
 -         * and don't need to continue checking the command input */
 -        unsigned int j, k;
 -
 -        for (j = 0; j < vector_active (matches); j++)
 -          if ((match_vector = vector_slot (matches, j)) != NULL)
 -            for (k = 0; k < vector_active (match_vector); k++)
 -              {
 -                struct cmd_token *token = vector_slot (match_vector, k);
 -                vector_set (matchvec, token);
 -              }
 -
 -        *status = CMD_SUCCESS;
 -        vector_set(matchvec, &token_cr);
 -        vector_free (cmd_vector);
 -        cmd_matches_free(&matches);
 -        cmd_describe_sort(matchvec);
 -        return matchvec;
 -      }
 -
 -      ret = is_cmd_ambiguous(cmd_vector, command, matches, match);
 -      if (ret == 1)
 -      {
 -        vector_free (cmd_vector);
 -        vector_free (matchvec);
 -        cmd_matches_free(&matches);
 -        *status = CMD_ERR_AMBIGUOUS;
 -        return NULL;
 -      }
 -      else if (ret == 2)
 -      {
 -        vector_free (cmd_vector);
 -        vector_free (matchvec);
 -        cmd_matches_free(&matches);
 -        *status = CMD_ERR_NO_MATCH;
 -        return NULL;
 -      }
 -    }
 -
 -  /* Make description vector. */
 -  for (i = 0; i < vector_active (matches); i++) {
 -    if ((cmd_element = vector_slot (cmd_vector, i)) != NULL &&
 -        !(cmd_element->attr == CMD_ATTR_DEPRECATED ||
 -          cmd_element->attr == CMD_ATTR_HIDDEN))
 -      {
 -        unsigned int j;
 -        vector vline_trimmed;
 -
 -      command_found++;
 -        last_word = vector_slot(vline, vector_active(vline) - 1);
 -        if (last_word == NULL || !strlen(last_word))
 -          {
 -            vline_trimmed = vector_copy(vline);
 -            vector_unset(vline_trimmed, vector_active(vline_trimmed) - 1);
 -
 -            if (cmd_is_complete(cmd_element, vline_trimmed)
 -                && desc_unique_string(matchvec, command_cr))
 -              {
 -                if (match != vararg_match)
 -                  vector_set(matchvec, &token_cr);
 -              }
 -
 -            vector_free(vline_trimmed);
 -          }
 -
 -        match_vector = vector_slot (matches, i);
 -        if (match_vector)
 -          for (j = 0; j < vector_active(match_vector); j++)
 -            {
 -              struct cmd_token *token = vector_slot(match_vector, j);
 -              const char *string;
 -
 -              string = cmd_entry_function_desc(command, token);
 -              if (string && desc_unique_string(matchvec, string))
 -                vector_set(matchvec, token);
 -            }
 -      }
 -  }
 -
 -  /*
 -   * We can get into this situation when the command is complete
 -   * but the last part of the command is an optional piece of
 -   * cli.
 -   */
 -  last_word = vector_slot(vline, vector_active(vline) - 1);
 -  if (command_found == 0 && (last_word == NULL || !strlen(last_word))) {
 -    vector_set(matchvec, &token_cr);
 -  }
 -
 -  vector_free (cmd_vector);
 -  cmd_matches_free(&matches);
 -
 -  if (vector_slot (matchvec, 0) == NULL)
 -    {
 -      vector_free (matchvec);
 -      *status = CMD_ERR_NO_MATCH;
 -      return NULL;
 -    }
 -
 -  *status = CMD_SUCCESS;
 -  cmd_describe_sort(matchvec);
 -  return matchvec;
 -}
 -
 -vector
 -cmd_describe_command (vector vline, struct vty *vty, int *status)
 -{
 -  vector ret;
 -
 -  if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) )
 -    {
 -      enum node_type onode;
 -      vector shifted_vline;
 -      unsigned int index;
 -
 -      onode = vty->node;
 -      vty->node = ENABLE_NODE;
 -      /* We can try it on enable node, cos' the vty is authenticated */
 -
 -      shifted_vline = vector_init (vector_count(vline));
 -      /* use memcpy? */
 -      for (index = 1; index < vector_active (vline); index++) 
 -      {
 -        vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
 -      }
 -
 -      ret = cmd_describe_command_real (shifted_vline, vty, status);
 -
 -      vector_free(shifted_vline);
 -      vty->node = onode;
 -      return ret;
 -  }
 -
 -
 -  return cmd_describe_command_real (vline, vty, status);
 -}
 -
 -
 -/* Check LCD of matched command. */
 -static int
 -cmd_lcd (char **matched)
 -{
 -  int i;
 -  int j;
 -  int lcd = -1;
 -  char *s1, *s2;
 -  char c1, c2;
 -
 -  if (matched[0] == NULL || matched[1] == NULL)
 -    return 0;
 -
 -  for (i = 1; matched[i] != NULL; i++)
 -    {
 -      s1 = matched[i - 1];
 -      s2 = matched[i];
 -
 -      for (j = 0; (c1 = s1[j]) && (c2 = s2[j]); j++)
 -      if (c1 != c2)
 -        break;
 -
 -      if (lcd < 0)
 -      lcd = j;
 -      else
 -      {
 -        if (lcd > j)
 -          lcd = j;
 -      }
 -    }
 -  return lcd;
 -}
 -
 -static int
 -cmd_complete_cmp(const void *a, const void *b)
 -{
 -  const char *first = *(char * const *)a;
 -  const char *second = *(char * const *)b;
 -
 -  if (!first)
 -    {
 -      if (!second)
 -        return 0;
 -      return 1;
 -    }
 -  if (!second)
 -    return -1;
 -
 -  return strcmp(first, second);
 -}
 -
 -static void
 -cmd_complete_sort(vector matchvec)
 -{
 -  qsort(matchvec->index, vector_active(matchvec),
 -        sizeof(void*), cmd_complete_cmp);
 -}
 -
 -/* Command line completion support. */
 -static char **
 -cmd_complete_command_real (vector vline, struct vty *vty, int *status, int islib)
 -{
 -  unsigned int i;
 -  vector cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node));
 -#define INIT_MATCHVEC_SIZE 10
 -  vector matchvec;
 -  unsigned int index;
 -  char **match_str;
 -  struct cmd_token *token;
 -  char *command;
 -  int lcd;
 -  vector matches = NULL;
 -  vector match_vector;
 -
 -  if (vector_active (vline) == 0)
 -    {
 -      vector_free (cmd_vector);
 -      *status = CMD_ERR_NO_MATCH;
 -      return NULL;
 -    }
 -  else
 -    index = vector_active (vline) - 1;
 -
 -  /* First, filter by command string */
 -  for (i = 0; i <= index; i++)
 -    {
 -      command = vector_slot (vline, i);
 -      enum match_type match;
 -      int ret;
 -
 -      if (matches)
 -        cmd_matches_free(&matches);
 -
 -      /* First try completion match, if there is exactly match return 1 */
 -      ret = cmd_vector_filter(cmd_vector,
 -                            FILTER_RELAXED,
 -                            vline, i,
 -                            &match,
 -                            &matches);
 -
 -      if (ret != CMD_SUCCESS)
 -      {
 -        vector_free(cmd_vector);
 -        cmd_matches_free(&matches);
 -        *status = ret;
 -        return NULL;
 -      }
 -
 -      /* Break here - the completion mustn't be checked to be non-ambiguous */
 -      if (i == index)
 -      break;
 -
 -      /* If there is exact match then filter ambiguous match else check
 -       ambiguousness. */
 -      ret = is_cmd_ambiguous (cmd_vector, command, matches, match);
 -      if (ret == 1)
 -      {
 -        vector_free (cmd_vector);
 -        cmd_matches_free(&matches);
 -        *status = CMD_ERR_AMBIGUOUS;
 -        return NULL;
 -      }
 -    }
 -  
 -  /* Prepare match vector. */
 -  matchvec = vector_init (INIT_MATCHVEC_SIZE);
 -
 -  /* Build the possible list of continuations into a list of completions */
 -  for (i = 0; i < vector_active (matches); i++)
 -    if ((match_vector = vector_slot (matches, i)))
 -      {
 -      const char *string;
 -      unsigned int j;
 -
 -      for (j = 0; j < vector_active (match_vector); j++)
 -        if ((token = vector_slot (match_vector, j)))
 -            {
 -              string = cmd_entry_function (vector_slot (vline, index),
 -                                           token);
 -              if (string && cmd_unique_string (matchvec, string))
 -                vector_set (matchvec, (islib != 0 ?
 -                                      XSTRDUP (MTYPE_TMP, string) :
 -                                      strdup (string) /* rl freed */));
 -            }
 -      }
 -
 -  /* We don't need cmd_vector any more. */
 -  vector_free (cmd_vector);
 -  cmd_matches_free(&matches);
 -
 -  /* No matched command */
 -  if (vector_slot (matchvec, 0) == NULL)
 -    {
 -      vector_free (matchvec);
 -
 -      /* In case of 'command \t' pattern.  Do you need '?' command at
 -         the end of the line. */
 -      if (vector_slot (vline, index) == '\0')
 -      *status = CMD_ERR_NOTHING_TODO;
 -      else
 -      *status = CMD_ERR_NO_MATCH;
 -      return NULL;
 -    }
 -
 -  /* Only one matched */
 -  if (vector_slot (matchvec, 1) == NULL)
 -    {
 -      size_t index_size = matchvec->alloced * sizeof (void *);
 -      match_str = XMALLOC (MTYPE_TMP, index_size);
 -      memcpy (match_str, matchvec->index, index_size);
 -      vector_free (matchvec);
 -
 -      *status = CMD_COMPLETE_FULL_MATCH;
 -      return match_str;
 -    }
 -  /* Make it sure last element is NULL. */
 -  vector_set (matchvec, NULL);
 -
 -  /* Check LCD of matched strings. */
 -  if (vector_slot (vline, index) != NULL)
 -    {
 -      lcd = cmd_lcd ((char **) matchvec->index);
 -
 -      if (lcd)
 -      {
 -        int len = strlen (vector_slot (vline, index));
 -
 -        if (len < lcd)
 -          {
 -            char *lcdstr;
 -
 -            lcdstr = (islib != 0 ?
 -                        XMALLOC (MTYPE_TMP, lcd + 1) :
 -                        malloc(lcd + 1));
 -            memcpy (lcdstr, matchvec->index[0], lcd);
 -            lcdstr[lcd] = '\0';
 -
 -            /* Free matchvec. */
 -            for (i = 0; i < vector_active (matchvec); i++)
 -                {
 -                  if (vector_slot (matchvec, i))
 -                    {
 -                      if (islib != 0)
 -                        XFREE (MTYPE_TMP, vector_slot (matchvec, i));
 -                      else
 -                        free (vector_slot (matchvec, i));
 -                    }
 -                }
 -            vector_free (matchvec);
 -
 -            /* Make new matchvec. */
 -            matchvec = vector_init (INIT_MATCHVEC_SIZE);
 -            vector_set (matchvec, lcdstr);
 -
 -              size_t index_size = matchvec->alloced * sizeof (void *);
 -              match_str = XMALLOC (MTYPE_TMP, index_size);
 -              memcpy (match_str, matchvec->index, index_size);
 -              vector_free (matchvec);
 -
 -            *status = CMD_COMPLETE_MATCH;
 -            return match_str;
 -          }
 -      }
 -    }
 -
 -  match_str = (char **) matchvec->index;
 -  cmd_complete_sort(matchvec);
 -  vector_only_wrapper_free (matchvec);
 -  *status = CMD_COMPLETE_LIST_MATCH;
 -  return match_str;
 -}
 -
 -char **
 -cmd_complete_command_lib (vector vline, struct vty *vty, int *status, int islib)
 -{
 -  char **ret;
 -
 -  if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) )
 -    {
 -      enum node_type onode;
 -      vector shifted_vline;
 -      unsigned int index;
 -
 -      onode = vty->node;
 -      vty->node = ENABLE_NODE;
 -      /* We can try it on enable node, cos' the vty is authenticated */
 -
 -      shifted_vline = vector_init (vector_count(vline));
 -      /* use memcpy? */
 -      for (index = 1; index < vector_active (vline); index++) 
 -      {
 -        vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
 -      }
 -
 -      ret = cmd_complete_command_real (shifted_vline, vty, status, islib);
 -
 -      vector_free(shifted_vline);
 -      vty->node = onode;
 -      return ret;
 -  }
 -
 -  return cmd_complete_command_real (vline, vty, status, islib);
 -}
 -
 -char **
 -cmd_complete_command (vector vline, struct vty *vty, int *status)
 +char **
 +cmd_complete_command (vector vline, struct vty *vty, int *status)
  {
    return cmd_complete_command_lib (vline, vty, status, 0);
  }
@@@ -695,6 -2535,9 +692,9 @@@ node_parent ( enum node_type node 
      case BGP_VPNV6_NODE:
      case BGP_ENCAP_NODE:
      case BGP_ENCAPV6_NODE:
 -    case BGP_VNC_NVE_GROUP_NODE: 
 -    case BGP_VNC_L2_GROUP_NODE: 
+     case BGP_VNC_DEFAULTS_NODE:
++    case BGP_VNC_NVE_GROUP_NODE:
++    case BGP_VNC_L2_GROUP_NODE:
      case BGP_IPV4_NODE:
      case BGP_IPV4M_NODE:
      case BGP_IPV6_NODE:
@@@ -999,11 -2914,10 +1012,10 @@@ DEFUN (config_exit
      {
      case VIEW_NODE:
      case ENABLE_NODE:
-     case RESTRICTED_NODE:
        if (vty_shell (vty))
 -      exit (0);
 +        exit (0);
        else
 -      vty->status = VTY_CLOSE;
 +        vty->status = VTY_CLOSE;
        break;
      case CONFIG_NODE:
        vty->node = ENABLE_NODE;
@@@ -1719,12 -3628,13 +1758,13 @@@ DEFUN (config_logmsg
    int level;
    char *message;
  
 -  if ((level = level_match(argv[0])) == ZLOG_DISABLED)
 +  if ((level = level_match(argv[idx_log_level]->arg)) == ZLOG_DISABLED)
      return CMD_ERR_NO_MATCH;
  
 -  zlog(NULL, level, "%s", ((message = argv_concat(argv, argc, 1)) ? message : ""));
 +  zlog(NULL, level, "%s", ((message = argv_concat(argv, argc, idx_message)) ? message : ""));
    if (message)
      XFREE(MTYPE_TMP, message);
    return CMD_SUCCESS;
  }
  
@@@ -2195,6 -4174,14 +2235,8 @@@ install_default (enum node_type node
  void
  cmd_init (int terminal)
  {
 -  command_cr = XSTRDUP(MTYPE_CMD_TOKENS, "<cr>");
 -  token_cr.type = TOKEN_TERMINAL;
 -  token_cr.terminal = TERMINAL_LITERAL;
 -  token_cr.cmd = command_cr;
 -  token_cr.desc = XSTRDUP(MTYPE_CMD_TOKENS, "");
 -
+   qobj_init ();
    /* Allocate initial top vector of commands. */
    cmdvec = vector_init (VECTOR_MIN_SIZE);
  
  
    if (terminal)
      {
-       install_default (ENABLE_NODE);
+       install_element (ENABLE_NODE, &config_end_cmd);
        install_element (ENABLE_NODE, &config_disable_cmd);
        install_element (ENABLE_NODE, &config_terminal_cmd);
 -      install_element (ENABLE_NODE, &copy_runningconfig_startupconfig_cmd);
 -      install_element (ENABLE_NODE, &config_write_terminal_cmd);
 -      install_element (ENABLE_NODE, &config_write_file_cmd);
 -      install_element (ENABLE_NODE, &config_write_memory_cmd);
 +      install_element (ENABLE_NODE, &copy_runningconf_startupconf_cmd);
+       install_element (ENABLE_NODE, &config_write_cmd);
+       install_element (ENABLE_NODE, &show_running_config_cmd);
      }
    install_element (ENABLE_NODE, &show_startup_config_cmd);
-   install_element (ENABLE_NODE, &show_version_cmd);
-   install_element (ENABLE_NODE, &show_commandtree_cmd);
  
    if (terminal)
      {
-       install_element (ENABLE_NODE, &config_terminal_length_cmd);
-       install_element (ENABLE_NODE, &config_terminal_no_length_cmd);
-       install_element (ENABLE_NODE, &show_logging_cmd);
-       install_element (ENABLE_NODE, &echo_cmd);
        install_element (ENABLE_NODE, &config_logmsg_cmd);
        install_default (CONFIG_NODE);
      }
 -  
 +
    install_element (CONFIG_NODE, &hostname_cmd);
    install_element (CONFIG_NODE, &no_hostname_cmd);
  
        install_element (CONFIG_NODE, &no_service_terminal_length_cmd);
  
        install_element (VIEW_NODE, &show_thread_cpu_cmd);
-       install_element (ENABLE_NODE, &show_thread_cpu_cmd);
-       install_element (RESTRICTED_NODE, &show_thread_cpu_cmd);
 -      
 +
        install_element (ENABLE_NODE, &clear_thread_cpu_cmd);
        install_element (VIEW_NODE, &show_work_queues_cmd);
-       install_element (ENABLE_NODE, &show_work_queues_cmd);
  
        vrf_install_commands ();
      }
diff --cc lib/command.h
index e411e9c18c121f85f85c4977903b729b2400f196,fd0918f11892c20b9c0f445ec4eadd858cf03b3c..3c1008d4ebb3db5a0acdbd16ac9b0fd3f71d3653
@@@ -67,56 -66,68 +67,68 @@@ struct hos
  };
  
  /* There are some command levels which called from command node. */
 -enum node_type 
 +enum node_type
  {
 -  AUTH_NODE,                  /* Authentication mode of vty interface. */
 -  VIEW_NODE,                  /* View node. Default mode of vty interface. */
 -  AUTH_ENABLE_NODE,           /* Authentication mode for change enable. */
 -  ENABLE_NODE,                        /* Enable node. */
 -  CONFIG_NODE,                        /* Config node. Default mode of config file. */
 -  SERVICE_NODE,               /* Service node. */
 -  DEBUG_NODE,                 /* Debug node. */
 +  AUTH_NODE,                    /* Authentication mode of vty interface. */
-   RESTRICTED_NODE,              /* Restricted view mode */
 +  VIEW_NODE,                    /* View node. Default mode of vty interface. */
 +  AUTH_ENABLE_NODE,             /* Authentication mode for change enable. */
 +  ENABLE_NODE,                  /* Enable node. */
 +  CONFIG_NODE,                  /* Config node. Default mode of config file. */
 +  SERVICE_NODE,                 /* Service node. */
 +  DEBUG_NODE,                   /* Debug node. */
    VRF_DEBUG_NODE,               /* Vrf Debug node. */
 -  AAA_NODE,                   /* AAA node. */
 -  KEYCHAIN_NODE,              /* Key-chain node. */
 -  KEYCHAIN_KEY_NODE,          /* Key-chain key node. */
 -  NS_NODE,                    /* Logical-Router node. */
 -  VRF_NODE,                   /* VRF mode node. */
 -  INTERFACE_NODE,             /* Interface mode node. */
 -  ZEBRA_NODE,                 /* zebra connection node. */
 -  TABLE_NODE,                 /* rtm_table selection node. */
 -  RIP_NODE,                   /* RIP protocol mode node. */ 
 -  RIPNG_NODE,                 /* RIPng protocol mode node. */
 -  BGP_NODE,                   /* BGP protocol mode which includes BGP4+ */
 -  BGP_VPNV4_NODE,             /* BGP MPLS-VPN PE exchange. */
 -  BGP_VPNV6_NODE,             /* BGP MPLS-VPN PE exchange. */
 -  BGP_IPV4_NODE,              /* BGP IPv4 unicast address family.  */
 -  BGP_IPV4M_NODE,             /* BGP IPv4 multicast address family.  */
 -  BGP_IPV6_NODE,              /* BGP IPv6 address family */
 -  BGP_IPV6M_NODE,             /* BGP IPv6 multicast address family. */
 -  BGP_ENCAP_NODE,             /* BGP ENCAP SAFI */
 -  BGP_ENCAPV6_NODE,           /* BGP ENCAP SAFI */
+   DEBUG_VNC_NODE,             /* Debug VNC node. */
 -  OSPF_NODE,                  /* OSPF protocol mode */
 -  OSPF6_NODE,                 /* OSPF protocol for IPv6 mode */
 +  AAA_NODE,                     /* AAA node. */
 +  KEYCHAIN_NODE,                /* Key-chain node. */
 +  KEYCHAIN_KEY_NODE,            /* Key-chain key node. */
 +  NS_NODE,                      /* Logical-Router node. */
 +  VRF_NODE,                     /* VRF mode node. */
 +  INTERFACE_NODE,               /* Interface mode node. */
 +  ZEBRA_NODE,                   /* zebra connection node. */
 +  TABLE_NODE,                   /* rtm_table selection node. */
 +  RIP_NODE,                     /* RIP protocol mode node. */
 +  RIPNG_NODE,                   /* RIPng protocol mode node. */
 +  BGP_NODE,                     /* BGP protocol mode which includes BGP4+ */
 +  BGP_VPNV4_NODE,               /* BGP MPLS-VPN PE exchange. */
 +  BGP_VPNV6_NODE,               /* BGP MPLS-VPN PE exchange. */
 +  BGP_IPV4_NODE,                /* BGP IPv4 unicast address family.  */
 +  BGP_IPV4M_NODE,               /* BGP IPv4 multicast address family.  */
 +  BGP_IPV6_NODE,                /* BGP IPv6 address family */
 +  BGP_IPV6M_NODE,               /* BGP IPv6 multicast address family. */
 +  BGP_ENCAP_NODE,               /* BGP ENCAP SAFI */
 +  BGP_ENCAPV6_NODE,             /* BGP ENCAP SAFI */
+   BGP_VNC_DEFAULTS_NODE,      /* BGP VNC nve defaults */
+   BGP_VNC_NVE_GROUP_NODE,     /* BGP VNC nve group */
+   BGP_VNC_L2_GROUP_NODE,      /* BGP VNC L2 group */
+   RFP_DEFAULTS_NODE,  /* RFP defaults node */
 -  ISIS_NODE,                  /* ISIS protocol mode */
 -  PIM_NODE,                   /* PIM protocol mode */
 -  MASC_NODE,                  /* MASC for multicast.  */
 -  IRDP_NODE,                  /* ICMP Router Discovery Protocol mode. */ 
 -  IP_NODE,                    /* Static ip route node. */
 -  ACCESS_NODE,                        /* Access list node. */
 -  PREFIX_NODE,                        /* Prefix list node. */
 -  ACCESS_IPV6_NODE,           /* Access list node. */
 -  PREFIX_IPV6_NODE,           /* Prefix list node. */
 -  AS_LIST_NODE,                       /* AS list node. */
 -  COMMUNITY_LIST_NODE,                /* Community list node. */
 -  RMAP_NODE,                  /* Route map node. */
 -  SMUX_NODE,                  /* SNMP configuration node. */
 -  DUMP_NODE,                  /* Packet dump node. */
 -  FORWARDING_NODE,            /* IP forwarding node. */
 +  OSPF_NODE,                    /* OSPF protocol mode */
 +  OSPF6_NODE,                   /* OSPF protocol for IPv6 mode */
+   LDP_NODE,                   /* LDP protocol mode */
+   LDP_IPV4_NODE,              /* LDP IPv4 address family */
+   LDP_IPV6_NODE,              /* LDP IPv6 address family */
+   LDP_IPV4_IFACE_NODE,                /* LDP IPv4 Interface */
+   LDP_IPV6_IFACE_NODE,                /* LDP IPv6 Interface */
+   LDP_L2VPN_NODE,             /* LDP L2VPN node */
+   LDP_PSEUDOWIRE_NODE,                /* LDP Pseudowire node */
 +  ISIS_NODE,                    /* ISIS protocol mode */
 +  PIM_NODE,                     /* PIM protocol mode */
 +  MASC_NODE,                    /* MASC for multicast.  */
 +  IRDP_NODE,                    /* ICMP Router Discovery Protocol mode. */
 +  IP_NODE,                      /* Static ip route node. */
 +  ACCESS_NODE,                  /* Access list node. */
 +  PREFIX_NODE,                  /* Prefix list node. */
 +  ACCESS_IPV6_NODE,             /* Access list node. */
 +  PREFIX_IPV6_NODE,             /* Prefix list node. */
 +  AS_LIST_NODE,                 /* AS list node. */
 +  COMMUNITY_LIST_NODE,          /* Community list node. */
 +  RMAP_NODE,                    /* Route map node. */
 +  SMUX_NODE,                    /* SNMP configuration node. */
 +  DUMP_NODE,                    /* Packet dump node. */
 +  FORWARDING_NODE,              /* IP forwarding node. */
    PROTOCOL_NODE,                /* protocol filtering node */
 -  VTY_NODE,                   /* Vty node. */
 -  LINK_PARAMS_NODE,           /* Link-parameters node */
+   MPLS_NODE,                    /* MPLS config node */
 +  VTY_NODE,                     /* Vty node. */
 +  LINK_PARAMS_NODE,             /* Link-parameters node */
  };
  
  /* Node which has some commands and prompt string and configuration
index 8a00833915025edd5ad59038a6b31e22820eb7c7,498410c22d0bed8438ca8dbbfb5170916f003cf1..8726e993c5496a14e049559654dcc4fe097b9ca9
@@@ -185,27 -191,13 +189,13 @@@ distribute_list_unset (const char *ifna
    if (!dist)
      return 0;
  
-   if (type == DISTRIBUTE_IN)
-     {
-       if (!dist->list[DISTRIBUTE_IN])
+   if (!dist->list[type])
 -    return 0;
 +      return 0;
-       if (strcmp (dist->list[DISTRIBUTE_IN], alist_name) != 0)
+   if (strcmp (dist->list[type], alist_name) != 0)
 -    return 0;
 +      return 0;
  
-       XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[DISTRIBUTE_IN]);
-       dist->list[DISTRIBUTE_IN] = NULL;      
-     }
-   if (type == DISTRIBUTE_OUT)
-     {
-       if (!dist->list[DISTRIBUTE_OUT])
-       return 0;
-       if (strcmp (dist->list[DISTRIBUTE_OUT], alist_name) != 0)
-       return 0;
-       XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[DISTRIBUTE_OUT]);
-       dist->list[DISTRIBUTE_OUT] = NULL;      
-     }
+   XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]);
+   dist->list[type] = NULL;
  
    /* Apply this distribute-list to the interface. */
    (*distribute_delete_hook) (dist);
@@@ -261,27 -238,13 +234,13 @@@ distribute_list_prefix_unset (const cha
    if (!dist)
      return 0;
  
-   if (type == DISTRIBUTE_IN)
-     {
-       if (!dist->prefix[DISTRIBUTE_IN])
-       return 0;
-       if (strcmp (dist->prefix[DISTRIBUTE_IN], plist_name) != 0)
-       return 0;
-       XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[DISTRIBUTE_IN]);
-       dist->prefix[DISTRIBUTE_IN] = NULL;
-     }
-   if (type == DISTRIBUTE_OUT)
-     {
-       if (!dist->prefix[DISTRIBUTE_OUT])
+   if (!dist->prefix[type])
 -    return 0;
 +      return 0;
-       if (strcmp (dist->prefix[DISTRIBUTE_OUT], plist_name) != 0)
+   if (strcmp (dist->prefix[type], plist_name) != 0)
 -    return 0;
 +      return 0;
  
-       XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[DISTRIBUTE_OUT]);
-       dist->prefix[DISTRIBUTE_OUT] = NULL;
-     }
+   XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]);
+   dist->prefix[type] = NULL;
  
    /* Apply this distribute-list to the interface. */
    (*distribute_delete_hook) (dist);
@@@ -308,30 -402,64 +259,61 @@@ DEFUN (distribute_list
         "Filter outgoing routing updates\n"
         "Interface name\n")
  {
 -  enum distribute_type type;
 +  int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
  
    /* Check of distribute list type. */
 -  if (strncmp (argv[1], "i", 1) == 0)
 -    type = DISTRIBUTE_V4_IN;
 -  else if (strncmp (argv[1], "o", 1) == 0)
 -    type = DISTRIBUTE_V4_OUT;
 -  else
 -    {
 -      vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 +  enum distribute_type type = argv[2 + prefix]->arg[0] == 'i' ?
-     DISTRIBUTE_IN : DISTRIBUTE_OUT;
++    DISTRIBUTE_V4_IN : DISTRIBUTE_V4_OUT;
 +
 +  /* Set appropriate function call */
 +  void (*distfn)(const char *, enum distribute_type, const char *) = prefix ? 
 +    &distribute_list_prefix_set : &distribute_list_set;
 +  
 +  /* if interface is present, get name */
 +  const char *ifname = NULL;
 +  if (argv[argc - 1]->type == VARIABLE_TKN)
 +    ifname = argv[argc - 1]->arg;
  
    /* Get interface name corresponding distribute list. */
 -  distribute_list_set (argv[2], type, argv[0]);
 +  distfn (ifname, type, argv[1 + prefix]->arg);
  
    return CMD_SUCCESS;
  }
  
 -       "ipv6 distribute-list WORD (in|out) WORD",
+ DEFUN (ipv6_distribute_list,
+        ipv6_distribute_list_cmd,
 -  enum distribute_type type;
++       "ipv6 distribute-list [prefix] WORD <in|out> [WORD]",
++       "IPv6\n"
+        "Filter networks in routing updates\n"
+        "Access-list name\n"
+        "Filter incoming routing updates\n"
+        "Filter outgoing routing updates\n"
+        "Interface name\n")
+ {
 -  if (strncmp (argv[1], "i", 1) == 0)
 -    type = DISTRIBUTE_V6_IN;
 -  else if (strncmp (argv[1], "o", 1) == 0)
 -    type = DISTRIBUTE_V6_OUT;
 -  else
 -  {
 -    vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
 -    return CMD_WARNING;
 -  }
++  int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
+   /* Check of distribute list type. */
 -  distribute_list_set (argv[2], type, argv[0]);
++  enum distribute_type type = argv[3 + prefix]->arg[0] == 'i' ?
++    DISTRIBUTE_V6_IN : DISTRIBUTE_V6_OUT;
++
++  /* Set appropriate function call */
++  void (*distfn)(const char *, enum distribute_type, const char *) = prefix ? 
++    &distribute_list_prefix_set : &distribute_list_set;
++  
++  /* if interface is present, get name */
++  const char *ifname = NULL;
++  if (argv[argc - 1]->type == VARIABLE_TKN)
++    ifname = argv[argc - 1]->arg;
+   /* Get interface name corresponding distribute list. */
 -
 -ALIAS (ipv6_distribute_list,
 -       ipv6_as_v4_distribute_list_cmd,
 -       "distribute-list WORD (in|out) WORD",
 -       "Filter networks in routing updates\n"
 -       "Access-list name\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n"
 -       "Interface name\n")
 -
 -DEFUN (no_distribute_list, no_distribute_list_cmd,
 -       "no distribute-list WORD (in|out) WORD",
++  distfn (ifname, type, argv[1 + prefix]->arg);
+   return CMD_SUCCESS;
+ }
-        "no distribute-list [prefix] WORD <in|out> [WORD]",
++       
 +DEFUN (no_distribute_list,
 +       no_distribute_list_cmd,
++       "no [ipv6] distribute-list [prefix] WORD <in|out> [WORD]",
         NO_STR
         "Filter networks in routing updates\n"
         "Access-list name\n"
         "Filter outgoing routing updates\n"
         "Interface name\n")
  {
-   int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
 -  int ret;
 -  enum distribute_type type;
 -
 -  /* Check of distribute list type. */
 -  if (strncmp (argv[1], "i", 1) == 0)
 -    type = DISTRIBUTE_V4_IN;
 -  else if (strncmp (argv[1], "o", 1) == 0)
 -    type = DISTRIBUTE_V4_OUT;
 -  else
 -    {
 -      vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 -
 -  ret = distribute_list_unset (argv[2], type, argv[0]);
 -  if (! ret)
 -    {
 -      vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 -  return CMD_SUCCESS;
 -}
++  int ipv6 = strmatch(argv[1]->text, "ipv6");
++  int prefix = (argv[2 + ipv6]->type == WORD_TKN) ? 1 : 0;
 -DEFUN (no_ipv6_distribute_list,
 -       no_ipv6_distribute_list_cmd,
 -       "no ipv6 distribute-list WORD (in|out) WORD",
 -       NO_STR
 -       "Filter networks in routing updates\n"
 -       "Access-list name\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n"
 -       "Interface name\n")
 -{
 -  int ret;
 -  enum distribute_type type;
++  int idx_alname = 2 + ipv6 + prefix;
++  int idx_disttype = idx_alname + 1;
  
    /* Check of distribute list type. */
-   enum distribute_type type = argv[3 + prefix]->arg[0] == 'i' ?
-     DISTRIBUTE_IN : DISTRIBUTE_OUT;
 -  if (strncmp (argv[1], "i", 1) == 0)
 -    type = DISTRIBUTE_V6_IN;
 -  else if (strncmp (argv[1], "o", 1) == 0)
 -    type = DISTRIBUTE_V6_OUT;
 -  else
 -  {
 -    vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
 -    return CMD_WARNING;
 -  }
++  enum distribute_type distin = (ipv6) ? DISTRIBUTE_V6_IN : DISTRIBUTE_V4_IN;
++  enum distribute_type distout = (ipv6) ? DISTRIBUTE_V6_OUT : DISTRIBUTE_V4_OUT;
 -  ret = distribute_list_unset (argv[2], type, argv[0]);
 -  if (! ret)
 -  {
 -    vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
 -    return CMD_WARNING;
 -  }
 -  return CMD_SUCCESS;
 -}
 -
 -ALIAS (no_ipv6_distribute_list,
 -       no_ipv6_as_v4_distribute_list_cmd,
 -       "no distribute-list WORD (in|out) WORD",
 -       NO_STR
 -       "Filter networks in routing updates\n"
 -       "Access-list name\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n"
 -       "Interface name\n")
 -
 -DEFUN (distribute_list_prefix_all,
 -       distribute_list_prefix_all_cmd,
 -       "distribute-list prefix WORD (in|out)",
 -       "Filter networks in routing updates\n"
 -       "Filter prefixes in routing updates\n"
 -       "Name of an IP prefix-list\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n")
 -{
 -  enum distribute_type type;
 -
 -  /* Check of distribute list type. */
 -  if (strncmp (argv[1], "i", 1) == 0)
 -    type = DISTRIBUTE_V4_IN;
 -  else if (strncmp (argv[1], "o", 1) == 0)
 -    type = DISTRIBUTE_V4_OUT;
 -  else
 -    {
 -      vty_out (vty, "distribute list direction must be [in|out]%s",
 -             VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 -
 -  /* Get interface name corresponding distribute list. */
 -  distribute_list_prefix_set (NULL, type, argv[0]);
 -
 -  return CMD_SUCCESS;
 -}
 -
 -DEFUN (ipv6_distribute_list_prefix_all,
 -       ipv6_distribute_list_prefix_all_cmd,
 -       "ipv6 distribute-list prefix WORD (in|out)",
 -       "Filter networks in routing updates\n"
 -       "Filter prefixes in routing updates\n"
 -       "Name of an IP prefix-list\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n")
 -{
 -  enum distribute_type type;
 -
 -  /* Check of distribute list type. */
 -  if (strncmp (argv[1], "i", 1) == 0)
 -    type = DISTRIBUTE_V6_IN;
 -  else if (strncmp (argv[1], "o", 1) == 0)
 -    type = DISTRIBUTE_V6_OUT;
 -  else
 -  {
 -    vty_out (vty, "distribute list direction must be [in|out]%s",
 -             VTY_NEWLINE);
 -    return CMD_WARNING;
 -  }
 -
 -  /* Get interface name corresponding distribute list. */
 -  distribute_list_prefix_set (NULL, type, argv[0]);
 -
 -  return CMD_SUCCESS;
 -}
 -
 -ALIAS (ipv6_distribute_list_prefix_all,
 -       ipv6_as_v4_distribute_list_prefix_all_cmd,
 -       "distribute-list prefix WORD (in|out)",
 -       "Filter networks in routing updates\n"
 -       "Filter prefixes in routing updates\n"
 -       "Name of an IP prefix-list\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n")
 -
 -DEFUN (no_distribute_list_prefix_all,
 -       no_distribute_list_prefix_all_cmd,
 -       "no distribute-list prefix WORD (in|out)",
 -       NO_STR
 -       "Filter networks in routing updates\n"
 -       "Filter prefixes in routing updates\n"
 -       "Name of an IP prefix-list\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n")
 -{
 -  int ret;
 -  enum distribute_type type;
 -
 -  /* Check of distribute list type. */
 -  if (strncmp (argv[1], "i", 1) == 0)
 -    type = DISTRIBUTE_V4_IN;
 -  else if (strncmp (argv[1], "o", 1) == 0)
 -    type = DISTRIBUTE_V4_OUT;
 -  else
 -    {
 -      vty_out (vty, "distribute list direction must be [in|out]%s",
 -             VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 -
 -  ret = distribute_list_prefix_unset (NULL, type, argv[0]);
 -  if (! ret)
 -    {
 -      vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 -  return CMD_SUCCESS;
 -}
 -
 -DEFUN (no_ipv6_distribute_list_prefix_all,
 -       no_ipv6_distribute_list_prefix_all_cmd,
 -       "no ipv6 distribute-list prefix WORD (in|out)",
 -       NO_STR
 -       "Filter networks in routing updates\n"
 -       "Filter prefixes in routing updates\n"
 -       "Name of an IP prefix-list\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n")
 -{
 -  int ret;
 -  enum distribute_type type;
 -
 -  /* Check of distribute list type. */
 -  if (strncmp (argv[1], "i", 1) == 0)
 -    type = DISTRIBUTE_V6_IN;
 -  else if (strncmp (argv[1], "o", 1) == 0)
 -    type = DISTRIBUTE_V6_OUT;
 -  else
 -  {
 -    vty_out (vty, "distribute list direction must be [in|out]%s",
 -             VTY_NEWLINE);
 -    return CMD_WARNING;
 -  }
 -
 -  ret = distribute_list_prefix_unset (NULL, type, argv[0]);
 -  if (! ret)
 -  {
 -    vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
 -    return CMD_WARNING;
 -  }
 -  return CMD_SUCCESS;
 -}
 -
 -ALIAS (no_ipv6_distribute_list_prefix_all,
 -       no_ipv6_as_v4_distribute_list_prefix_all_cmd,
 -       "no distribute-list prefix WORD (in|out)",
 -       NO_STR
 -       "Filter networks in routing updates\n"
 -       "Filter prefixes in routing updates\n"
 -       "Name of an IP prefix-list\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n")
 -
 -DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
 -       "distribute-list prefix WORD (in|out) WORD",
 -       "Filter networks in routing updates\n"
 -       "Filter prefixes in routing updates\n"
 -       "Name of an IP prefix-list\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n"
 -       "Interface name\n")
 -{
 -  enum distribute_type type;
 -
 -  /* Check of distribute list type. */
 -  if (strncmp (argv[1], "i", 1) == 0)
 -    type = DISTRIBUTE_V4_IN;
 -  else if (strncmp (argv[1], "o", 1) == 0)
 -    type = DISTRIBUTE_V4_OUT;
 -  else
 -    {
 -      vty_out (vty, "distribute list direction must be [in|out]%s",
 -             VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 -
 -  /* Get interface name corresponding distribute list. */
 -  distribute_list_prefix_set (argv[2], type, argv[0]);
 -
 -  return CMD_SUCCESS;
 -}
 -
 -DEFUN (ipv6_distribute_list_prefix,
 -       ipv6_distribute_list_prefix_cmd,
 -       "ipv6 distribute-list prefix WORD (in|out) WORD",
 -       "Filter networks in routing updates\n"
 -       "Filter prefixes in routing updates\n"
 -       "Name of an IP prefix-list\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n"
 -       "Interface name\n")
 -{
 -  enum distribute_type type;
 -
 -  /* Check of distribute list type. */
 -  if (strncmp (argv[1], "i", 1) == 0)
 -    type = DISTRIBUTE_V6_IN;
 -  else if (strncmp (argv[1], "o", 1) == 0)
 -    type = DISTRIBUTE_V6_OUT;
 -  else
 -  {
 -    vty_out (vty, "distribute list direction must be [in|out]%s",
 -             VTY_NEWLINE);
 -    return CMD_WARNING;
 -  }
++  enum distribute_type type = argv[idx_disttype]->arg[0] == 'i' ? distin : distout;
  
 +  /* Set appropriate function call */
 +  int (*distfn)(const char *, enum distribute_type, const char *) = prefix ? 
 +    &distribute_list_prefix_unset : &distribute_list_unset;
 +  
 +  /* if interface is present, get name */
 +  const char *ifname = NULL;
 +  if (argv[argc - 1]->type == VARIABLE_TKN)
 +    ifname = argv[argc - 1]->arg;
    /* Get interface name corresponding distribute list. */
 -  distribute_list_prefix_set (argv[2], type, argv[0]);
 -
 -  return CMD_SUCCESS;
 -}
 -
 -ALIAS (ipv6_distribute_list_prefix,
 -       ipv6_as_v4_distribute_list_prefix_cmd,
 -       "distribute-list prefix WORD (in|out) WORD",
 -       "Filter networks in routing updates\n"
 -       "Filter prefixes in routing updates\n"
 -       "Name of an IP prefix-list\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n"
 -       "Interface name\n")
 -
 -DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
 -       "no distribute-list prefix WORD (in|out) WORD",
 -       NO_STR
 -       "Filter networks in routing updates\n"
 -       "Filter prefixes in routing updates\n"
 -       "Name of an IP prefix-list\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n"
 -       "Interface name\n")
 -{
 -  int ret;
 -  enum distribute_type type;
 +  int ret = distfn (ifname, type, argv[2 + prefix]->arg);
  
 -  /* Check of distribute list type. */
 -  if (strncmp (argv[1], "i", 1) == 0)
 -    type = DISTRIBUTE_V4_IN;
 -  else if (strncmp (argv[1], "o", 1) == 0)
 -    type = DISTRIBUTE_V4_OUT;
 -  else
 -    {
 -      vty_out (vty, "distribute list direction must be [in|out]%s",
 -             VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 -
 -  ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
    if (! ret)
      {
        vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
    return CMD_SUCCESS;
  }
  
 -DEFUN (no_ipv6_distribute_list_prefix,
 -       no_ipv6_distribute_list_prefix_cmd,
 -       "no ipv6 distribute-list prefix WORD (in|out) WORD",
 -       NO_STR
 -       "Filter networks in routing updates\n"
 -       "Filter prefixes in routing updates\n"
 -       "Name of an IP prefix-list\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n"
 -       "Interface name\n")
 -{
 -  int ret;
 -  enum distribute_type type;
 -
 -  /* Check of distribute list type. */
 -  if (strncmp (argv[1], "i", 1) == 0)
 -    type = DISTRIBUTE_V6_IN;
 -  else if (strncmp (argv[1], "o", 1) == 0)
 -    type = DISTRIBUTE_V6_OUT;
 -  else
 -  {
 -    vty_out (vty, "distribute list direction must be [in|out]%s",
 -             VTY_NEWLINE);
 -    return CMD_WARNING;
 -  }
 -
 -  ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
 -  if (! ret)
 -  {
 -    vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
 -    return CMD_WARNING;
 -  }
 -  return CMD_SUCCESS;
 -}
 -
 -ALIAS (no_ipv6_distribute_list_prefix,
 -       no_ipv6_as_v4_distribute_list_prefix_cmd,
 -       "no distribute-list prefix WORD (in|out) WORD",
 -       NO_STR
 -       "Filter networks in routing updates\n"
 -       "Filter prefixes in routing updates\n"
 -       "Name of an IP prefix-list\n"
 -       "Filter incoming routing updates\n"
 -       "Filter outgoing routing updates\n"
 -       "Interface name\n")
 -
+ static int
+ distribute_print (struct vty *vty, char *tab[], int is_prefix,
+                   enum distribute_type type, int has_print)
+ {
+   if (tab[type]) {
+     vty_out (vty, "%s %s%s",
+              has_print ? "," : "",
+              is_prefix ? "(prefix-list) " : "",
+              tab[type]);
+     return 1;
+   }
+   return has_print;
+ }
  int
  config_show_distribute (struct vty *vty)
  {
  
    /* Output filter configuration. */
    dist = distribute_lookup (NULL);
-   if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
-     {
 -  vty_out(vty, "  Outgoing update filter list for all interface is");
 +      vty_out (vty, "  Outgoing update filter list for all interface is");
-       if (dist->list[DISTRIBUTE_OUT])
-       vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
-       if (dist->prefix[DISTRIBUTE_OUT])
-       vty_out (vty, "%s (prefix-list) %s",
-                dist->list[DISTRIBUTE_OUT] ? "," : "",
-                dist->prefix[DISTRIBUTE_OUT]);
-       vty_out (vty, "%s", VTY_NEWLINE);
+   has_print = 0;
+   if (dist)
+     {
+       has_print = distribute_print(vty, dist->list,   0,
+                                    DISTRIBUTE_V4_OUT, has_print);
+       has_print = distribute_print(vty, dist->prefix, 1,
+                                    DISTRIBUTE_V4_OUT, has_print);
+       has_print = distribute_print(vty, dist->list,   0,
+                                    DISTRIBUTE_V6_OUT, has_print);
+       has_print = distribute_print(vty, dist->prefix, 1,
+                                    DISTRIBUTE_V6_OUT, has_print);
      }
+   if (has_print)
+     vty_out (vty, "%s", VTY_NEWLINE);
    else
-     vty_out (vty, "  Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
+     vty_out (vty, " not set%s", VTY_NEWLINE);
  
    for (i = 0; i < disthash->size; i++)
      for (mp = disthash->index[i]; mp; mp = mp->next)
        {
        dist = mp->data;
        if (dist->ifname)
-         if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
 -          {
 -            vty_out (vty, "    %s filtered by", dist->ifname);
 +          {
 +            vty_out (vty, "    %s filtered by", dist->ifname);
-             if (dist->list[DISTRIBUTE_OUT])
-               vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
-             if (dist->prefix[DISTRIBUTE_OUT])
-               vty_out (vty, "%s (prefix-list) %s",
-                        dist->list[DISTRIBUTE_OUT] ? "," : "",
-                        dist->prefix[DISTRIBUTE_OUT]);
+             has_print = 0;
+             has_print = distribute_print(vty, dist->list,   0,
+                                          DISTRIBUTE_V4_OUT, has_print);
+             has_print = distribute_print(vty, dist->prefix, 1,
+                                          DISTRIBUTE_V4_OUT, has_print);
+             has_print = distribute_print(vty, dist->list,   0,
+                                          DISTRIBUTE_V6_OUT, has_print);
+             has_print = distribute_print(vty, dist->prefix, 1,
+                                          DISTRIBUTE_V6_OUT, has_print);
+             if (has_print)
 -              vty_out (vty, "%s", VTY_NEWLINE);
 +            vty_out (vty, "%s", VTY_NEWLINE);
+             else
+               vty_out(vty, " nothing%s", VTY_NEWLINE);
 -          }
 +          }
        }
  
  
    /* Input filter configuration. */
    dist = distribute_lookup (NULL);
-   if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
-     {
 -  vty_out(vty, "  Incoming update filter list for all interface is");
 +      vty_out (vty, "  Incoming update filter list for all interface is");
-       if (dist->list[DISTRIBUTE_IN])
-       vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
-       if (dist->prefix[DISTRIBUTE_IN])
-       vty_out (vty, "%s (prefix-list) %s",
-                dist->list[DISTRIBUTE_IN] ? "," : "",
-                dist->prefix[DISTRIBUTE_IN]);
-       vty_out (vty, "%s", VTY_NEWLINE);
+   has_print = 0;
+   if (dist)
+     {
+       has_print = distribute_print(vty, dist->list,   0,
+                                    DISTRIBUTE_V4_IN, has_print);
+       has_print = distribute_print(vty, dist->prefix, 1,
+                                    DISTRIBUTE_V4_IN, has_print);
+       has_print = distribute_print(vty, dist->list,   0,
+                                    DISTRIBUTE_V6_IN, has_print);
+       has_print = distribute_print(vty, dist->prefix, 1,
+                                    DISTRIBUTE_V6_IN, has_print);
      }
+   if (has_print)
+     vty_out (vty, "%s", VTY_NEWLINE);
    else
-     vty_out (vty, "  Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
+     vty_out (vty, " not set%s", VTY_NEWLINE);
  
    for (i = 0; i < disthash->size; i++)
      for (mp = disthash->index[i]; mp; mp = mp->next)
        {
        dist = mp->data;
 -        if (dist->ifname)
 -          {
 -            vty_out (vty, "    %s filtered by", dist->ifname);
 +      if (dist->ifname)
-         if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
 +          {
 +            vty_out (vty, "    %s filtered by", dist->ifname);
-             if (dist->list[DISTRIBUTE_IN])
-               vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
-             if (dist->prefix[DISTRIBUTE_IN])
-               vty_out (vty, "%s (prefix-list) %s",
-                        dist->list[DISTRIBUTE_IN] ? "," : "",
-                        dist->prefix[DISTRIBUTE_IN]);
+             has_print = 0;
+             has_print = distribute_print(vty, dist->list,   0,
+                                          DISTRIBUTE_V4_IN, has_print);
+             has_print = distribute_print(vty, dist->prefix, 1,
+                                          DISTRIBUTE_V4_IN, has_print);
+             has_print = distribute_print(vty, dist->list,   0,
+                                          DISTRIBUTE_V6_IN, has_print);
+             has_print = distribute_print(vty, dist->prefix, 1,
+                                          DISTRIBUTE_V6_IN, has_print);
+             if (has_print)
 -              vty_out (vty, "%s", VTY_NEWLINE);
 +            vty_out (vty, "%s", VTY_NEWLINE);
+             else
+               vty_out(vty, " nothing%s", VTY_NEWLINE);
 -          }
 +          }
        }
    return 0;
  }
@@@ -511,7 -997,39 +522,24 @@@ distribute_list_init (int node
  {
    disthash = hash_create (distribute_hash_make,
                            (int (*) (const void *, const void *)) distribute_cmp);
 -  /* install v4 */
 -  if (node == RIP_NODE) {
 -    install_element (node, &distribute_list_all_cmd);
 -    install_element (node, &no_distribute_list_all_cmd);
 -    install_element (node, &distribute_list_cmd);
 -    install_element (node, &no_distribute_list_cmd);
 -    install_element (node, &distribute_list_prefix_all_cmd);
 -    install_element (node, &no_distribute_list_prefix_all_cmd);
 -    install_element (node, &distribute_list_prefix_cmd);
 -    install_element (node, &no_distribute_list_prefix_cmd);
 -  }
 +
 +  install_element (node, &distribute_list_cmd);
 +  install_element (node, &no_distribute_list_cmd);
+   /* install v6 */
+   if (node == RIPNG_NODE) {
 -    install_element (node, &ipv6_distribute_list_all_cmd);
 -    install_element (node, &no_ipv6_distribute_list_all_cmd);
+     install_element (node, &ipv6_distribute_list_cmd);
 -    install_element (node, &no_ipv6_distribute_list_cmd);
 -    install_element (node, &ipv6_distribute_list_prefix_all_cmd);
 -    install_element (node, &no_ipv6_distribute_list_prefix_all_cmd);
 -    install_element (node, &ipv6_distribute_list_prefix_cmd);
 -    install_element (node, &no_ipv6_distribute_list_prefix_cmd);
+   }
 -  /* install v4 syntax command for v6 only protocols. */
 -  if (node == RIPNG_NODE) {
 -    install_element (node, &ipv6_as_v4_distribute_list_all_cmd);
 -    install_element (node, &no_ipv6_as_v4_distribute_list_all_cmd);
 -    install_element (node, &ipv6_as_v4_distribute_list_cmd);
 -    install_element (node, &no_ipv6_as_v4_distribute_list_cmd);
 -    install_element (node, &ipv6_as_v4_distribute_list_prefix_all_cmd);
 -    install_element (node, &no_ipv6_as_v4_distribute_list_prefix_all_cmd);
 -    install_element (node, &ipv6_as_v4_distribute_list_prefix_cmd);
 -    install_element (node, &no_ipv6_as_v4_distribute_list_prefix_cmd);
 -  }
++  /* TODO: install v4 syntax command for v6 only protocols. */
++ /* if (node == RIPNG_NODE) {
++  *   install_element (node, &ipv6_as_v4_distribute_list_all_cmd);
++  *   install_element (node, &no_ipv6_as_v4_distribute_list_all_cmd);
++  *   install_element (node, &ipv6_as_v4_distribute_list_cmd);
++  *   install_element (node, &no_ipv6_as_v4_distribute_list_cmd);
++  *   install_element (node, &ipv6_as_v4_distribute_list_prefix_all_cmd);
++  *   install_element (node, &no_ipv6_as_v4_distribute_list_prefix_all_cmd);
++  *   install_element (node, &ipv6_as_v4_distribute_list_prefix_cmd);
++  *   install_element (node, &no_ipv6_as_v4_distribute_list_prefix_cmd);
++    }*/
  }
diff --cc lib/if.c
index dd8922ee91c5417b18f0d73bdfde71c827cc6c42,6ae85002917dba92b71ea21b43453f68b15ad211..6235884e5d3aade3559893cd396a27f3328e2b04
+++ b/lib/if.c
@@@ -677,13 -683,14 +683,12 @@@ DEFUN (interface_desc
         "Interface specific description\n"
         "Characters describing this interface\n")
  {
-   struct interface *ifp;
 +  int idx_line = 1;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
  
-   ifp = vty->index;
 -  if (argc == 0)
 -    return CMD_SUCCESS;
 -
    if (ifp->desc)
      XFREE (MTYPE_TMP, ifp->desc);
 -  ifp->desc = argv_concat(argv, argc, 0);
 +  ifp->desc = argv_concat(argv, argc, idx_line);
  
    return CMD_SUCCESS;
  }
@@@ -783,11 -783,10 +787,10 @@@ DEFUN (interface
  
    if (!ifp)
      {
 -      vty_out (vty, "%% interface %s not in %s%s", argv[0], argv[1], VTY_NEWLINE);
 +      vty_out (vty, "%% interface %s not in %s%s", ifname, vrfname, VTY_NEWLINE);
        return CMD_WARNING;
      }
-   vty->index = ifp;
-   vty->node = INTERFACE_NODE;
+   VTY_PUSH_CONTEXT_COMPAT (INTERFACE_NODE, ifp);
  
    return CMD_SUCCESS;
  }
@@@ -850,10 -857,9 +853,9 @@@ DEFUN (vrf
        return CMD_WARNING;
      }
  
 -  vrfp = vrf_get (VRF_UNKNOWN, argv[0]);
 +  vrfp = vrf_get (VRF_UNKNOWN, vrfname);
  
-   vty->index = vrfp;
-   vty->node = VRF_NODE;
+   VTY_PUSH_CONTEXT_COMPAT (VRF_NODE, vrfp);
  
    return CMD_SUCCESS;
  }
diff --cc lib/json.h
index 3fcfe340e913793bff14e05f1371397f1d38a76b,c8d7fae1cd88ee75d25e9cfedb8a74942f78e427..e3d73d9d880ebb5482cce22ad9555b4ad39d8618
  #include <json-c/json.h>
  #else
  #include <json/json.h>
+ /*
+  * json_object_to_json_string_ext is only available for json-c
+  * so let's just turn it back to the original usage.
+  */
+ #define json_object_to_json_string_ext(A, B) json_object_to_json_string (A)
  #endif
  
 -extern int use_json(const int argc, const char *argv[]);
 +extern int use_json(const int argc, struct cmd_token *argv[]);
  extern void json_object_string_add(struct json_object* obj, const char *key,
                                     const char *s);
  extern void json_object_int_add(struct json_object* obj, const char *key,
diff --cc lib/keychain.c
index c2d6e45714dc67af6c4880ad3b26e64473482f96,c090956487b769a212ab04123415d831eee8a999..f8a3ffc012c3c3cce753ee2b6e44cacdf059f03f
@@@ -237,12 -247,10 +247,11 @@@ DEFUN (key_chain
         "Key-chain management\n"
         "Key-chain name\n")
  {
 +  int idx_word = 2;
    struct keychain *keychain;
  
 -  keychain = keychain_get (argv[0]);
 +  keychain = keychain_get (argv[idx_word]->arg);
-   vty->index = keychain;
-   vty->node = KEYCHAIN_NODE;
+   VTY_PUSH_CONTEXT_COMPAT (KEYCHAIN_NODE, keychain);
  
    return CMD_SUCCESS;
  }
@@@ -277,18 -284,14 +286,15 @@@ DEFUN (key
         "Configure a key\n"
         "Key identifier number\n")
  {
-   struct keychain *keychain;
 +  int idx_number = 1;
+   VTY_DECLVAR_CONTEXT (keychain, keychain);
    struct key *key;
    u_int32_t index;
  
-   keychain = vty->index;
 -  VTY_GET_INTEGER ("key identifier", index, argv[0]);
 +  VTY_GET_INTEGER ("key identifier", index, argv[idx_number]->arg);
    key = key_get (keychain, index);
-   vty->index_sub = key;
-   vty->node = KEYCHAIN_KEY_NODE;
+   VTY_PUSH_CONTEXT_SUB (KEYCHAIN_KEY_NODE, key);
 -
 +  
    return CMD_SUCCESS;
  }
  
@@@ -299,14 -302,11 +305,12 @@@ DEFUN (no_key
         "Delete a key\n"
         "Key identifier number\n")
  {
-   struct keychain *keychain;
 +  int idx_number = 2;
+   VTY_DECLVAR_CONTEXT (keychain, keychain);
    struct key *key;
    u_int32_t index;
 -
 -  VTY_GET_INTEGER ("key identifier", index, argv[0]);
 +  
-   keychain = vty->index;
 +  VTY_GET_INTEGER ("key identifier", index, argv[idx_number]->arg);
    key = key_lookup (keychain, index);
    if (! key)
      {
@@@ -327,10 -327,7 +331,8 @@@ DEFUN (key_string
         "Set key string\n"
         "The key\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_line = 1;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
    if (key->string)
      XFREE(MTYPE_KEY, key->string);
@@@ -557,20 -552,10 +557,18 @@@ DEFUN (accept_lifetime_day_month_day_mo
         "Month of the year to expire\n"
         "Year to expire\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_number = 2;
 +  int idx_month = 3;
 +  int idx_number_2 = 4;
 +  int idx_hhmmss_2 = 5;
 +  int idx_number_3 = 6;
 +  int idx_month_2 = 7;
 +  int idx_number_4 = 8;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_set (vty, &key->accept, argv[0], argv[1], argv[2],
 -                         argv[3], argv[4], argv[5], argv[6], argv[7]);
 +  return key_lifetime_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
 +                         argv[idx_number_2]->arg, argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
  }
  
  DEFUN (accept_lifetime_day_month_month_day,
         "Day of th month to expire\n"
         "Year to expire\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_number = 2;
 +  int idx_month = 3;
 +  int idx_number_2 = 4;
 +  int idx_hhmmss_2 = 5;
 +  int idx_month_2 = 6;
 +  int idx_number_3 = 7;
 +  int idx_number_4 = 8;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_set (vty, &key->accept, argv[0], argv[1], argv[2],
 -                         argv[3], argv[4], argv[6], argv[5], argv[7]);
 +  return key_lifetime_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
 +                         argv[idx_number_2]->arg, argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
  }
  
  DEFUN (accept_lifetime_month_day_day_month,
         "Month of the year to expire\n"
         "Year to expire\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_month = 2;
 +  int idx_number = 3;
 +  int idx_number_2 = 4;
 +  int idx_hhmmss_2 = 5;
 +  int idx_number_3 = 6;
 +  int idx_month_2 = 7;
 +  int idx_number_4 = 8;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_set (vty, &key->accept, argv[0], argv[2], argv[1],
 -                         argv[3], argv[4], argv[5], argv[6], argv[7]);
 +  return key_lifetime_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
 +                         argv[idx_number_2]->arg, argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
  }
  
  DEFUN (accept_lifetime_month_day_month_day,
         "Day of th month to expire\n"
         "Year to expire\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_month = 2;
 +  int idx_number = 3;
 +  int idx_number_2 = 4;
 +  int idx_hhmmss_2 = 5;
 +  int idx_month_2 = 6;
 +  int idx_number_3 = 7;
 +  int idx_number_4 = 8;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_set (vty, &key->accept, argv[0], argv[2], argv[1],
 -                         argv[3], argv[4], argv[6], argv[5], argv[7]);
 +  return key_lifetime_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
 +                         argv[idx_number_2]->arg, argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
  }
  
  DEFUN (accept_lifetime_infinite_day_month,
         "Year to start\n"
         "Never expires")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_number = 2;
 +  int idx_month = 3;
 +  int idx_number_2 = 4;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_infinite_set (vty, &key->accept, argv[0], argv[1],
 -                                  argv[2], argv[3]);
 +  return key_lifetime_infinite_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
 +                                  argv[idx_month]->arg, argv[idx_number_2]->arg);
  }
  
  DEFUN (accept_lifetime_infinite_month_day,
         "Year to start\n"
         "Never expires")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_month = 2;
 +  int idx_number = 3;
 +  int idx_number_2 = 4;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_infinite_set (vty, &key->accept, argv[0], argv[2],
 -                                  argv[1], argv[3]);
 +  return key_lifetime_infinite_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
 +                                  argv[idx_month]->arg, argv[idx_number_2]->arg);
  }
  
  DEFUN (accept_lifetime_duration_day_month,
         "Duration of the key\n"
         "Duration seconds\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_number = 2;
 +  int idx_month = 3;
 +  int idx_number_2 = 4;
 +  int idx_number_3 = 6;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_duration_set (vty, &key->accept, argv[0], argv[1],
 -                                  argv[2], argv[3], argv[4]);
 +  return key_lifetime_duration_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
 +                                  argv[idx_month]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg);
  }
  
  DEFUN (accept_lifetime_duration_month_day,
         "Duration of the key\n"
         "Duration seconds\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_month = 2;
 +  int idx_number = 3;
 +  int idx_number_2 = 4;
 +  int idx_number_3 = 6;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_duration_set (vty, &key->accept, argv[0], argv[2],
 -                                  argv[1], argv[3], argv[4]);
 +  return key_lifetime_duration_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg,
 +                                  argv[idx_month]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg);
  }
  
  DEFUN (send_lifetime_day_month_day_month,
         "Month of the year to expire\n"
         "Year to expire\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_number = 2;
 +  int idx_month = 3;
 +  int idx_number_2 = 4;
 +  int idx_hhmmss_2 = 5;
 +  int idx_number_3 = 6;
 +  int idx_month_2 = 7;
 +  int idx_number_4 = 8;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_set (vty, &key->send, argv[0], argv[1], argv[2], argv[3],
 -                         argv[4], argv[5], argv[6], argv[7]);
 +  return key_lifetime_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, argv[idx_number_2]->arg,
 +                         argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
  }
  
  DEFUN (send_lifetime_day_month_month_day,
         "Day of th month to expire\n"
         "Year to expire\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_number = 2;
 +  int idx_month = 3;
 +  int idx_number_2 = 4;
 +  int idx_hhmmss_2 = 5;
 +  int idx_month_2 = 6;
 +  int idx_number_3 = 7;
 +  int idx_number_4 = 8;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_set (vty, &key->send, argv[0], argv[1], argv[2], argv[3],
 -                         argv[4], argv[6], argv[5], argv[7]);
 +  return key_lifetime_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, argv[idx_number_2]->arg,
 +                         argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
  }
  
  DEFUN (send_lifetime_month_day_day_month,
         "Month of the year to expire\n"
         "Year to expire\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_month = 2;
 +  int idx_number = 3;
 +  int idx_number_2 = 4;
 +  int idx_hhmmss_2 = 5;
 +  int idx_number_3 = 6;
 +  int idx_month_2 = 7;
 +  int idx_number_4 = 8;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_set (vty, &key->send, argv[0], argv[2], argv[1], argv[3],
 -                         argv[4], argv[5], argv[6], argv[7]);
 +  return key_lifetime_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, argv[idx_number_2]->arg,
 +                         argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
  }
  
  DEFUN (send_lifetime_month_day_month_day,
         "Day of th month to expire\n"
         "Year to expire\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_month = 2;
 +  int idx_number = 3;
 +  int idx_number_2 = 4;
 +  int idx_hhmmss_2 = 5;
 +  int idx_month_2 = 6;
 +  int idx_number_3 = 7;
 +  int idx_number_4 = 8;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_set (vty, &key->send, argv[0], argv[2], argv[1], argv[3],
 -                         argv[4], argv[6], argv[5], argv[7]);
 +  return key_lifetime_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, argv[idx_number_2]->arg,
 +                         argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg);
  }
  
  DEFUN (send_lifetime_infinite_day_month,
         "Year to start\n"
         "Never expires")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_number = 2;
 +  int idx_month = 3;
 +  int idx_number_2 = 4;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_infinite_set (vty, &key->send, argv[0], argv[1], argv[2],
 -                                  argv[3]);
 +  return key_lifetime_infinite_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
 +                                  argv[idx_number_2]->arg);
  }
  
  DEFUN (send_lifetime_infinite_month_day,
         "Year to start\n"
         "Never expires")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_month = 2;
 +  int idx_number = 3;
 +  int idx_number_2 = 4;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_infinite_set (vty, &key->send, argv[0], argv[2], argv[1],
 -                                  argv[3]);
 +  return key_lifetime_infinite_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
 +                                  argv[idx_number_2]->arg);
  }
  
  DEFUN (send_lifetime_duration_day_month,
         "Duration of the key\n"
         "Duration seconds\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_number = 2;
 +  int idx_month = 3;
 +  int idx_number_2 = 4;
 +  int idx_number_3 = 6;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_duration_set (vty, &key->send, argv[0], argv[1], argv[2],
 -                                  argv[3], argv[4]);
 +  return key_lifetime_duration_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
 +                                  argv[idx_number_2]->arg, argv[idx_number_3]->arg);
  }
  
  DEFUN (send_lifetime_duration_month_day,
         "Duration of the key\n"
         "Duration seconds\n")
  {
-   struct key *key;
-   key = vty->index_sub;
 +  int idx_hhmmss = 1;
 +  int idx_month = 2;
 +  int idx_number = 3;
 +  int idx_number_2 = 4;
 +  int idx_number_3 = 6;
+   VTY_DECLVAR_CONTEXT_SUB (key, key);
  
 -  return key_lifetime_duration_set (vty, &key->send, argv[0], argv[2], argv[1],
 -                                  argv[3], argv[4]);
 +  return key_lifetime_duration_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg,
 +                                  argv[idx_number_2]->arg, argv[idx_number_3]->arg);
  }
  
  static struct cmd_node keychain_node =
diff --cc lib/log.h
Simple merge
diff --cc lib/plist.c
Simple merge
Simple merge
diff --cc lib/routemap.c
index a68b6210b3b0fd0b47d9339404e4adba64e0386d,6f93087ae9f1bed22987ac8026c0e9c2877c9600..fc2e6b7e52f913a36cfe6e2354429614a3193ac9
@@@ -1984,540 -1405,52 +1993,581 @@@ route_map_notify_dependencies (const ch
    XFREE (MTYPE_ROUTE_MAP_NAME, name);
  }
  
 +
  /* VTY related functions. */
 -DEFUN (route_map,
 -       route_map_cmd,
 -       "route-map WORD (deny|permit) <1-65535>",
 -       "Create route-map or enter route-map command mode\n"
 -       "Route map tag\n"
 -       "Route map denies set operations\n"
 -       "Route map permits set operations\n"
 -       "Sequence to insert to/delete from existing route-map entry\n")
 +DEFUN (match_interface,
 +       match_interface_cmd,
 +       "match interface WORD",
 +       MATCH_STR
 +       "match first hop interface of route\n"
 +       "Interface name\n")
 +{
 +  int idx_word = 2;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
 +
 +  if (rmap_match_set_hook.match_interface)
-     return rmap_match_set_hook.match_interface (vty, vty->index, "interface", argv[idx_word]->arg, RMAP_EVENT_MATCH_ADDED);
++    return rmap_match_set_hook.match_interface (vty, index, "interface", argv[idx_word]->arg, RMAP_EVENT_MATCH_ADDED);
 +  return CMD_SUCCESS;
 +}
 +
 +DEFUN (no_match_interface,
 +       no_match_interface_cmd,
 +       "no match interface [INTERFACE]",
 +       NO_STR
 +       MATCH_STR
 +       "Match first hop interface of route\n"
 +       "Interface name\n")
  {
 -  int permit;
 -  unsigned long pref;
 -  struct route_map *map;
 -  struct route_map_index *index;
 -  char *endptr = NULL;
 +  char *iface = (argc == 4) ? argv[3]->arg : NULL;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
  
 -  /* Permit check. */
 -  if (strncmp (argv[1], "permit", strlen (argv[1])) == 0)
 -    permit = RMAP_PERMIT;
 -  else if (strncmp (argv[1], "deny", strlen (argv[1])) == 0)
 -    permit = RMAP_DENY;
 -  else
 +  if (rmap_match_set_hook.no_match_interface)
-     return rmap_match_set_hook.no_match_interface (vty, vty->index, "interface", iface, RMAP_EVENT_MATCH_DELETED);
++    return rmap_match_set_hook.no_match_interface (vty, index, "interface", iface, RMAP_EVENT_MATCH_DELETED);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (match_ip_address,
 +       match_ip_address_cmd,
 +       "match ip address <(1-199)|(1300-2699)|WORD>",
 +       MATCH_STR
 +       IP_STR
 +       "Match address of route\n"
 +       "IP access-list number\n"
 +       "IP access-list number (expanded range)\n"
 +       "IP Access-list name\n")
 +{
 +  int idx_acl = 3;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
 +
 +  if (rmap_match_set_hook.match_ip_address)
-         return rmap_match_set_hook.match_ip_address (vty, vty->index, "ip address", argv[idx_acl]->arg,
++        return rmap_match_set_hook.match_ip_address (vty, index, "ip address", argv[idx_acl]->arg,
 +                                                     RMAP_EVENT_FILTER_ADDED);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (no_match_ip_address,
 +       no_match_ip_address_cmd,
 +       "no match ip address [<(1-199)|(1300-2699)|WORD>]",
 +       NO_STR
 +       MATCH_STR
 +       IP_STR
 +       "Match address of route\n"
 +       "IP access-list number\n"
 +       "IP access-list number (expanded range)\n"
 +       "IP Access-list name\n")
 +{
 +  int idx_word = 4;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
 +
 +  if (rmap_match_set_hook.no_match_ip_address)
      {
 -      vty_out (vty, "the third field must be [permit|deny]%s", VTY_NEWLINE);
 +      if (argc <= idx_word)
-         return rmap_match_set_hook.no_match_ip_address (vty, vty->index, "ip address", NULL,
++        return rmap_match_set_hook.no_match_ip_address (vty, index, "ip address", NULL,
 +                                                        RMAP_EVENT_FILTER_DELETED);
-       return rmap_match_set_hook.no_match_ip_address (vty, vty->index, "ip address", argv[idx_word]->arg,
++      return rmap_match_set_hook.no_match_ip_address (vty, index, "ip address", argv[idx_word]->arg,
 +                                                      RMAP_EVENT_FILTER_DELETED);
 +    }
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (match_ip_address_prefix_list,
 +       match_ip_address_prefix_list_cmd,
 +       "match ip address prefix-list WORD",
 +       MATCH_STR
 +       IP_STR
 +       "Match address of route\n"
 +       "Match entries of prefix-lists\n"
 +       "IP prefix-list name\n")
 +{
 +  int idx_word = 4;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.match_ip_address_prefix_list)
-     return rmap_match_set_hook.match_ip_address_prefix_list (vty, vty->index, "ip address prefix-list",
++    return rmap_match_set_hook.match_ip_address_prefix_list (vty, index, "ip address prefix-list",
 +                                                             argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (no_match_ip_address_prefix_list,
 +       no_match_ip_address_prefix_list_cmd,
 +       "no match ip address prefix-list [WORD]",
 +       NO_STR
 +       MATCH_STR
 +       IP_STR
 +       "Match address of route\n"
 +       "Match entries of prefix-lists\n"
 +       "IP prefix-list name\n")
 +{
 +  int idx_word = 5;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
 +
 +  if (rmap_match_set_hook.no_match_ip_address_prefix_list)
 +    {
 +      if (argc <= idx_word)
-         return rmap_match_set_hook.no_match_ip_address_prefix_list (vty, vty->index, "ip address prefix-list",
++        return rmap_match_set_hook.no_match_ip_address_prefix_list (vty, index, "ip address prefix-list",
 +                                                                    NULL, RMAP_EVENT_PLIST_DELETED);
-       return rmap_match_set_hook.no_match_ip_address_prefix_list(vty, vty->index, "ip address prefix-list",
++      return rmap_match_set_hook.no_match_ip_address_prefix_list(vty, index, "ip address prefix-list",
 +                                                                 argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
 +    }
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (match_ip_next_hop,
 +       match_ip_next_hop_cmd,
 +       "match ip next-hop <(1-199)|(1300-2699)|WORD>",
 +       MATCH_STR
 +       IP_STR
 +       "Match next-hop address of route\n"
 +       "IP access-list number\n"
 +       "IP access-list number (expanded range)\n"
 +       "IP Access-list name\n")
 +{
 +  int idx_acl = 3;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.match_ip_next_hop)
-     return rmap_match_set_hook.match_ip_next_hop (vty, vty->index, "ip next-hop", argv[idx_acl]->arg,
++    return rmap_match_set_hook.match_ip_next_hop (vty, index, "ip next-hop", argv[idx_acl]->arg,
 +                                                  RMAP_EVENT_FILTER_ADDED);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (no_match_ip_next_hop,
 +       no_match_ip_next_hop_cmd,
 +       "no match ip next-hop [<(1-199)|(1300-2699)|WORD>]",
 +       NO_STR
 +       MATCH_STR
 +       IP_STR
 +       "Match next-hop address of route\n"
 +       "IP access-list number\n"
 +       "IP access-list number (expanded range)\n"
 +       "IP Access-list name\n")
 +{
-   int idx_word = 4;
++  int idx_word = 4; 
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
 +
 +  if (rmap_match_set_hook.no_match_ip_next_hop)
 +    {
 +      if (argc <= idx_word)
-         return rmap_match_set_hook.no_match_ip_next_hop (vty, vty->index, "ip next-hop", NULL,
++        return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop", NULL,
 +                                                        RMAP_EVENT_FILTER_DELETED);
-       return rmap_match_set_hook.no_match_ip_next_hop (vty, vty->index, "ip next-hop", argv[idx_word]->arg,
++      return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop", argv[idx_word]->arg,
 +                                                      RMAP_EVENT_FILTER_DELETED);
 +    }
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (match_ip_next_hop_prefix_list,
 +       match_ip_next_hop_prefix_list_cmd,
 +       "match ip next-hop prefix-list WORD",
 +       MATCH_STR
 +       IP_STR
 +       "Match next-hop address of route\n"
 +       "Match entries of prefix-lists\n"
 +       "IP prefix-list name\n")
 +{
 +  int idx_word = 4;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.match_ip_next_hop_prefix_list)
-     return rmap_match_set_hook.match_ip_next_hop_prefix_list (vty, vty->index, "ip next-hop prefix-list",
++    return rmap_match_set_hook.match_ip_next_hop_prefix_list (vty, index, "ip next-hop prefix-list",
 +                                                             argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
 +  return CMD_SUCCESS;
 +}
 +
 +DEFUN (no_match_ip_next_hop_prefix_list,
 +       no_match_ip_next_hop_prefix_list_cmd,
 +       "no match ip next-hop prefix-list [WORD]",
 +       NO_STR
 +       MATCH_STR
 +       IP_STR
 +       "Match next-hop address of route\n"
 +       "Match entries of prefix-lists\n"
 +       "IP prefix-list name\n")
 +{
 +  int idx_word = 5;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
 +
 +  if (rmap_match_set_hook.no_match_ip_next_hop)
 +    {
 +      if (argc <= idx_word)
-         return rmap_match_set_hook.no_match_ip_next_hop (vty, vty->index, "ip next-hop prefix-list",
++        return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop prefix-list",
 +                                                        NULL, RMAP_EVENT_PLIST_DELETED);
-       return rmap_match_set_hook.no_match_ip_next_hop (vty, vty->index, "ip next-hop prefix-list",
++      return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop prefix-list",
 +                                                      argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
 +    }
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (match_ipv6_address,
 +       match_ipv6_address_cmd,
 +       "match ipv6 address WORD",
 +       MATCH_STR
 +       IPV6_STR
 +       "Match IPv6 address of route\n"
 +       "IPv6 access-list name\n")
 +{
 +  int idx_word = 3;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.match_ipv6_address)
-     return rmap_match_set_hook.match_ipv6_address (vty, vty->index, "ipv6 address", argv[idx_word]->arg,
++    return rmap_match_set_hook.match_ipv6_address (vty, index, "ipv6 address", argv[idx_word]->arg,
 +                                                   RMAP_EVENT_FILTER_ADDED);
 +  return CMD_SUCCESS;
 +}
 +
 +DEFUN (no_match_ipv6_address,
 +       no_match_ipv6_address_cmd,
 +       "no match ipv6 address WORD",
 +       NO_STR
 +       MATCH_STR
 +       IPV6_STR
 +       "Match IPv6 address of route\n"
 +       "IPv6 access-list name\n")
 +{
 +  int idx_word = 4;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.no_match_ipv6_address)
-     return rmap_match_set_hook.no_match_ipv6_address (vty, vty->index, "ipv6 address", argv[idx_word]->arg,
++    return rmap_match_set_hook.no_match_ipv6_address (vty, index, "ipv6 address", argv[idx_word]->arg,
 +                                                      RMAP_EVENT_FILTER_DELETED);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (match_ipv6_address_prefix_list,
 +       match_ipv6_address_prefix_list_cmd,
 +       "match ipv6 address prefix-list WORD",
 +       MATCH_STR
 +       IPV6_STR
 +       "Match address of route\n"
 +       "Match entries of prefix-lists\n"
 +       "IP prefix-list name\n")
 +{
 +  int idx_word = 4;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.match_ipv6_address_prefix_list)
-     return rmap_match_set_hook.match_ipv6_address_prefix_list (vty, vty->index, "ipv6 address prefix-list",
++    return rmap_match_set_hook.match_ipv6_address_prefix_list (vty, index, "ipv6 address prefix-list",
 +                                                               argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
 +  return CMD_SUCCESS;
 +}
 +
 +DEFUN (no_match_ipv6_address_prefix_list,
 +       no_match_ipv6_address_prefix_list_cmd,
 +       "no match ipv6 address prefix-list WORD",
 +       NO_STR
 +       MATCH_STR
 +       IPV6_STR
 +       "Match address of route\n"
 +       "Match entries of prefix-lists\n"
 +       "IP prefix-list name\n")
 +{
 +  int idx_word = 5;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.no_match_ipv6_address_prefix_list)
-     return rmap_match_set_hook.no_match_ipv6_address_prefix_list(vty, vty->index, "ipv6 address prefix-list",
++    return rmap_match_set_hook.no_match_ipv6_address_prefix_list(vty, index, "ipv6 address prefix-list",
 +                                                                 argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (match_metric,
 +       match_metric_cmd,
 +       "match metric (0-4294967295)",
 +       MATCH_STR
 +       "Match metric of route\n"
 +       "Metric value\n")
 +{
 +  int idx_number = 2;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.match_metric)
-     return rmap_match_set_hook.match_metric(vty, vty->index, "metric", argv[idx_number]->arg,
++    return rmap_match_set_hook.match_metric(vty, index, "metric", argv[idx_number]->arg,
 +                                            RMAP_EVENT_MATCH_ADDED);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (no_match_metric,
 +       no_match_metric_cmd,
 +       "no match metric [(0-4294967295)]",
 +       NO_STR
 +       MATCH_STR
 +       "Match metric of route\n"
 +       "Metric value\n")
 +{
 +  int idx_number = 3;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.no_match_metric)
 +    {
 +      if (argc <= idx_number)
-         return rmap_match_set_hook.no_match_metric (vty, vty->index, "metric",
++        return rmap_match_set_hook.no_match_metric (vty, index, "metric",
 +                                                    NULL, RMAP_EVENT_MATCH_DELETED);
-         return rmap_match_set_hook.no_match_metric(vty, vty->index, "metric",
++        return rmap_match_set_hook.no_match_metric(vty, index, "metric",
 +                                                   argv[idx_number]->arg,
 +                                                   RMAP_EVENT_MATCH_DELETED);
 +    }
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (match_tag,
 +       match_tag_cmd,
-        "match tag (1-65535)",
++       "match tag (1-4294967295)",
 +       MATCH_STR
 +       "Match tag of route\n"
 +       "Tag value\n")
 +{
 +  int idx_number = 2;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.match_tag)
-     return rmap_match_set_hook.match_tag(vty, vty->index, "tag", argv[idx_number]->arg,
++    return rmap_match_set_hook.match_tag(vty, index, "tag", argv[idx_number]->arg,
 +                                         RMAP_EVENT_MATCH_ADDED);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (no_match_tag,
 +       no_match_tag_cmd,
-        "no match tag [(1-65535)]",
++       "no match tag [(1-4294967295)]",
 +       NO_STR
 +       MATCH_STR
 +       "Match tag of route\n"
 +       "Tag value\n")
 +{
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.no_match_tag)
-     return rmap_match_set_hook.no_match_tag (vty, vty->index, "tag", argv[3]->arg,
++    return rmap_match_set_hook.no_match_tag (vty, index, "tag", argv[3]->arg,
 +                                             RMAP_EVENT_MATCH_DELETED);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (set_ip_nexthop,
 +       set_ip_nexthop_cmd,
 +       "set ip next-hop A.B.C.D",
 +       SET_STR
 +       IP_STR
 +       "Next hop address\n"
 +       "IP address of next hop\n")
 +{
 +  int idx_ipv4 = 3;
 +  union sockunion su;
 +  int ret;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
 +
 +  ret = str2sockunion (argv[idx_ipv4]->arg, &su);
 +  if (ret < 0)
 +    {
 +      vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
 +      return CMD_WARNING;
 +    }
 +  if (su.sin.sin_addr.s_addr == 0 ||
 +      IPV4_CLASS_DE(su.sin.sin_addr.s_addr))
 +    {
 +      vty_out (vty, "%% nexthop address cannot be 0.0.0.0, multicast "
 +               "or reserved%s", VTY_NEWLINE);
        return CMD_WARNING;
      }
  
 -  /* Preference check. */
 -  pref = strtoul (argv[2], &endptr, 10);
 -  if (pref == ULONG_MAX || *endptr != '\0')
 +  if (rmap_match_set_hook.set_ip_nexthop)
-     return rmap_match_set_hook.set_ip_nexthop(vty, vty->index, "ip next-hop", argv[idx_ipv4]->arg);
++    return rmap_match_set_hook.set_ip_nexthop(vty, index, "ip next-hop", argv[idx_ipv4]->arg);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (no_set_ip_nexthop,
 +       no_set_ip_nexthop_cmd,
 +       "no set ip next-hop [<peer-address|A.B.C.D>]",
 +       NO_STR
 +       SET_STR
 +       "Next hop address\n"
 +       "Use peer address (for BGP only)\n"
 +       "IP address of next hop\n")
 +{
 +  int idx_peer = 4;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
 +
 +  if (rmap_match_set_hook.no_set_ip_nexthop)
      {
 -      vty_out (vty, "the fourth field must be positive integer%s",
 -             VTY_NEWLINE);
 +      if (argc <= idx_peer)
-         return rmap_match_set_hook.no_set_ip_nexthop (vty, vty->index, "ip next-hop", NULL);
-       return rmap_match_set_hook.no_set_ip_nexthop (vty, vty->index, "ip next-hop", argv[idx_peer]->arg);
++        return rmap_match_set_hook.no_set_ip_nexthop (vty, index, "ip next-hop", NULL);
++      return rmap_match_set_hook.no_set_ip_nexthop (vty, index, "ip next-hop", argv[idx_peer]->arg);
 +    }
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (set_ipv6_nexthop_local,
 +       set_ipv6_nexthop_local_cmd,
 +       "set ipv6 next-hop local X:X::X:X",
 +       SET_STR
 +       IPV6_STR
 +       "IPv6 next-hop address\n"
 +       "IPv6 local address\n"
 +       "IPv6 address of next hop\n")
 +{
 +  int idx_ipv6 = 4;
 +  struct in6_addr addr;
 +  int ret;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
 +
 +  ret = inet_pton (AF_INET6, argv[idx_ipv6]->arg, &addr);
 +  if (!ret)
 +    {
 +      vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
        return CMD_WARNING;
      }
 -  if (pref == 0 || pref > 65535)
 +  if (!IN6_IS_ADDR_LINKLOCAL(&addr))
      {
 -      vty_out (vty, "the fourth field must be <1-65535>%s", VTY_NEWLINE);
 +      vty_out (vty, "%% Invalid link-local nexthop address%s", VTY_NEWLINE);
        return CMD_WARNING;
      }
  
-     return rmap_match_set_hook.set_ipv6_nexthop_local (vty, vty->index, "ipv6 next-hop local", argv[idx_ipv6]->arg);
 +  if (rmap_match_set_hook.set_ipv6_nexthop_local)
-         return rmap_match_set_hook.no_set_ipv6_nexthop_local (vty, vty->index, "ipv6 next-hop local", NULL);
-       return rmap_match_set_hook.no_set_ipv6_nexthop_local (vty, vty->index, "ipv6 next-hop local", argv[5]->arg);
++    return rmap_match_set_hook.set_ipv6_nexthop_local (vty, index, "ipv6 next-hop local", argv[idx_ipv6]->arg);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (no_set_ipv6_nexthop_local,
 +       no_set_ipv6_nexthop_local_cmd,
 +       "no set ipv6 next-hop local [X:X::X:X]",
 +       NO_STR
 +       SET_STR
 +       IPV6_STR
 +       "IPv6 next-hop address\n"
 +       "IPv6 local address\n"
 +       "IPv6 address of next hop\n")
 +{
 +  int idx_ipv6 = 5;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.no_set_ipv6_nexthop_local)
 +    {
 +      if (argc <= idx_ipv6)
-     return rmap_match_set_hook.set_metric (vty, vty->index, "metric", argv[idx_number]->arg);
++        return rmap_match_set_hook.no_set_ipv6_nexthop_local (vty, index, "ipv6 next-hop local", NULL);
++      return rmap_match_set_hook.no_set_ipv6_nexthop_local (vty, index, "ipv6 next-hop local", argv[5]->arg);
 +    }
 +  return CMD_SUCCESS;
 +}
 +
 +DEFUN (set_metric,
 +       set_metric_cmd,
 +       "set metric <(0-4294967295)|rtt|+rtt|-rtt|+metric|-metric>",
 +       SET_STR
 +       "Metric value for destination routing protocol\n"
 +       "Metric value\n"
 +       "Assign round trip time\n"
 +       "Add round trip time\n"
 +       "Subtract round trip time\n"
 +       "Add metric\n"
 +       "Subtract metric\n")
 +{
 +  int idx_number = 2;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.set_metric)
-         return rmap_match_set_hook.no_set_metric (vty, vty->index, "metric", NULL);
-       return rmap_match_set_hook.no_set_metric (vty, vty->index, "metric", argv[idx_number]->arg);
++    return rmap_match_set_hook.set_metric (vty, index, "metric", argv[idx_number]->arg);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (no_set_metric,
 +       no_set_metric_cmd,
 +       "no set metric [(0-4294967295)]",
 +       NO_STR
 +       SET_STR
 +       "Metric value for destination routing protocol\n"
 +       "Metric value\n")
 +{
 +  int idx_number = 3;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  if (rmap_match_set_hook.no_set_metric)
 +    {
 +      if (argc <= idx_number)
-        "set tag (1-65535)",
++        return rmap_match_set_hook.no_set_metric (vty, index, "metric", NULL);
++      return rmap_match_set_hook.no_set_metric (vty, index, "metric", argv[idx_number]->arg);
 +    }
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (set_tag,
 +       set_tag_cmd,
-     return rmap_match_set_hook.set_tag (vty, vty->index, "tag", argv[idx_number]->arg);
++       "set tag (1-4294967295)",
 +       SET_STR
 +       "Tag value for routing protocol\n"
 +       "Tag value\n")
 +{
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  int idx_number = 2;
 +  if (rmap_match_set_hook.set_tag)
-        "no set tag [(1-65535)]",
++    return rmap_match_set_hook.set_tag (vty, index, "tag", argv[idx_number]->arg);
 +  return CMD_SUCCESS;
 +}
 +
 +
 +DEFUN (no_set_tag,
 +       no_set_tag_cmd,
-         return rmap_match_set_hook.no_set_tag (vty, vty->index, "tag", NULL);
-       return rmap_match_set_hook.no_set_tag (vty, vty->index, "tag", argv[idx_number]->arg);
++       "no set tag [(1-4294967295)]",
 +       NO_STR
 +       SET_STR
 +       "Tag value for routing protocol\n"
 +       "Tag value\n")
 +{
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++
 +  int idx_number = 3;
 +  if (rmap_match_set_hook.no_set_tag)
 +    {
 +      if (argc <= idx_number)
++        return rmap_match_set_hook.no_set_tag (vty, index, "tag", NULL);
++      return rmap_match_set_hook.no_set_tag (vty, index, "tag", argv[idx_number]->arg);
 +    }
 +  return CMD_SUCCESS;
 +}
 +
 +
 +
 +DEFUN (route_map,
 +       route_map_cmd,
 +       "route-map WORD <deny|permit> (1-65535)",
 +       "Create route-map or enter route-map command mode\n"
 +       "Route map tag\n"
 +       "Route map denies set operations\n"
 +       "Route map permits set operations\n"
 +       "Sequence to insert to/delete from existing route-map entry\n")
 +{
 +  int idx_word = 1;
 +  int idx_permit_deny = 2;
 +  int idx_number = 3;
 +  struct route_map *map;
 +  struct route_map_index *index;
 +  char *endptr = NULL;
 +  int permit = argv[idx_permit_deny]->arg[0] == 'p' ? RMAP_PERMIT : RMAP_DENY;
 +  unsigned long pref = strtoul (argv[idx_number]->arg, &endptr, 10);
 +  const char *mapname = argv[idx_word]->arg;
 +
    /* Get route map. */
 -  map = route_map_get (argv[0]);
 +  map = route_map_get (mapname);
    index = route_map_index_get (map, permit, pref);
  
-   vty->index = index;
-   vty->node = RMAP_NODE;
+   VTY_PUSH_CONTEXT_COMPAT (RMAP_NODE, index);
    return CMD_SUCCESS;
  }
  
@@@ -2623,10 -1574,8 +2671,8 @@@ DEFUN (no_rmap_onmatch_next
         "Exit policy on matches\n"
         "Next clause\n")
  {
-   struct route_map_index *index;
-   index = vty->index;
+   struct route_map_index *index = VTY_GET_CONTEXT (route_map_index);
 -
 +  
    if (index)
      index->exitpolicy = RMAP_EXIT;
  
@@@ -2640,11 -1589,7 +2686,12 @@@ DEFUN (rmap_onmatch_goto
         "Goto Clause number\n"
         "Number\n")
  {
-   struct route_map_index *index = vty->index;
 +  int idx_number = 2;
 +  char *num = NULL;
 +  num = argv[idx_number]->arg;
++  
++  
+   struct route_map_index *index = VTY_GET_CONTEXT (route_map_index);
    int d = 0;
  
    if (index)
@@@ -2735,11 -1689,8 +2780,10 @@@ DEFUN (rmap_call
         "Jump to another Route-Map after match+set\n"
         "Target route-map name\n")
  {
-   struct route_map_index *index;
 +  int idx_word = 1;
+   struct route_map_index *index = VTY_GET_CONTEXT (route_map_index);
 +  const char *rmap = argv[idx_word]->arg;
  
-   index = vty->index;
    if (index)
      {
        if (index->nextrm)
@@@ -2787,10 -1736,8 +2829,9 @@@ DEFUN (rmap_description
         "Route-map comment\n"
         "Comment describing this route-map rule\n")
  {
-   struct route_map_index *index;
 +  int idx_line = 1;
+   struct route_map_index *index = VTY_GET_CONTEXT (route_map_index);
  
-   index = vty->index;
    if (index)
      {
        if (index->description)
diff --cc lib/routemap.h
index a6d3123335e27dfde24a99702e87f18d15ce3497,0f888897b25ef8302758726722796ffcf1353c2a..86d72ce47421f507386be68fc84eee296ff3cc46
@@@ -228,169 -235,7 +235,173 @@@ extern void route_map_upd8_dependency (
  extern void route_map_notify_dependencies (const char *affected_name,
                                           route_map_event_t event);
  
 +extern int generic_match_add (struct vty *vty,
 +                              struct route_map_index *index,
 +                              const char *command,
 +                              const char *arg,
 +                              route_map_event_t type);
 +
 +extern int generic_match_delete (struct vty *vty,
 +                                 struct route_map_index *index,
 +                                 const char *command,
 +                                 const char *arg,
 +                                 route_map_event_t type);
 +extern int generic_set_add (struct vty *vty, struct route_map_index *index,
 +                            const char *command, const char *arg);
 +extern int generic_set_delete (struct vty *vty, struct route_map_index *index,
 +                               const char *command, const char *arg);
 +
 +
 +/* match interface */
 +extern void route_map_match_interface_hook (int (*func) (struct vty *vty,
 +                                                         struct route_map_index *index,
 +                                                         const char *command,
 +                                                         const char *arg,
 +                                                         route_map_event_t type));
 +/* no match interface */
 +extern void route_map_no_match_interface_hook (int (*func) (struct vty *vty,
 +                                                            struct route_map_index *index,
 +                                                            const char *command,
 +                                                            const char *arg,
 +                                                            route_map_event_t type));
 +/* match ip address */
 +extern void route_map_match_ip_address_hook (int (*func) (struct vty *vty,
 +                                                          struct route_map_index *index,
 +                                                          const char *command,
 +                                                          const char *arg,
 +                                                          route_map_event_t type));
 +/* no match ip address */
 +extern void route_map_no_match_ip_address_hook (int (*func) (struct vty *vty,
 +                                                             struct route_map_index *index,
 +                                                             const char *command,
 +                                                             const char *arg,
 +                                                             route_map_event_t type));
 +/* match ip address prefix list */
 +extern void route_map_match_ip_address_prefix_list_hook (int (*func) (struct vty *vty,
 +                                                                      struct route_map_index *index,
 +                                                                      const char *command,
 +                                                                      const char *arg,
 +                                                                      route_map_event_t type));
 +/* no match ip address prefix list */
 +extern void route_map_no_match_ip_address_prefix_list_hook (int (*func) (struct vty *vty,
 +                                                                         struct route_map_index *index,
 +                                                                         const char *command,
 +                                                                         const char *arg,
 +                                                                         route_map_event_t type));
 +/* match ip next hop */
 +extern void route_map_match_ip_next_hop_hook (int (*func) (struct vty *vty,
 +                                                           struct route_map_index *index,
 +                                                           const char *command,
 +                                                           const char *arg,
 +                                                           route_map_event_t type));
 +/* no match ip next hop */
 +extern void route_map_no_match_ip_next_hop_hook (int (*func) (struct vty *vty,
 +                                                              struct route_map_index *index,
 +                                                              const char *command,
 +                                                              const char *arg,
 +                                                              route_map_event_t type));
 +/* match ip next hop prefix list */
 +extern void route_map_match_ip_next_hop_prefix_list_hook (int (*func) (struct vty *vty,
 +                                                                       struct route_map_index *index,
 +                                                                       const char *command,
 +                                                                       const char *arg,
 +                                                                       route_map_event_t type));
 +/* no match ip next hop prefix list */
 +extern void route_map_no_match_ip_next_hop_prefix_list_hook (int (*func) (struct vty *vty,
 +                                                                          struct route_map_index *index,
 +                                                                          const char *command,
 +                                                                          const char *arg,
 +                                                                          route_map_event_t type));
 +/* match ipv6 address */
 +extern void route_map_match_ipv6_address_hook (int (*func) (struct vty *vty,
 +                                                            struct route_map_index *index,
 +                                                            const char *command,
 +                                                            const char *arg,
 +                                                            route_map_event_t type));
 +/* no match ipv6 address */
 +extern void route_map_no_match_ipv6_address_hook (int (*func) (struct vty *vty,
 +                                                               struct route_map_index *index,
 +                                                               const char *command,
 +                                                               const char *arg,
 +                                                               route_map_event_t type));
 +/* match ipv6 address prefix list */
 +extern void route_map_match_ipv6_address_prefix_list_hook (int (*func) (struct vty *vty,
 +                                                                        struct route_map_index *index,
 +                                                                        const char *command,
 +                                                                        const char *arg,
 +                                                                        route_map_event_t type));
 +/* no match ipv6 address prefix list */
 +extern void route_map_no_match_ipv6_address_prefix_list_hook (int (*func) (struct vty *vty,
 +                                                                           struct route_map_index *index,
 +                                                                           const char *command,
 +                                                                           const char *arg,
 +                                                                           route_map_event_t type));
 +/* match metric */
 +extern void route_map_match_metric_hook (int (*func) (struct vty *vty,
 +                                                      struct route_map_index *index,
 +                                                      const char *command,
 +                                                      const char *arg,
 +                                                      route_map_event_t type));
 +/* no match metric */
 +extern void route_map_no_match_metric_hook (int (*func) (struct vty *vty,
 +                                                         struct route_map_index *index,
 +                                                         const char *command,
 +                                                         const char *arg,
 +                                                         route_map_event_t type));
 +/* match tag */
 +extern void route_map_match_tag_hook (int (*func) (struct vty *vty,
 +                                                   struct route_map_index *index,
 +                                                   const char *command,
 +                                                   const char *arg,
 +                                                   route_map_event_t type));
 +/* no match tag */
 +extern void route_map_no_match_tag_hook (int (*func) (struct vty *vty,
 +                                                      struct route_map_index *index,
 +                                                      const char *command,
 +                                                      const char *arg,
 +                                                      route_map_event_t type));
 +/* set ip nexthop */
 +extern void route_map_set_ip_nexthop_hook (int (*func) (struct vty *vty,
 +                                                        struct route_map_index *index,
 +                                                        const char *command,
 +                                                        const char *arg));
 +/* no set ip nexthop */
 +extern void route_map_no_set_ip_nexthop_hook (int (*func) (struct vty *vty,
 +                                                           struct route_map_index *index,
 +                                                           const char *command,
 +                                                           const char *arg));
 +/* set ipv6 nexthop local */
 +extern void route_map_set_ipv6_nexthop_local_hook (int (*func) (struct vty *vty,
 +                                                                struct route_map_index *index,
 +                                                                const char *command,
 +                                                                const char *arg));
 +/* no set ipv6 nexthop local */
 +extern void route_map_no_set_ipv6_nexthop_local_hook (int (*func) (struct vty *vty,
 +                                                                   struct route_map_index *index,
 +                                                                   const char *command,
 +                                                                   const char *arg));
 +/* set metric */
 +extern void route_map_set_metric_hook (int (*func) (struct vty *vty,
 +                                                    struct route_map_index *index,
 +                                                    const char *command,
 +                                                    const char *arg));
 +/* no set metric */
 +extern void route_map_no_set_metric_hook (int (*func) (struct vty *vty,
 +                                                       struct route_map_index *index,
 +                                                       const char *command,
 +                                                       const char *arg));
 +/* set tag */
 +extern void route_map_set_tag_hook (int (*func) (struct vty *vty,
 +                                                 struct route_map_index *index,
 +                                                 const char *command,
 +                                                 const char *arg));
 +/* no set tag */
 +extern void route_map_no_set_tag_hook (int (*func) (struct vty *vty,
 +                                                    struct route_map_index *index,
 +                                                    const char *command,
 +                                                    const char *arg));
++
+ extern void *route_map_rule_tag_compile (const char *arg);
+ extern void route_map_rule_tag_free (void *rule);
  #endif /* _ZEBRA_ROUTEMAP_H */
diff --cc lib/thread.c
Simple merge
diff --cc lib/vrf.h
Simple merge
diff --cc lib/vty.c
index ee7ea579a770b108067a07c9d106d4db47ce10d7,171aca173964838ca2aaf254b00e0525e5c1b68d..78bf0e720db803c8d1ab448bf4e343a96aa0fcd0
+++ b/lib/vty.c
@@@ -383,20 -380,20 +380,20 @@@ vty_auth (struct vty *vty, char *buf
      {
        vty->fail++;
        if (vty->fail >= 3)
 -      {
 -        if (vty->node == AUTH_NODE)
 -          {
 -            vty_out (vty, "%% Bad passwords, too many failures!%s", VTY_NEWLINE);
 -            vty->status = VTY_CLOSE;
 -          }
 -        else                  
 -          {
 -            /* AUTH_ENABLE_NODE */
 -            vty->fail = 0;
 -            vty_out (vty, "%% Bad enable passwords, too many failures!%s", VTY_NEWLINE);
 +        {
 +          if (vty->node == AUTH_NODE)
 +            {
 +              vty_out (vty, "%% Bad passwords, too many failures!%s", VTY_NEWLINE);
 +              vty->status = VTY_CLOSE;
 +            }
 +          else
 +            {
 +              /* AUTH_ENABLE_NODE */
 +              vty->fail = 0;
 +              vty_out (vty, "%% Bad enable passwords, too many failures!%s", VTY_NEWLINE);
-               vty->node = restricted_mode ? RESTRICTED_NODE : VIEW_NODE;
+             vty->status = VTY_CLOSE;
 -          }
 -      }
 +            }
 +        }
      }
  }
  
@@@ -1697,12 -1711,10 +1709,10 @@@ vty_create (int vty_sock, union sockuni
    strcpy (vty->address, buf);
    if (no_password_check)
      {
-       if (restricted_mode)
-         vty->node = RESTRICTED_NODE;
-       else if (host.advanced)
+       if (host.advanced)
 -      vty->node = ENABLE_NODE;
 +        vty->node = ENABLE_NODE;
        else
 -      vty->node = VIEW_NODE;
 +        vty->node = VIEW_NODE;
      }
    if (host.lines >= 0)
      vty->lines = host.lines;
@@@ -3017,17 -3000,9 +3017,9 @@@ vty_config_write (struct vty *vty
    if (no_password_check)
      vty_out (vty, " no login%s", VTY_NEWLINE);
  
-   if (restricted_mode != restricted_mode_default)
-     {
-       if (restricted_mode_default)
-         vty_out (vty, " no anonymous restricted%s", VTY_NEWLINE);
-       else
-         vty_out (vty, " anonymous restricted%s", VTY_NEWLINE);
-     }
    if (do_log_commands)
      vty_out (vty, "log commands%s", VTY_NEWLINE);
 -    
 +
    vty_out (vty, "!%s", VTY_NEWLINE);
  
    return CMD_SUCCESS;
index 3449ec3ff74e6c76333f798b394647d13b6060b2,685be58324c10abf946f23804d9f8791de5fb703..de395e8b57a9f8381bf979353f41d43273c6c47d
@@@ -1053,12 -1089,14 +1053,8 @@@ ospf6_area_init (void
    install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
    install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
  
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_tree_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
    install_element (OSPF6_NODE, &area_range_cmd);
 -  install_element (OSPF6_NODE, &area_range_advertise_cmd);
 -  install_element (OSPF6_NODE, &area_range_cost_cmd);
 -  install_element (OSPF6_NODE, &area_range_advertise_cost_cmd);
    install_element (OSPF6_NODE, &no_area_range_cmd);
 -  install_element (OSPF6_NODE, &no_area_range_advertise_cmd);
 -  install_element (OSPF6_NODE, &no_area_range_cost_cmd);
 -  install_element (OSPF6_NODE, &no_area_range_advertise_cost_cmd);
    install_element (OSPF6_NODE, &ospf6_area_stub_no_summary_cmd);
    install_element (OSPF6_NODE, &ospf6_area_stub_cmd);
    install_element (OSPF6_NODE, &no_ospf6_area_stub_no_summary_cmd);
index 07ddb9cc88754da21e2d8dac87efb5d10739994a,e3626c25d8957b8981592c4c0a4223da18b1b1f2..3ade69c30fbf444a26e457c04b60f030a7089697
@@@ -93,7 -93,10 +93,10 @@@ ospf6_as_external_lsa_originate (struc
      UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
  
    /* external route tag */
 -    UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
+   if (info->tag)
+     SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
+   else
 +  UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
  
    /* Set metric */
    OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);
@@@ -642,10 -686,10 +686,9 @@@ ospf6_asbr_redistribute_remove (int typ
  
  DEFUN (ospf6_redistribute,
         ospf6_redistribute_cmd,
 -       "redistribute " QUAGGA_REDIST_STR_OSPF6D,
 +       "redistribute <kernel|connected|static|ripng|isis|bgp|table>",
         "Redistribute\n"
--       QUAGGA_REDIST_HELP_STR_OSPF6D
--      )
++       QUAGGA_REDIST_HELP_STR_OSPF6D)
  {
    int type;
  
@@@ -664,14 -708,12 +707,13 @@@ DEFUN (ospf6_redistribute_routemap
         "Redistribute\n"
         QUAGGA_REDIST_HELP_STR_OSPF6D
         "Route map reference\n"
--       "Route map name\n"
--      )
++       "Route map name\n")
  {
 +  int idx_protocol = 1;
 +  int idx_word = 3;
    int type;
  
 -  type = proto_redistnum(AFI_IP6, argv[0]);
 +  type = proto_redistnum(AFI_IP6, argv[idx_protocol]->arg);
    if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
      return CMD_WARNING;
  
@@@ -1052,21 -1145,47 +1142,21 @@@ DEFUN (ospf6_routemap_match_interface
  /* "no match interface WORD" */
  DEFUN (ospf6_routemap_no_match_interface,
         ospf6_routemap_no_match_interface_cmd,
 -       "no match interface",
 -       NO_STR
 -       MATCH_STR
 -       "Match first hop interface of route\n")
 -{
 -  int ret = route_map_delete_match ((struct route_map_index *) vty->index,
 -                                    "interface", (argc == 0) ? NULL : argv[0]);
 -  return route_map_command_status (vty, ret);
 -}
 -
 -ALIAS (ospf6_routemap_no_match_interface,
 -       ospf6_routemap_no_match_interface_val_cmd,
 -       "no match interface WORD",
 +       "no match interface [WORD]",
-        MATCH_STR
         NO_STR
+        MATCH_STR
         "Match first hop interface of route\n"
         "Interface name\n")
 -
 -/* add "match tag" */
 -DEFUN (ospf6_routemap_match_tag,
 -       ospf6_routemap_match_tag_cmd,
 -       "match tag <1-4294967295>",
 -       MATCH_STR
 -       "Tag value for routing protocol\n"
 -       "Tag value\n")
  {
 -  int ret = route_map_add_match ((struct route_map_index *) vty->index,
 -                               "tag", argv[0]);
 -  return route_map_command_status (vty, ret);
 -}
 +  int idx_word = 3;
 +  int ret;
  
 -/* delete "match tag" */
 -DEFUN (ospf6_routemap_no_match_tag,
 -       ospf6_routemap_no_match_tag_cmd,
 -       "no match tag",
 -       NO_STR
 -       MATCH_STR
 -       "Tag value for routing protocol\n")
 -{
 -  int ret = route_map_delete_match ((struct route_map_index *) vty->index,
 -                                  "tag", argc ? argv[0] : NULL);
 +  if (argc == 4)
 +    ret  = route_map_delete_match ((struct route_map_index *) vty->index,
 +                                    "interface", argv[idx_word]->arg);
 +  else
 +    ret  = route_map_delete_match ((struct route_map_index *) vty->index,
 +                                    "interface", NULL);
    return route_map_command_status (vty, ret);
  }
  
@@@ -1130,6 -1293,40 +1220,34 @@@ DEFUN (ospf6_routemap_no_set_forwarding
    return route_map_command_status (vty, ret);
  }
  
 -       "set tag <1-4294967295>",
+ /* add "set tag" */
+ DEFUN (ospf6_routemap_set_tag,
+        ospf6_routemap_set_tag_cmd,
 -                               "tag", argv[0]);
++       "set tag (1-4294967295)",
+        "Set value\n"
+        "Tag value for routing protocol\n"
+        "Tag value\n")
+ {
+   int ret = route_map_add_set ((struct route_map_index *) vty->index,
 -       "no set tag",
++                               "tag", argv[2]->arg);
+   return route_map_command_status (vty, ret);
+ }
+ /* delete "set tag" */
+ DEFUN (ospf6_routemap_no_set_tag,
+        ospf6_routemap_no_set_tag_cmd,
 -       "Tag value for routing protocol\n")
++       "no set tag [(1-4294967295)]",
+        NO_STR
+        "Set value\n"
 -  int ret = route_map_delete_set ((struct route_map_index *) vty->index,
 -                                  "tag", argc ? argv[0] : NULL);
++       "Tag value for routing protocol\n"
++       "Tag value\n")
+ {
 -ALIAS (ospf6_routemap_no_set_tag,
 -       ospf6_routemap_no_set_tag_val_cmd,
 -       "no set tag <1-4294967295>",
 -       NO_STR
 -       "Set value\n"
 -       "Tag value for routing protocol\n"
 -       "Tag value\n")
 -
++  char *tag = (argc == 4) ? argv[3]->arg : NULL;
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++  int ret = route_map_delete_set (index, "tag", tag);
+   return route_map_command_status (vty, ret);
+ }
  static void
  ospf6_routemap_init (void)
  {
    route_map_add_hook (ospf6_asbr_routemap_update);
    route_map_delete_hook (ospf6_asbr_routemap_update);
  
 +  route_map_set_metric_hook (generic_set_add);
 +  route_map_no_set_metric_hook (generic_set_delete);
 +
    route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
    route_map_install_match (&ospf6_routemap_rule_match_interface_cmd);
+   route_map_install_match (&ospf6_routemap_rule_match_tag_cmd);
  
    route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
    route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
    install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
  
    /* ASE Metric */
 -  install_element (RMAP_NODE, &set_metric_cmd);
 -  install_element (RMAP_NODE, &no_set_metric_cmd);
 -  install_element (RMAP_NODE, &no_set_metric_val_cmd);
 -
 -  /* Forwarding address */
    install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
    install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
 -  install_element (RMAP_NODE, &ospf6_routemap_no_set_tag_val_cmd);
+   /* Tag */
+   install_element (RMAP_NODE, &ospf6_routemap_set_tag_cmd);
+   install_element (RMAP_NODE, &ospf6_routemap_no_set_tag_cmd);
  }
  
  
index 17c701f10f06344158b173a2fe661327a7963584,cd3b171a61ce2a5944e9b9914ee14340d4e428af..45977c616eafb6b8ff6e3f118d11262cfa69f59f
@@@ -1847,12 -1899,14 +1847,9 @@@ ospf6_interface_init (void
    /* Install interface node. */
    install_node (&interface_node, config_write_ospf6_interface);
  
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_interface_cmd);
    install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_detail_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_match_cmd);
    install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
    install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_detail_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_match_cmd);
  
    install_element (CONFIG_NODE, &interface_cmd);
    install_default (INTERFACE_NODE);
index 91c7f7c62c9d6ba3124ff6515874e45648b802c6,bb265274f50e3bab1d459882f161f72bc70ba4b3..385232f7f891441adbd10c1f00eebe44adb05230
@@@ -913,7 -920,7 +913,6 @@@ voi
  ospf6_neighbor_init (void)
  {
    install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
  }
  
  DEFUN (debug_ospf6_neighbor,
Simple merge
index 48b6cb949a44e8922dbca9f2b167d40984da2a24,5def2acf69c3fdbc22a552340e8851ae29717ec7..31cdbd3c5d0f050e9f1486bf091a47b01646fe3e
@@@ -929,13 -1007,13 +928,9 @@@ ospf6_top_init (void
    install_element (CONFIG_NODE, &no_router_ospf6_cmd);
  
    install_element (VIEW_NODE, &show_ipv6_ospf6_route_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_route_detail_cmd);
    install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_cmd);
    install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_route_longer_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_route_longer_detail_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_route_type_cmd);
    install_element (VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_route_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_route_match_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
  
    install_default (OSPF6_NODE);
    install_element (OSPF6_NODE, &ospf6_router_id_cmd);
index fd87c5a56f8e266acecb82f9f2be4ce6e588fd9c,4d658ed1b8e55da17497af0d6561357699827906..c3b873953233b88d334a542d20ea6a274e843dda
@@@ -670,7 -700,9 +676,6 @@@ ospf6_zebra_init (struct thread_master 
  
    /* Install command element for zebra node. */
    install_element (VIEW_NODE, &show_zebra_cmd);
-   install_element (ENABLE_NODE, &show_zebra_cmd);
 -  install_element (CONFIG_NODE, &router_zebra_cmd);
 -  install_element (CONFIG_NODE, &no_router_zebra_cmd);
 -
    install_default (ZEBRA_NODE);
    install_element (ZEBRA_NODE, &redistribute_ospf6_cmd);
    install_element (ZEBRA_NODE, &no_redistribute_ospf6_cmd);
diff --cc ospf6d/ospf6d.c
index 8042c73225f5730b75fe6bdd58bbc5e74558554f,5ae7e60e8bdd5c345b6a5fa48fe1703f4495f689..349dae5c767d59e67a7f80d90395adb719ad1518
@@@ -1235,49 -1799,92 +1235,30 @@@ ospf6_init (void
    install_element_ospf6_clear_interface ();
  
    install_element (VIEW_NODE, &show_version_ospf6_cmd);
-   install_element (ENABLE_NODE, &show_version_ospf6_cmd);
  
    install_element (VIEW_NODE, &show_ipv6_ospf6_border_routers_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_border_routers_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_border_routers_detail_cmd);
  
    install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_router_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_network_cmd);
    install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_detail_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_linkstate_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_ospf6_linkstate_detail_cmd);
  
  #define INSTALL(n,c) \
    install_element (n ## _NODE, &show_ipv6_ospf6_ ## c)
  
    INSTALL (VIEW, database_cmd);
 -  INSTALL (VIEW, database_detail_cmd);
    INSTALL (VIEW, database_type_cmd);
 -  INSTALL (VIEW, database_type_detail_cmd);
    INSTALL (VIEW, database_id_cmd);
 -  INSTALL (VIEW, database_id_detail_cmd);
 -  INSTALL (VIEW, database_linkstate_id_cmd);
 -  INSTALL (VIEW, database_linkstate_id_detail_cmd);
    INSTALL (VIEW, database_router_cmd);
 -  INSTALL (VIEW, database_router_detail_cmd);
 -  INSTALL (VIEW, database_adv_router_cmd);
 -  INSTALL (VIEW, database_adv_router_detail_cmd);
    INSTALL (VIEW, database_type_id_cmd);
 -  INSTALL (VIEW, database_type_id_detail_cmd);
 -  INSTALL (VIEW, database_type_linkstate_id_cmd);
 -  INSTALL (VIEW, database_type_linkstate_id_detail_cmd);
    INSTALL (VIEW, database_type_router_cmd);
 -  INSTALL (VIEW, database_type_router_detail_cmd);
 -  INSTALL (VIEW, database_type_adv_router_cmd);
 -  INSTALL (VIEW, database_type_adv_router_detail_cmd);
    INSTALL (VIEW, database_adv_router_linkstate_id_cmd);
 -  INSTALL (VIEW, database_adv_router_linkstate_id_detail_cmd);
    INSTALL (VIEW, database_id_router_cmd);
 -  INSTALL (VIEW, database_id_router_detail_cmd);
    INSTALL (VIEW, database_type_id_router_cmd);
 -  INSTALL (VIEW, database_type_id_router_detail_cmd);
    INSTALL (VIEW, database_type_adv_router_linkstate_id_cmd);
 -  INSTALL (VIEW, database_type_adv_router_linkstate_id_detail_cmd);
    INSTALL (VIEW, database_self_originated_cmd);
 -  INSTALL (VIEW, database_self_originated_detail_cmd);
    INSTALL (VIEW, database_type_self_originated_cmd);
 -  INSTALL (VIEW, database_type_self_originated_detail_cmd);
    INSTALL (VIEW, database_type_id_self_originated_cmd);
 -  INSTALL (VIEW, database_type_id_self_originated_detail_cmd);
    INSTALL (VIEW, database_type_self_originated_linkstate_id_cmd);
 -  INSTALL (VIEW, database_type_self_originated_linkstate_id_detail_cmd);
 -
 -  INSTALL (ENABLE, database_cmd);
 -  INSTALL (ENABLE, database_detail_cmd);
 -  INSTALL (ENABLE, database_type_cmd);
 -  INSTALL (ENABLE, database_type_detail_cmd);
 -  INSTALL (ENABLE, database_id_cmd);
 -  INSTALL (ENABLE, database_id_detail_cmd);
 -  INSTALL (ENABLE, database_linkstate_id_cmd);
 -  INSTALL (ENABLE, database_linkstate_id_detail_cmd);
 -  INSTALL (ENABLE, database_router_cmd);
 -  INSTALL (ENABLE, database_router_detail_cmd);
 -  INSTALL (ENABLE, database_adv_router_cmd);
 -  INSTALL (ENABLE, database_adv_router_detail_cmd);
 -  INSTALL (ENABLE, database_type_id_cmd);
 -  INSTALL (ENABLE, database_type_id_detail_cmd);
 -  INSTALL (ENABLE, database_type_linkstate_id_cmd);
 -  INSTALL (ENABLE, database_type_linkstate_id_detail_cmd);
 -  INSTALL (ENABLE, database_type_router_cmd);
 -  INSTALL (ENABLE, database_type_router_detail_cmd);
 -  INSTALL (ENABLE, database_type_adv_router_cmd);
 -  INSTALL (ENABLE, database_type_adv_router_detail_cmd);
 -  INSTALL (ENABLE, database_adv_router_linkstate_id_cmd);
 -  INSTALL (ENABLE, database_adv_router_linkstate_id_detail_cmd);
 -  INSTALL (ENABLE, database_id_router_cmd);
 -  INSTALL (ENABLE, database_id_router_detail_cmd);
 -  INSTALL (ENABLE, database_type_id_router_cmd);
 -  INSTALL (ENABLE, database_type_id_router_detail_cmd);
 -  INSTALL (ENABLE, database_type_adv_router_linkstate_id_cmd);
 -  INSTALL (ENABLE, database_type_adv_router_linkstate_id_detail_cmd);
 -  INSTALL (ENABLE, database_self_originated_cmd);
 -  INSTALL (ENABLE, database_self_originated_detail_cmd);
 -  INSTALL (ENABLE, database_type_self_originated_cmd);
 -  INSTALL (ENABLE, database_type_self_originated_detail_cmd);
 -  INSTALL (ENABLE, database_type_id_self_originated_cmd);
 -  INSTALL (ENABLE, database_type_id_self_originated_detail_cmd);
 -  INSTALL (ENABLE, database_type_self_originated_linkstate_id_cmd);
 -  INSTALL (ENABLE, database_type_self_originated_linkstate_id_detail_cmd);
  
-   INSTALL (ENABLE, database_cmd);
-   INSTALL (ENABLE, database_type_cmd);
-   INSTALL (ENABLE, database_id_cmd);
-   INSTALL (ENABLE, database_router_cmd);
-   INSTALL (ENABLE, database_type_id_cmd);
-   INSTALL (ENABLE, database_type_router_cmd);
-   INSTALL (ENABLE, database_adv_router_linkstate_id_cmd);
-   INSTALL (ENABLE, database_id_router_cmd);
-   INSTALL (ENABLE, database_type_id_router_cmd);
-   INSTALL (ENABLE, database_type_adv_router_linkstate_id_cmd);
-   INSTALL (ENABLE, database_self_originated_cmd);
-   INSTALL (ENABLE, database_type_self_originated_cmd);
-   INSTALL (ENABLE, database_type_id_self_originated_cmd);
-   INSTALL (ENABLE, database_type_self_originated_linkstate_id_cmd);
    /* Make ospf protocol socket. */
    ospf6_serv_sock ();
    thread_add_read (master, ospf6_receive, NULL, ospf6_sock);
Simple merge
diff --cc ospfd/ospf_ri.c
index bcb1cd8e20a864b0655b574c2da402ec0abe2236,be06cc0a8876933ee1b9fe5b8a684c808b86382c..b3d20dca7518dc8a41d75332f6d620f82043edf0
@@@ -1621,10 -1621,9 +1621,8 @@@ ospf_router_info_register_vty (void
  {
    install_element (VIEW_NODE, &show_ip_ospf_router_info_cmd);
    install_element (VIEW_NODE, &show_ip_ospf_router_info_pce_cmd);
-   install_element (ENABLE_NODE, &show_ip_ospf_router_info_cmd);
-   install_element (ENABLE_NODE, &show_ip_ospf_router_info_pce_cmd);
  
    install_element (OSPF_NODE, &router_info_area_cmd);
 -  install_element (OSPF_NODE, &router_info_as_cmd);
    install_element (OSPF_NODE, &no_router_info_cmd);
    install_element (OSPF_NODE, &pce_address_cmd);
    install_element (OSPF_NODE, &pce_path_scope_cmd);
index ebe426cee03d88cf542b1271c8b7ffaac9800310,6bd853bf89b49d8ad5e816350d95a45e50ae9122..6e88515d3e18ae751151897b443973af4aace675
@@@ -668,15 -662,219 +603,14 @@@ DEFUN (no_match_ip_nexthop
         "IP access-list number\n"
         "IP access-list number (expanded range)\n"
         "IP access-list name\n")
 -
 -DEFUN (match_ip_next_hop_prefix_list,
 -       match_ip_next_hop_prefix_list_cmd,
 -       "match ip next-hop prefix-list WORD",
 -       MATCH_STR
 -       IP_STR
 -       "Match next-hop address of route\n"
 -       "Match entries of prefix-lists\n"
 -       "IP prefix-list name\n")
  {
 -  return ospf_route_match_add (vty, vty->index, "ip next-hop prefix-list",
 -                             argv[0]);
 +  char *al = (argc == 5) ? argv[4]->arg : NULL;
 +  return ospf_route_match_delete (vty, vty->index, "ip next-hop", al);
  }
  
 -DEFUN (no_match_ip_next_hop_prefix_list,
 -       no_match_ip_next_hop_prefix_list_cmd,
 -       "no match ip next-hop prefix-list",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match next-hop address of route\n"
 -       "Match entries of prefix-lists\n")
 -{
 -  if (argc == 0)
 -    return ospf_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
 -                                  NULL);
 -  return ospf_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
 -                                argv[0]);
 -}
 -
 -ALIAS (no_match_ip_next_hop_prefix_list,
 -       no_match_ip_next_hop_prefix_list_val_cmd,
 -       "no match ip next-hop prefix-list WORD",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match next-hop address of route\n"
 -       "Match entries of prefix-lists\n"
 -       "IP prefix-list name\n")
 -
 -DEFUN (match_ip_address,
 -       match_ip_address_cmd,
 -       "match ip address (<1-199>|<1300-2699>|WORD)",
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "IP access-list number\n"
 -       "IP access-list number (expanded range)\n"
 -       "IP access-list name\n")
 -{
 -  return ospf_route_match_add (vty, vty->index, "ip address", argv[0]);
 -}
 -
 -DEFUN (no_match_ip_address,
 -       no_match_ip_address_cmd,
 -       "no match ip address",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n")
 -{
 -  if (argc == 0)
 -    return ospf_route_match_delete (vty, vty->index, "ip address", NULL);
 -
 -  return ospf_route_match_delete (vty, vty->index, "ip address", argv[0]);
 -}
 -
 -ALIAS (no_match_ip_address,
 -       no_match_ip_address_val_cmd,
 -       "no match ip address (<1-199>|<1300-2699>|WORD)",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "IP access-list number\n"
 -       "IP access-list number (expanded range)\n"
 -       "IP access-list name\n")
 -
 -DEFUN (match_ip_address_prefix_list,
 -       match_ip_address_prefix_list_cmd,
 -       "match ip address prefix-list WORD",
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "Match entries of prefix-lists\n"
 -       "IP prefix-list name\n")
 -{
 -  return ospf_route_match_add (vty, vty->index, "ip address prefix-list",
 -                             argv[0]);
 -}
 -
 -DEFUN (no_match_ip_address_prefix_list,
 -       no_match_ip_address_prefix_list_cmd,
 -       "no match ip address prefix-list",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "Match entries of prefix-lists\n")
 -{
 -  if (argc == 0)
 -    return ospf_route_match_delete (vty, vty->index, "ip address prefix-list",
 -                                  NULL);
 -  return ospf_route_match_delete (vty, vty->index, "ip address prefix-list",
 -                                argv[0]);
 -}
 -
 -ALIAS (no_match_ip_address_prefix_list,
 -       no_match_ip_address_prefix_list_val_cmd,
 -       "no match ip address prefix-list WORD",
 -       NO_STR
 -       MATCH_STR
 -       IP_STR
 -       "Match address of route\n"
 -       "Match entries of prefix-lists\n"
 -       "IP prefix-list name\n")
 -
 -DEFUN (match_interface,
 -       match_interface_cmd,
 -       "match interface WORD",
 -       MATCH_STR
 -       "Match first hop interface of route\n"
 -       "Interface name\n")
 -{
 -  return ospf_route_match_add (vty, vty->index, "interface", argv[0]);
 -}
 -
 -DEFUN (no_match_interface,
 -       no_match_interface_cmd,
 -       "no match interface",
 -       NO_STR
 -       MATCH_STR
 -       "Match first hop interface of route\n")
 -{
 -  if (argc == 0)
 -    return ospf_route_match_delete (vty, vty->index, "interface", NULL);
 -
 -  return ospf_route_match_delete (vty, vty->index, "interface", argv[0]);
 -}
 -
 -ALIAS (no_match_interface,
 -       no_match_interface_val_cmd,
 -       "no match interface WORD",
 -       NO_STR
 -       MATCH_STR
 -       "Match first hop interface of route\n"
 -       "Interface name\n")
 -
 -DEFUN (match_tag,
 -       match_tag_cmd,
 -       "match tag <1-4294967295>",
 -       MATCH_STR
 -       "Match tag of route\n"
 -       "Tag value\n")
 -{
 -  return ospf_route_match_add (vty, vty->index, "tag", argv[0]);
 -}
 -
 -DEFUN (no_match_tag,
 -       no_match_tag_cmd,
 -       "no match tag",
 -       NO_STR
 -       MATCH_STR
 -       "Match tag of route\n")
 -{
 -  if (argc == 0)
 -    return ospf_route_match_delete (vty, vty->index, "tag", NULL);
 -
 -  return ospf_route_match_delete (vty, vty->index, "tag", argv[0]);
 -}
 -
 -ALIAS (no_match_tag,
 -       no_match_tag_val_cmd,
 -       "no match tag <1-4294967295>",
 -       NO_STR
 -       MATCH_STR
 -       "Match tag of route\n"
 -       "Tag value\n")
 -
 -DEFUN (set_metric,
 -       set_metric_cmd,
 -       "set metric <0-4294967295>",
 -       SET_STR
 -       "Metric value for destination routing protocol\n"
 -       "Metric value\n")
 -{
 -  return ospf_route_set_add (vty, vty->index, "metric", argv[0]);
 -}
 -
 -DEFUN (no_set_metric,
 -       no_set_metric_cmd,
 -       "no set metric",
 -       NO_STR
 -       SET_STR
 -       "Metric value for destination routing protocol\n")
 -{
 -  if (argc == 0)
 -    return ospf_route_set_delete (vty, vty->index, "metric", NULL);
 -
 -  return ospf_route_set_delete (vty, vty->index, "metric", argv[0]);
 -}
 -
 -ALIAS (no_set_metric,
 -       no_set_metric_val_cmd,
 -       "no set metric <0-4294967295>",
 -       NO_STR
 -       SET_STR
 -       "Metric value for destination routing protocol\n"
 -       "Metric value\n")
--
  DEFUN (set_metric_type,
         set_metric_type_cmd,
 -       "set metric-type (type-1|type-2)",
 +       "set metric-type <type-1|type-2>",
         SET_STR
         "Type of metric for destination routing protocol\n"
         "OSPF[6] external type 1 metric\n"
diff --cc ospfd/ospf_te.c
Simple merge
index 359189b345d658d0a13a47a6edbeb803a492bed2,9da36f6a6c12924c37d71cd23b79cdcea2419640..8261a96a208cf00d0cdebe03dddfad38544b2a96
@@@ -9969,25 -9976,25 +9969,17 @@@ ospf_vty_show_init (void
  {
    /* "show ip ospf" commands. */
    install_element (VIEW_NODE, &show_ip_ospf_cmd);
-   install_element (ENABLE_NODE, &show_ip_ospf_cmd);
  
    install_element (VIEW_NODE, &show_ip_ospf_instance_cmd);
-   install_element (ENABLE_NODE, &show_ip_ospf_instance_cmd);
  
    /* "show ip ospf database" commands. */
 -  install_element (VIEW_NODE, &show_ip_ospf_database_type_cmd);
 -  install_element (VIEW_NODE, &show_ip_ospf_database_type_id_cmd);
 -  install_element (VIEW_NODE, &show_ip_ospf_database_type_id_adv_router_cmd);
    install_element (VIEW_NODE, &show_ip_ospf_database_type_adv_router_cmd);
 -  install_element (VIEW_NODE, &show_ip_ospf_database_type_id_self_cmd);
 -  install_element (VIEW_NODE, &show_ip_ospf_database_type_self_cmd);
    install_element (VIEW_NODE, &show_ip_ospf_database_cmd);
-   install_element (ENABLE_NODE, &show_ip_ospf_database_type_adv_router_cmd);
-   install_element (ENABLE_NODE, &show_ip_ospf_database_cmd);
-   install_element (ENABLE_NODE, &show_ip_ospf_database_max_cmd);
 +  install_element (VIEW_NODE, &show_ip_ospf_database_max_cmd);
  
 -  install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_cmd);
 -  install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_cmd);
 -  install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_adv_router_cmd);
    install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_adv_router_cmd);
 -  install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_self_cmd);
 -  install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_self_cmd);
    install_element (VIEW_NODE, &show_ip_ospf_instance_database_cmd);
-   install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_adv_router_cmd);
-   install_element (ENABLE_NODE, &show_ip_ospf_instance_database_cmd);
-   install_element (ENABLE_NODE, &show_ip_ospf_instance_database_max_cmd);
 +  install_element (VIEW_NODE, &show_ip_ospf_instance_database_max_cmd);
  
    /* "show ip ospf interface" commands. */
    install_element (VIEW_NODE, &show_ip_ospf_interface_cmd);
diff --cc pimd/pim_cmd.c
Simple merge
index 6df219628c853e7dd1df29109e9ba998e5d64e9c,359549ed80c04fb9fb993043701777e5e0060eaa..8c5092d78754f2bf6cd27ef7b6a636be2c683d1c
@@@ -119,19 -121,9 +121,9 @@@ rip_interface_new (void
    struct rip_interface *ri;
  
    ri = XCALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
 -  
 +
-   /* Default authentication type is simple password for Cisco
-      compatibility. */
-   ri->auth_type = RIP_NO_AUTH;
-   ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
-   /* Set default split-horizon behavior.  If the interface is Frame
-      Relay or SMDS is enabled, the default value for split-horizon is
-      off.  But currently Zebra does detect Frame Relay or SMDS
-      interface.  So all interface is set to split horizon.  */
-   ri->split_horizon_default = RIP_SPLIT_HORIZON;
-   ri->split_horizon = ri->split_horizon_default;
+   rip_interface_reset (ri);
 -  
 +
    return ri;
  }
  
@@@ -503,81 -495,82 +495,82 @@@ rip_interface_delete (int command, stru
    return 0;
  }
  
- void
- rip_interface_clean (void)
- {
-   struct listnode *node;
-   struct interface *ifp;
-   struct rip_interface *ri;
-   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
+ static void
+ rip_interface_clean (struct rip_interface *ri)
 -{
 -  ri->enable_network = 0;
 -  ri->enable_interface = 0;
 -  ri->running = 0;
 -
 -  if (ri->t_wakeup)
      {
-       ri = ifp->info;
 -      thread_cancel (ri->t_wakeup);
 -      ri->t_wakeup = NULL;
 +      ri->enable_network = 0;
 +      ri->enable_interface = 0;
 +      ri->running = 0;
 +
 +      if (ri->t_wakeup)
 +      {
 +        thread_cancel (ri->t_wakeup);
 +        ri->t_wakeup = NULL;
 +      }
      }
--}
  
  void
- rip_interface_reset (void)
+ rip_interfaces_clean (void)
  {
    struct listnode *node;
    struct interface *ifp;
-   struct rip_interface *ri;
  
    for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
 -{
+     rip_interface_clean (ifp->info);
+ }
+ static void
+ rip_interface_reset (struct rip_interface *ri)
-       ri = ifp->info;
 +    {
+   /* Default authentication type is simple password for Cisco
+      compatibility. */
+   ri->auth_type = RIP_NO_AUTH;
+   ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
  
-       ri->enable_network = 0;
-       ri->enable_interface = 0;
-       ri->running = 0;
+   /* Set default split-horizon behavior.  If the interface is Frame
+      Relay or SMDS is enabled, the default value for split-horizon is
+      off.  But currently Zebra does detect Frame Relay or SMDS
+      interface.  So all interface is set to split horizon.  */
+   ri->split_horizon_default = RIP_SPLIT_HORIZON;
+   ri->split_horizon = ri->split_horizon_default;
  
 -  ri->ri_send = RI_RIP_UNSPEC;
 -  ri->ri_receive = RI_RIP_UNSPEC;
 -  
 -  if (ri->auth_str)
 -    {
 -      free (ri->auth_str);
 -      ri->auth_str = NULL;
 -    }
 -  if (ri->key_chain)
 -    {
 -      free (ri->key_chain);
 -      ri->key_chain = NULL;
 -    }
 +      ri->ri_send = RI_RIP_UNSPEC;
 +      ri->ri_receive = RI_RIP_UNSPEC;
  
-       ri->auth_type = RIP_NO_AUTH;
 -  ri->list[RIP_FILTER_IN] = NULL;
 -  ri->list[RIP_FILTER_OUT] = NULL;
 +      if (ri->auth_str)
 +      {
 +        free (ri->auth_str);
 +        ri->auth_str = NULL;
 +      }
 +      if (ri->key_chain)
 +      {
 +        free (ri->key_chain);
 +        ri->key_chain = NULL;
 +      }
  
-       ri->split_horizon = RIP_NO_SPLIT_HORIZON;
-       ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
 -  ri->prefix[RIP_FILTER_IN] = NULL;
 -  ri->prefix[RIP_FILTER_OUT] = NULL;
 -  
 -  ri->recv_badpackets = 0;
 -  ri->recv_badroutes = 0;
 -  ri->sent_updates = 0;
 +      ri->list[RIP_FILTER_IN] = NULL;
 +      ri->list[RIP_FILTER_OUT] = NULL;
  
 -  ri->passive = 0;
 +      ri->prefix[RIP_FILTER_IN] = NULL;
 +      ri->prefix[RIP_FILTER_OUT] = NULL;
 +      
-       if (ri->t_wakeup)
-       {
-         thread_cancel (ri->t_wakeup);
-         ri->t_wakeup = NULL;
-       }
 +      ri->recv_badpackets = 0;
 +      ri->recv_badroutes = 0;
 +      ri->sent_updates = 0;
 +
 +      ri->passive = 0;
+   
+   rip_interface_clean (ri);
 -}
 +    }
+ void
+ rip_interfaces_reset (void)
+ {
+   struct listnode *node;
+   struct interface *ifp;
+   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
+     rip_interface_reset (ifp->info);
  }
  
  int
Simple merge
Simple merge
diff --cc ripd/ripd.c
index c5d928ba6d72caffc8ef18fbeffcd33451586da2,ab81996640c8c36166a6c58ada5ec4bfdb21155a..7b04368496328183d4b9ba5dd86e001214d5aceb
@@@ -329,84 -332,14 +332,14 @@@ rip_filter (int rip_distribute, struct 
                             (struct prefix *) p) == FILTER_DENY)
        {
          if (IS_RIP_DEBUG_PACKET)
-           zlog_debug ("%s/%d filtered by distribute in",
-                      inet_ntoa (p->prefix), p->prefixlen);
-         return -1;
-       }
-     }
-   if (ri->prefix[RIP_FILTER_IN])
-     {
-       if (prefix_list_apply (ri->prefix[RIP_FILTER_IN], 
-                            (struct prefix *) p) == PREFIX_DENY)
-       {
-         if (IS_RIP_DEBUG_PACKET)
-           zlog_debug ("%s/%d filtered by prefix-list in",
-                      inet_ntoa (p->prefix), p->prefixlen);
-         return -1;
-       }
-     }
-   /* All interface filter check. */
-   dist = distribute_lookup (NULL);
-   if (dist)
-     {
-       if (dist->list[DISTRIBUTE_IN])
-       {
-         alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
-           
-         if (alist)
-           {
-             if (access_list_apply (alist,
-                                    (struct prefix *) p) == FILTER_DENY)
-               {
-                 if (IS_RIP_DEBUG_PACKET)
-                   zlog_debug ("%s/%d filtered by distribute in",
-                              inet_ntoa (p->prefix), p->prefixlen);
+           zlog_debug ("%s/%d filtered by distribute %s",
+                         inet_ntoa (p->prefix), p->prefixlen, inout);
 -        return -1;
 -      }
 -    }
 +                return -1;
 +              }
 +          }
-       }
-       if (dist->prefix[DISTRIBUTE_IN])
-       {
-         plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
-         
-         if (plist)
-           {
-             if (prefix_list_apply (plist,
-                                    (struct prefix *) p) == PREFIX_DENY)
-               {
-                 if (IS_RIP_DEBUG_PACKET)
-                   zlog_debug ("%s/%d filtered by prefix-list in",
-                              inet_ntoa (p->prefix), p->prefixlen);
-                 return -1;
-               }
-           }
-       }
-     }
-   return 0;
- }
- static int
- rip_outgoing_filter (struct prefix_ipv4 *p, struct rip_interface *ri)
+   if (ri->prefix[rip_distribute])
 -    {
 +{
-   struct distribute *dist;
-   struct access_list *alist;
-   struct prefix_list *plist;
-   if (ri->list[RIP_FILTER_OUT])
-     {
-       if (access_list_apply (ri->list[RIP_FILTER_OUT],
-                            (struct prefix *) p) == FILTER_DENY)
-       {
-         if (IS_RIP_DEBUG_PACKET)
-           zlog_debug ("%s/%d is filtered by distribute out",
-                      inet_ntoa (p->prefix), p->prefixlen);
-         return -1;
-       }
-     }
-   if (ri->prefix[RIP_FILTER_OUT])
-     {
-       if (prefix_list_apply (ri->prefix[RIP_FILTER_OUT],
+       if (prefix_list_apply (ri->prefix[rip_distribute],
                             (struct prefix *) p) == PREFIX_DENY)
        {
          if (IS_RIP_DEBUG_PACKET)
    dist = distribute_lookup (NULL);
    if (dist)
      {
-       if (dist->list[DISTRIBUTE_OUT])
+       if (dist->list[distribute])
        {
-         alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
+         alist = access_list_lookup (AFI_IP, dist->list[distribute]);
 -
 +          
          if (alist)
            {
-             if (access_list_apply (alist,
-                                    (struct prefix *) p) == FILTER_DENY)
+             if (access_list_apply (alist, (struct prefix *) p) == FILTER_DENY)
                {
                  if (IS_RIP_DEBUG_PACKET)
-                   zlog_debug ("%s/%d filtered by distribute out",
-                              inet_ntoa (p->prefix), p->prefixlen);
+                   zlog_debug ("%s/%d filtered by distribute %s",
+                                 inet_ntoa (p->prefix), p->prefixlen, inout);
                  return -1;
                }
            }
        }
-       if (dist->prefix[DISTRIBUTE_OUT])
+       if (dist->prefix[distribute])
        {
-         plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
+         plist = prefix_list_lookup (AFI_IP, dist->prefix[distribute]);
 -
 +        
          if (plist)
            {
              if (prefix_list_apply (plist,
diff --cc ripd/ripd.h
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc ripngd/ripngd.c
index c896922bc063db761c7205d3143a6c498e316a93,2a32b934f2b50e06b3124a882b7c920819288e99..e7db9712080bc66d1780c848f3eeb7a083699fea
@@@ -623,84 -627,14 +627,14 @@@ ripng_filter (int ripng_distribute, str
                             (struct prefix *) p) == FILTER_DENY)
        {
          if (IS_RIPNG_DEBUG_PACKET)
-           zlog_debug ("%s/%d filtered by distribute in",
-                      inet6_ntoa (p->prefix), p->prefixlen);
-         return -1;
-       }
-     }
-   if (ri->prefix[RIPNG_FILTER_IN])
-     {
-       if (prefix_list_apply (ri->prefix[RIPNG_FILTER_IN], 
-                            (struct prefix *) p) == PREFIX_DENY)
-       {
-         if (IS_RIPNG_DEBUG_PACKET)
-           zlog_debug ("%s/%d filtered by prefix-list in",
-                      inet6_ntoa (p->prefix), p->prefixlen);
-         return -1;
-       }
-     }
-   /* All interface filter check. */
-   dist = distribute_lookup (NULL);
-   if (dist)
-     {
-       if (dist->list[DISTRIBUTE_IN])
-       {
-         alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_IN]);
-           
-         if (alist)
-           {
-             if (access_list_apply (alist,
-                                    (struct prefix *) p) == FILTER_DENY)
-               {
-                 if (IS_RIPNG_DEBUG_PACKET)
-                   zlog_debug ("%s/%d filtered by distribute in",
-                              inet6_ntoa (p->prefix), p->prefixlen);
-                 return -1;
-               }
-           }
-       }
-       if (dist->prefix[DISTRIBUTE_IN])
-       {
-         plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_IN]);
-         
-         if (plist)
-           {
-             if (prefix_list_apply (plist,
-                                    (struct prefix *) p) == PREFIX_DENY)
-               {
-                 if (IS_RIPNG_DEBUG_PACKET)
-                   zlog_debug ("%s/%d filtered by prefix-list in",
-                              inet6_ntoa (p->prefix), p->prefixlen);
+           zlog_debug ("%s/%d filtered by distribute %s",
+                         inet6_ntoa (p->prefix), p->prefixlen, inout);
 -        return -1;
 -      }
 -    }
 +                return -1;
 +              }
 +          }
-       }
-     }
-   return 0;
- }
- static int
- ripng_outgoing_filter (struct prefix_ipv6 *p, struct ripng_interface *ri)
+   if (ri->prefix[ripng_distribute])
 -    {
 +{
-   struct distribute *dist;
-   struct access_list *alist;
-   struct prefix_list *plist;
-   if (ri->list[RIPNG_FILTER_OUT])
-     {
-       if (access_list_apply (ri->list[RIPNG_FILTER_OUT],
-                            (struct prefix *) p) == FILTER_DENY)
-       {
-         if (IS_RIPNG_DEBUG_PACKET)
-           zlog_debug ("%s/%d is filtered by distribute out",
-                      inet6_ntoa (p->prefix), p->prefixlen);
-         return -1;
-       }
-     }
-   if (ri->prefix[RIPNG_FILTER_OUT])
-     {
-       if (prefix_list_apply (ri->prefix[RIPNG_FILTER_OUT],
+       if (prefix_list_apply (ri->prefix[ripng_distribute],
                             (struct prefix *) p) == PREFIX_DENY)
        {
          if (IS_RIPNG_DEBUG_PACKET)
    dist = distribute_lookup (NULL);
    if (dist)
      {
-       if (dist->list[DISTRIBUTE_OUT])
+       if (dist->list[distribute])
        {
-         alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_OUT]);
+         alist = access_list_lookup (AFI_IP6, dist->list[distribute]);
 -
 +          
          if (alist)
            {
              if (access_list_apply (alist,
                }
            }
        }
-       if (dist->prefix[DISTRIBUTE_OUT])
+       if (dist->prefix[distribute])
        {
-         plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_OUT]);
+         plist = prefix_list_lookup (AFI_IP6, dist->prefix[distribute]);
 -
 +        
          if (plist)
            {
              if (prefix_list_apply (plist,
diff --cc ripngd/ripngd.h
Simple merge
index 2b0f50cb2f27bfa8ecaa89f69143decf0374acf8,7c5dec9a5474c4e629f4d39d20e2fe9e338d1834..0c06aee4f46bfbe0cf44a4d3bdfb39fa0f57e868
@@@ -42,12 -42,14 +42,15 @@@ $ignore{'"ip vrf NAME"'} = "ignore"
  $ignore{'"router rip"'} = "ignore";
  $ignore{'"router ripng"'} = "ignore";
  $ignore{'"router ospf"'} = "ignore";
 -$ignore{'"router ospf <1-65535>"'} = "ignore";
 +$ignore{'"router ospf (1-65535)"'} = "ignore";
  $ignore{'"router ospf6"'} = "ignore";
+ $ignore{'"mpls ldp"'} = "ignore";
+ $ignore{'"l2vpn WORD type vpls"'} = "ignore";
+ $ignore{'"member pseudowire IFNAME"'} = "ignore";
  $ignore{'"router bgp"'} = "ignore";
 -$ignore{'"router bgp " "<1-4294967295>"'} = "ignore";
 -$ignore{'"router bgp " "<1-4294967295>" " (view|vrf) WORD"'} = "ignore";
 +$ignore{'"router bgp " "(1-4294967295)"'} = "ignore";
 +$ignore{'"router bgp " "(1-4294967295)" " <view|vrf> WORD"'} = "ignore";
 +$ignore{'"router bgp [(1-4294967295) [<view|vrf> WORD]]"'} = "ignore";
  $ignore{'"router isis WORD"'} = "ignore";
  $ignore{'"router zebra"'} = "ignore";
  $ignore{'"address-family ipv4"'} = "ignore";
@@@ -63,9 -65,12 +66,12 @@@ $ignore{'"address-family encapv6"'} = "
  $ignore{'"address-family vpnv6"'} = "ignore";
  $ignore{'"address-family vpnv6 unicast"'} = "ignore";
  $ignore{'"exit-address-family"'} = "ignore";
+ $ignore{'"vnc defaults"'} = "ignore";
+ $ignore{'"vnc nve-group NAME"'} = "ignore";
+ $ignore{'"exit-vnc"'} = "ignore";
  $ignore{'"key chain WORD"'} = "ignore";
 -$ignore{'"key <0-2147483647>"'} = "ignore";
 -$ignore{'"route-map WORD (deny|permit) <1-65535>"'} = "ignore";
 +$ignore{'"key (0-2147483647)"'} = "ignore";
 +$ignore{'"route-map WORD <deny|permit> (1-65535)"'} = "ignore";
  $ignore{'"show route-map"'} = "ignore";
  $ignore{'"line vty"'} = "ignore";
  $ignore{'"who"'} = "ignore";
@@@ -158,7 -162,10 +164,10 @@@ foreach (@ARGV) 
          elsif ($file =~ /lib\/vty\.c$/) {
             $protocol = "VTYSH_ALL";
          }
 -      else {
+         elsif ($file =~ /librfp\/.*\.c$/ || $file =~ /rfapi\/.*\.c$/) {
+            $protocol = "VTYSH_BGPD";
+         }
 +        else {
             ($protocol) = ($file =~ /^.*\/([a-z0-9]+)\/[a-zA-Z0-9_\-]+\.c$/);
             $protocol = "VTYSH_" . uc $protocol;
          }
  # If extract.pl fails with a error message and you've been
  # modifying the cli, then go back and fix your code to
  # not have cli command function collisions.
 -#
 -# If you've removed a cli overwrite, you can safely subtract
 -# one from $bad_cli_stomps.  If you've added to the problem
  # please fix your code before submittal
 -if ($cli_stomp != $bad_cli_stomps) {
 -    warn "Expected $bad_cli_stomps command line stomps, but got $cli_stomp instead\n";
 -    if ($cli_stomp > $bad_cli_stomps) {
 -        exit $cli_stomp;
 -    }
 +if ($cli_stomp) {
 +    warn "There are $cli_stomp command line stomps\n";
-     exit $cli_stomp;
  }
  
  # Check finaly alive $cmd;
diff --cc vtysh/vtysh.c
index 70b0d7832e85cf2654c643462a23e285b25f625d,39ad8d81d636d5fd283d166950a9a4c2d8e5288f..2d040fd5d3fc23cc81a1d150a98e5a9b8a5d9bc3
@@@ -1566,15 -1779,25 +1778,29 @@@ DEFUNSH (VTYSH_OSPF6D
    return vtysh_exit (vty);
  }
  
 -ALIAS (vtysh_exit_ospf6d,
 -       vtysh_quit_ospf6d_cmd,
 -       "quit",
 -       "Exit current mode and down to previous mode\n")
 +DEFUNSH (VTYSH_OSPF6D,
 +         vtysh_quit_ospf6d,
 +         vtysh_quit_ospf6d_cmd,
 +         "quit",
 +         "Exit current mode and down to previous mode\n")
 +{
 +  return vtysh_exit_ospf6d (self, vty, argc, argv);
 +}
  
+ DEFUNSH (VTYSH_LDPD,
+        vtysh_exit_ldpd,
+        vtysh_exit_ldpd_cmd,
+        "exit",
+        "Exit current mode and down to previous mode\n")
+ {
+   return vtysh_exit (vty);
+ }
+ ALIAS (vtysh_exit_ldpd,
+        vtysh_quit_ldpd_cmd,
+        "quit",
+        "Exit current mode and down to previous mode\n")
  DEFUNSH (VTYSH_ISISD,
         vtysh_exit_isisd,
         vtysh_exit_isisd_cmd,
@@@ -1623,8 -1837,16 +1849,8 @@@ DEFUNSH (VTYSH_INTERFACE
    return CMD_SUCCESS;
  }
  
 -ALIAS_SH (VTYSH_ZEBRA,
 -       vtysh_interface,
 -       vtysh_interface_vrf_cmd,
 -       "interface IFNAME " VRF_CMD_STR,
 -       "Select an interface to configure\n"
 -         "Interface's name\n"
 -         VRF_CMD_HELP_STR)
 -
  /* TODO Implement "no interface command in isisd. */
- DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D,
+ DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD,
         vtysh_no_interface_cmd,
         "no interface IFNAME",
         NO_STR
@@@ -1708,9 -1922,9 +1934,9 @@@ DEFUNSH (VTYSH_VRF
  
  /* TODO Implement interface description commands in ripngd, ospf6d
   * and isisd. */
- DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
+ DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_LDPD,
         interface_desc_cmd,
 -       "description .LINE",
 +       "description LINE...",
         "Interface specific description\n"
         "Characters describing this interface\n")
         
@@@ -2158,17 -2396,9 +2384,18 @@@ DEFUNSH (VTYSH_ALL
  
  DEFUN (vtysh_write_terminal,
         vtysh_write_terminal_cmd,
-        "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|pimd>]",
 -       "write terminal",
++       "write terminal [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
         "Write running configuration to memory, network, or terminal\n"
 -       "Write to terminal\n")
 +       "Write to terminal\n"
 +       "For the zebra daemon\n"
 +       "For the rip daemon\n"
 +       "For the ripng daemon\n"
 +       "For the ospf daemon\n"
 +       "For the ospfv6 daemon\n"
++       "For the ldpd daemon"
 +       "For the bgp daemon\n"
 +       "For the isis daemon\n"
 +       "For the pim daemon\n")
  {
    u_int i;
    char line[] = "write terminal\n";
    return CMD_SUCCESS;
  }
  
 -DEFUN (vtysh_write_terminal_daemon,
 -       vtysh_write_terminal_daemon_cmd,
 -       "write terminal (zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd)",
 -       "Write running configuration to memory, network, or terminal\n"
 -       "Write to terminal\n"
 +DEFUN (vtysh_show_running_config,
 +       vtysh_show_running_config_cmd,
-        "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|pimd>]",
++       "show running-config [<zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd>]",
 +       SHOW_STR
 +       "Current operating configuration\n"
         "For the zebra daemon\n"
         "For the rip daemon\n"
         "For the ripng daemon\n"
@@@ -2329,12 -2572,29 +2557,30 @@@ write_config_integrated(void
    return CMD_SUCCESS;
  }
  
+ static bool vtysh_writeconfig_integrated(void)
+ {
+   struct stat s;
+   switch (vtysh_write_integrated)
+     {
+     case WRITE_INTEGRATED_UNSPECIFIED:
+       if (stat(integrate_default, &s) && errno == ENOENT)
+         return false;
+       return true;
+     case WRITE_INTEGRATED_NO:
+       return false;
+     case WRITE_INTEGRATED_YES:
+       return true;
+     }
+   return true;
+ }
  DEFUN (vtysh_write_memory,
         vtysh_write_memory_cmd,
 -       "write memory",
 +       "write [<memory|file>]",
         "Write running configuration to memory, network, or terminal\n"
 -       "Write configuration to the file (same as write file)\n")
 +       "Write configuration to the file (same as write file)\n"
 +       "Write configuration to the file (same as write memory)\n")
  {
    int ret = CMD_SUCCESS;
    char line[] = "write memory\n";
@@@ -2384,14 -2644,42 +2630,13 @@@ DEFUN (vtysh_copy_running_config
         "Copy from one file to another\n"
         "Copy from current system configuration\n"
         "Copy to startup configuration\n")
 -
 -ALIAS (vtysh_write_memory,
 -       vtysh_write_file_cmd,
 -       "write file",
 -       "Write running configuration to memory, network, or terminal\n"
 -       "Write configuration to the file (same as write memory)\n")
 -
 -ALIAS (vtysh_write_memory,
 -       vtysh_write_cmd,
 -       "write",
 -       "Write running configuration to memory, network, or terminal\n")
 -
 -ALIAS (vtysh_write_terminal,
 -       vtysh_show_running_config_cmd,
 -       "show running-config",
 -       SHOW_STR
 -       "Current operating configuration\n")
 -
 -ALIAS (vtysh_write_terminal,
 -       vtysh_show_running_config_daemon_cmd,
 -       "show running-config (zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd)",
 -       SHOW_STR
 -       "Current operating configuration\n"
 -       "For the zebra daemon\n"
 -       "For the rip daemon\n"
 -       "For the ripng daemon\n"
 -       "For the ospf daemon\n"
 -       "For the ospfv6 daemon\n"
 -       "For the ldp daemon\n"
 -       "For the bgp daemon\n"
 -       "For the isis daemon\n"
 -       "For the pim daemon\n")
 +{
 +  return vtysh_write_memory (self, vty, argc, argv);
 +}
  
  DEFUN (vtysh_terminal_length,
         vtysh_terminal_length_cmd,
 -       "terminal length <0-512>",
 +       "terminal length (0-512)",
         "Set terminal line parameters\n"
         "Set number of lines on a screen\n"
         "Number of lines on screen (0 for no pausing)\n")
@@@ -2920,10 -3230,9 +3188,8 @@@ vtysh_init_vty (void
  
    /* "exit" command. */
    install_element (VIEW_NODE, &vtysh_exit_all_cmd);
 -  install_element (VIEW_NODE, &vtysh_quit_all_cmd);
    install_element (CONFIG_NODE, &vtysh_exit_all_cmd);
    /* install_element (CONFIG_NODE, &vtysh_quit_all_cmd); */
-   install_element (ENABLE_NODE, &vtysh_exit_all_cmd);
-   install_element (ENABLE_NODE, &vtysh_quit_all_cmd);
    install_element (RIP_NODE, &vtysh_exit_ripd_cmd);
    install_element (RIP_NODE, &vtysh_quit_ripd_cmd);
    install_element (RIPNG_NODE, &vtysh_exit_ripngd_cmd);
  #ifdef HAVE_IPV6
    install_element (CONFIG_NODE, &router_ospf6_cmd);
  #endif
+   install_element (CONFIG_NODE, &ldp_mpls_ldp_cmd);
+   install_element (LDP_NODE, &ldp_address_family_ipv4_cmd);
+   install_element (LDP_NODE, &ldp_address_family_ipv6_cmd);
+   install_element (LDP_IPV4_NODE, &ldp_interface_ifname_cmd);
+   install_element (LDP_IPV6_NODE, &ldp_interface_ifname_cmd);
+   install_element (CONFIG_NODE, &ldp_l2vpn_word_type_vpls_cmd);
+   install_element (LDP_L2VPN_NODE, &ldp_member_pseudowire_ifname_cmd);
    install_element (CONFIG_NODE, &router_isis_cmd);
    install_element (CONFIG_NODE, &router_bgp_cmd);
 -  install_element (CONFIG_NODE, &router_bgp_asn_cmd);
 -  install_element (CONFIG_NODE, &router_bgp_view_cmd);
    install_element (BGP_NODE, &address_family_vpnv4_cmd);
    install_element (BGP_NODE, &address_family_vpnv4_unicast_cmd);
    install_element (BGP_NODE, &address_family_vpnv6_cmd);
Simple merge
diff --cc zebra/debug.c
index 6acf32b43daecfbfc9e9febb9de89aa23a1db8f3,92354070ef6873463a7885e1c3422df7226c21f1..65ae3fd1743bcf8cae03b6770ba96b0b92a95d96
@@@ -422,9 -449,10 +454,9 @@@ zebra_debug_init (void
  
    install_element (VIEW_NODE, &show_debugging_zebra_cmd);
  
--  install_element (ENABLE_NODE, &show_debugging_zebra_cmd);
    install_element (ENABLE_NODE, &debug_zebra_events_cmd);
    install_element (ENABLE_NODE, &debug_zebra_nht_cmd);
+   install_element (ENABLE_NODE, &debug_zebra_mpls_cmd);
    install_element (ENABLE_NODE, &debug_zebra_packet_cmd);
    install_element (ENABLE_NODE, &debug_zebra_packet_direct_cmd);
    install_element (ENABLE_NODE, &debug_zebra_packet_detail_cmd);
index 62340a460a15640bdd9211c47a8e944cbbaddb6d,0f4d2ee9e47cbb5667bf32961209103074c69ca6..bbe19fbaf4bae7020e83a91ee3b701d242dc99cb
@@@ -1233,8 -1233,7 +1233,7 @@@ DEFUN_NOSH (zebra_interface
            "Interface's name\n")
  {
    int ret;
-   struct interface *ifp;
 -
 +  
    /* Call lib interface() */
    if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
      return ret;
@@@ -1553,10 -1567,9 +1549,9 @@@ DEFUN (linkdetect
         "link-detect",
         "Enable link detection on interface\n")
  {
-   struct interface *ifp;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    int if_was_operative;
 -
 +  
-   ifp = (struct interface *) vty->index;
    if_was_operative = if_is_no_ptm_operative(ifp);
    SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
  
@@@ -1657,12 -1666,10 +1648,11 @@@ DEFUN (bandwidth_if
         "Set bandwidth informational parameter\n"
         "Bandwidth in megabits\n")
  {
-   struct interface *ifp;   
 +  int idx_number = 1;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    unsigned int bandwidth;
 -
 -  bandwidth = strtol(argv[0], NULL, 10);
 +  
-   ifp = (struct interface *) vty->index;
 +  bandwidth = strtol(argv[idx_number]->arg, NULL, 10);
  
    /* bandwidth range is <1-100000> */
    if (bandwidth < 1 || bandwidth > 100000)
  
  DEFUN (no_bandwidth_if,
         no_bandwidth_if_cmd,
 -       "no bandwidth",
 +       "no bandwidth [(1-100000)]",
         NO_STR
 -       "Set bandwidth informational parameter\n")
 +       "Set bandwidth informational parameter\n"
 +       "Bandwidth in megabits\n")
  {
-   struct interface *ifp;   
-   
-   ifp = (struct interface *) vty->index;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
  
    ifp->bandwidth = 0;
    
@@@ -1817,8 -1828,7 +1806,8 @@@ DEFUN (link_params_metric
         "Link metric for MPLS-TE purpose\n"
         "Metric value in decimal\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_number = 1;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct if_link_params *iflp = if_link_params_get (ifp);
    u_int32_t metric;
  
@@@ -1850,8 -1860,7 +1839,8 @@@ DEFUN (link_params_maxbw
         "Maximum bandwidth that can be used\n"
         "Bytes/second (IEEE floating point format)\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_bandwidth = 1;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct if_link_params *iflp = if_link_params_get (ifp);
  
    float bw;
@@@ -1895,8 -1904,7 +1884,8 @@@ DEFUN (link_params_max_rsv_bw
         "Maximum bandwidth that may be reserved\n"
         "Bytes/second (IEEE floating point format)\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_bandwidth = 1;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct if_link_params *iflp = if_link_params_get (ifp);
    float bw;
  
@@@ -1929,9 -1937,7 +1918,9 @@@ DEFUN (link_params_unrsv_bw
         "Priority\n"
         "Bytes/second (IEEE floating point format)\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_number = 1;
 +  int idx_bandwidth = 2;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct if_link_params *iflp = if_link_params_get (ifp);
    int priority;
    float bw;
@@@ -1972,8 -1978,7 +1961,8 @@@ DEFUN (link_params_admin_grp
         "Administrative group membership\n"
         "32-bit Hexadecimal value (e.g. 0xa1)\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_bitpattern = 1;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct if_link_params *iflp = if_link_params_get (ifp);
    unsigned long value;
  
@@@ -2013,10 -2018,7 +2002,10 @@@ DEFUN (link_params_inter_as
         "Remote AS number\n"
         "AS number in the range <1-4294967295>\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_ipv4 = 1;
 +  int idx_number = 3;
 +
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct if_link_params *iflp = if_link_params_get (ifp);
    struct in_addr addr;
    u_int32_t as;
@@@ -2071,77 -2072,78 +2059,77 @@@ DEFUN (no_link_params_inter_as
  /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions & draft-ietf-isis-metric-extensions-07.txt */
  DEFUN (link_params_delay,
         link_params_delay_cmd,
 -       "delay <0-16777215>",
 +       "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
         "Unidirectional Average Link Delay\n"
 -       "Average delay in micro-second as decimal (0...16777215)\n")
 +       "Average delay in micro-second as decimal (0...16777215)\n"
 +       "Minimum delay\n"
 +       "Minimum delay in micro-second as decimal (0...16777215)\n"
 +       "Maximum delay\n"
 +       "Maximum delay in micro-second as decimal (0...16777215)\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  /* Get and Check new delay values */
 +  u_int32_t delay = 0, low = 0, high = 0;
 +  VTY_GET_ULONG("delay", delay, argv[1]->arg);
 +  if (argc == 6)
 +  {
 +    VTY_GET_ULONG("minimum delay", low, argv[3]->arg);
 +    VTY_GET_ULONG("maximum delay", high, argv[5]->arg);
 +  }
 +
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct if_link_params *iflp = if_link_params_get (ifp);
 -  u_int32_t delay = 0, low = 0, high = 0;
    u_int8_t update = 0;
  
 -  /* Get and Check new delay values */
 -  VTY_GET_ULONG("delay", delay, argv[0]);
 -  switch (argc)
 -    {
 -    case 1:
 -      /* Check new delay value against old Min and Max delays if set */
 -      if (IS_PARAM_SET(iflp, LP_MM_DELAY)
 -          && (delay <= iflp->min_delay || delay >= iflp->max_delay))
 -        {
 -          vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
 -                   iflp->min_delay, iflp->max_delay, VTY_NEWLINE);
 -          return CMD_WARNING;
 -        }
 -      /* Update delay if value is not set or change */
 -      if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay)
 -        {
 -          iflp->av_delay = delay;
 -          SET_PARAM(iflp, LP_DELAY);
 -          update = 1;
 -        }
 -      /* Unset Min and Max delays if already set */
 -      if (IS_PARAM_SET(iflp, LP_MM_DELAY))
 -        {
 -          iflp->min_delay = 0;
 -          iflp->max_delay = 0;
 -          UNSET_PARAM(iflp, LP_MM_DELAY);
 -          update = 1;
 -        }
 -      break;
 -    case 2:
 -      vty_out (vty, "You should specify both Minimum and Maximum delay with Average delay%s",
 -               VTY_NEWLINE);
 -      return CMD_WARNING;
 -    break;
 -    case 3:
 -      VTY_GET_ULONG("minimum delay", low, argv[1]);
 -      VTY_GET_ULONG("maximum delay", high, argv[2]);
 -      /* Check new delays value coherency */
 -      if (delay <= low || delay >= high)
 -        {
 -          vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
 -                   low, high, VTY_NEWLINE);
 -          return CMD_WARNING;
 -        }
 -      /* Update Delays if needed */
 -      if (IS_PARAM_UNSET(iflp, LP_DELAY)
 -          || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
 -          || iflp->av_delay != delay
 -          || iflp->min_delay != low
 -          || iflp->max_delay != high)
 -        {
 -          iflp->av_delay = delay;
 -          SET_PARAM(iflp, LP_DELAY);
 -          iflp->min_delay = low;
 -          iflp->max_delay = high;
 -          SET_PARAM(iflp, LP_MM_DELAY);
 -          update = 1;
 -        }
 -      break;
 -    default:
 -      return CMD_WARNING;
 -      break;
 -    }
 +  if (argc == 2)
 +  {
 +    /* Check new delay value against old Min and Max delays if set */
 +    if (IS_PARAM_SET(iflp, LP_MM_DELAY)
 +        && (delay <= iflp->min_delay || delay >= iflp->max_delay))
 +      {
 +        vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
 +                 iflp->min_delay, iflp->max_delay, VTY_NEWLINE);
 +        return CMD_WARNING;
 +      }
 +    /* Update delay if value is not set or change */
 +    if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay)
 +      {
 +        iflp->av_delay = delay;
 +        SET_PARAM(iflp, LP_DELAY);
 +        update = 1;
 +      }
 +    /* Unset Min and Max delays if already set */
 +    if (IS_PARAM_SET(iflp, LP_MM_DELAY))
 +      {
 +        iflp->min_delay = 0;
 +        iflp->max_delay = 0;
 +        UNSET_PARAM(iflp, LP_MM_DELAY);
 +        update = 1;
 +      }
 +  }
 +  else
 +  {
 +    /* Check new delays value coherency */
 +    if (delay <= low || delay >= high)
 +      {
 +        vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
 +                 low, high, VTY_NEWLINE);
 +        return CMD_WARNING;
 +      }
 +    /* Update Delays if needed */
 +    if (IS_PARAM_UNSET(iflp, LP_DELAY)
 +        || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
 +        || iflp->av_delay != delay
 +        || iflp->min_delay != low
 +        || iflp->max_delay != high)
 +      {
 +        iflp->av_delay = delay;
 +        SET_PARAM(iflp, LP_DELAY);
 +        iflp->min_delay = low;
 +        iflp->max_delay = high;
 +        SET_PARAM(iflp, LP_MM_DELAY);
 +        update = 1;
 +      }
 +  }
  
    /* force protocols to update LINK STATE due to parameters change */
    if (update == 1 && if_is_operative (ifp))
@@@ -2179,8 -2191,7 +2167,8 @@@ DEFUN (link_params_delay_var
         "Unidirectional Link Delay Variation\n"
         "delay variation in micro-second as decimal (0...16777215)\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_number = 1;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct if_link_params *iflp = if_link_params_get (ifp);
    u_int32_t value;
  
@@@ -2212,8 -2223,7 +2200,8 @@@ DEFUN (link_params_pkt_loss
         "Unidirectional Link Packet Loss\n"
         "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_percentage = 1;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct if_link_params *iflp = if_link_params_get (ifp);
    float fval;
  
@@@ -2253,8 -2263,7 +2241,8 @@@ DEFUN (link_params_res_bw
         "Unidirectional Residual Bandwidth\n"
         "Bytes/second (IEEE floating point format)\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_bandwidth = 1;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct if_link_params *iflp = if_link_params_get (ifp);
    float bw;
  
@@@ -2300,8 -2309,7 +2288,8 @@@ DEFUN (link_params_ava_bw
         "Unidirectional Available Bandwidth\n"
         "Bytes/second (IEEE floating point format)\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_bandwidth = 1;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct if_link_params *iflp = if_link_params_get (ifp);
    float bw;
  
@@@ -2347,8 -2355,7 +2335,8 @@@ DEFUN (link_params_use_bw
         "Unidirectional Utilised Bandwidth\n"
         "Bytes/second (IEEE floating point format)\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_bandwidth = 1;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct if_link_params *iflp = if_link_params_get (ifp);
    float bw;
  
@@@ -2536,8 -2543,8 +2524,9 @@@ DEFUN (ip_address
         "Set the IP address of an interface\n"
         "IP address (e.g. 10.0.0.1/8)\n")
  {
-   return ip_address_install (vty, vty->index, argv[idx_ipv4_prefixlen]->arg, NULL, NULL);
 +  int idx_ipv4_prefixlen = 2;
 -  return ip_address_install (vty, ifp, argv[0], NULL, NULL);
+   VTY_DECLVAR_CONTEXT (interface, ifp);
++  return ip_address_install (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, NULL);
  }
  
  DEFUN (no_ip_address,
         "Set the IP address of an interface\n"
         "IP Address (e.g. 10.0.0.1/8)")
  {
-   return ip_address_uninstall (vty, vty->index, argv[idx_ipv4_prefixlen]->arg, NULL, NULL);
 +  int idx_ipv4_prefixlen = 3;
 -  return ip_address_uninstall (vty, ifp, argv[0], NULL, NULL);
+   VTY_DECLVAR_CONTEXT (interface, ifp);
++  return ip_address_uninstall (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, NULL);
  }
  
  
@@@ -2563,9 -2570,8 +2553,10 @@@ DEFUN (ip_address_label
         "Label of this address\n"
         "Label\n")
  {
-   return ip_address_install (vty, vty->index, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg);
 +  int idx_ipv4_prefixlen = 2;
 +  int idx_line = 4;
 -  return ip_address_install (vty, ifp, argv[0], NULL, argv[1]);
+   VTY_DECLVAR_CONTEXT (interface, ifp);
++  return ip_address_install (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg);
  }
  
  DEFUN (no_ip_address_label,
         "Label of this address\n"
         "Label\n")
  {
-   return ip_address_uninstall (vty, vty->index, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg);
 +  int idx_ipv4_prefixlen = 3;
 +  int idx_line = 5;
 -  return ip_address_uninstall (vty, ifp, argv[0], NULL, argv[1]);
+   VTY_DECLVAR_CONTEXT (interface, ifp);
++  return ip_address_uninstall (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg);
  }
  #endif /* HAVE_NETLINK */
  
@@@ -2743,8 -2748,8 +2735,9 @@@ DEFUN (ipv6_address
         "Set the IP address of an interface\n"
         "IPv6 address (e.g. 3ffe:506::1/48)\n")
  {
-   return ipv6_address_install (vty, vty->index, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0);
 +  int idx_ipv6_prefixlen = 2;
 -  return ipv6_address_install (vty, ifp, argv[0], NULL, NULL, 0);
+   VTY_DECLVAR_CONTEXT (interface, ifp);
++  return ipv6_address_install (vty, ifp, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0);
  }
  
  DEFUN (no_ipv6_address,
         "Set the IP address of an interface\n"
         "IPv6 address (e.g. 3ffe:506::1/48)\n")
  {
-   return ipv6_address_uninstall (vty, vty->index, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0);
 +  int idx_ipv6_prefixlen = 3;
 -  return ipv6_address_uninstall (vty, ifp, argv[0], NULL, NULL, 0);
+   VTY_DECLVAR_CONTEXT (interface, ifp);
++  return ipv6_address_uninstall (vty, ifp, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0);
  }
  #endif /* HAVE_IPV6 */
  
@@@ -2930,17 -2935,18 +2924,14 @@@ zebra_if_init (void
    install_node (&vrf_node, vrf_config_write);
  
    install_element (VIEW_NODE, &show_interface_cmd);
 -  install_element (VIEW_NODE, &show_interface_vrf_cmd);
    install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
 -  install_element (VIEW_NODE, &show_interface_name_cmd);
    install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
    install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
-   install_element (ENABLE_NODE, &show_interface_cmd);
-   install_element (ENABLE_NODE, &show_interface_vrf_all_cmd);
-   install_element (ENABLE_NODE, &show_interface_name_vrf_cmd);
-   install_element (ENABLE_NODE, &show_interface_name_vrf_all_cmd);
++
    install_element (ENABLE_NODE, &show_interface_desc_cmd);
 -  install_element (ENABLE_NODE, &show_interface_desc_vrf_cmd);
    install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
    install_element (CONFIG_NODE, &zebra_interface_cmd);
 -  install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
    install_element (CONFIG_NODE, &no_interface_cmd);
 -  install_element (CONFIG_NODE, &no_interface_vrf_cmd);
    install_default (INTERFACE_NODE);
    install_element (INTERFACE_NODE, &interface_desc_cmd);
    install_element (INTERFACE_NODE, &no_interface_desc_cmd);
index 2f741380f58374573594d46e43fc13f87d5eb1a3,9d8c2e67bf1e58bfbd3e53f038c24994ee74bba5..3e244f5af30f991bc02b51e7b5614dbed558a17a
   * You should have received a copy of the GNU General Public License
   * along with GNU Zebra; see the file COPYING.  If not, write to the Free
   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-- * 02111-1307, USA.  
++ * 02111-1307, USA.
   */
  
--/* 
++/*
   * This work includes work with the following copywrite:
   *
   * Copyright (C) 1997, 2000 Kunihiro Ishiguro
   *
   */
  
--/* 
++/*
   * Thanks to Jens Låås at Swedish University of Agricultural Sciences
   * for reviewing and tests.
   */
@@@ -36,7 -36,7 +36,7 @@@
  
  #include <zebra.h>
  
--#ifdef HAVE_IRDP 
++#ifdef HAVE_IRDP
  
  #include "if.h"
  #include "vty.h"
@@@ -81,7 -81,7 +81,7 @@@ irdp_get_prefix(struct interface *ifp
  {
    struct listnode *node;
    struct connected *ifc;
--  
++
    if (ifp->connected)
      for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
        return ifc->address;
@@@ -91,9 -91,9 +91,9 @@@
  
  /* Join to the add/leave multicast group. */
  static int
--if_group (struct interface *ifp, 
--        int sock, 
--        u_int32_t group, 
++if_group (struct interface *ifp,
++        int sock,
++        u_int32_t group,
          int add_leave)
  {
    struct ip_mreq m;
                    (char *) &m, sizeof (struct ip_mreq));
    if (ret < 0)
      zlog_warn ("IRDP: %s can't setsockopt %s: %s",
--             add_leave == IP_ADD_MEMBERSHIP? "join group":"leave group", 
++             add_leave == IP_ADD_MEMBERSHIP? "join group":"leave group",
               inet_2a(group, b1),
               safe_strerror (errno));
  
@@@ -137,7 -137,7 +137,7 @@@ if_add_group (struct interface *ifp
    }
  
    if(irdp->flags & IF_DEBUG_MISC )
--    zlog_debug("IRDP: Adding group %s for %s", 
++    zlog_debug("IRDP: Adding group %s for %s",
               inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1),
               ifp->name);
    return 0;
@@@ -156,7 -156,7 +156,7 @@@ if_drop_group (struct interface *ifp
      return ret;
  
    if(irdp->flags & IF_DEBUG_MISC)
--    zlog_debug("IRDP: Leaving group %s for %s", 
++    zlog_debug("IRDP: Leaving group %s for %s",
               inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1),
               ifp->name);
    return 0;
@@@ -206,7 -206,7 +206,7 @@@ irdp_if_start(struct interface *ifp, in
    }
    irdp->flags |= IF_ACTIVE;
  
--  if(!multicast) 
++  if(!multicast)
      irdp->flags |= IF_BROADCAST;
  
    if_add_update(ifp);
  
    if( multicast) {
      if_add_group(ifp);
--    
++
      if (! (ifp->flags & (IFF_MULTICAST|IFF_ALLMULTI))) {
        zlog_warn("IRDP: Interface not multicast enabled %s", ifp->name);
      }
    }
  
--  if(set_defaults) 
++  if(set_defaults)
      if_set_defaults(ifp);
  
    irdp->irdp_sent = 0;
          seed = ifc->address->u.prefix4.s_addr;
          break;
        }
--  
++
    srandom(seed);
--  timer =  (random () % IRDP_DEFAULT_INTERVAL) + 1; 
++  timer =  (random () % IRDP_DEFAULT_INTERVAL) + 1;
  
    irdp->AdvPrefList = list_new();
    irdp->AdvPrefList->del =  (void (*)(void *)) Adv_free; /* Destructor */
    /* And this for startup. Speed limit from 1991 :-). But it's OK*/
  
    if(irdp->irdp_sent < MAX_INITIAL_ADVERTISEMENTS &&
--     timer > MAX_INITIAL_ADVERT_INTERVAL ) 
++     timer > MAX_INITIAL_ADVERT_INTERVAL )
          timer= MAX_INITIAL_ADVERT_INTERVAL;
  
--  
++
    if(irdp->flags & IF_DEBUG_MISC)
--    zlog_debug("IRDP: Init timer for %s set to %u", 
--             ifp->name, 
++    zlog_debug("IRDP: Init timer for %s set to %u",
++             ifp->name,
               timer);
  
--  irdp->t_advertise = thread_add_timer(zebrad.master, 
--                                     irdp_send_thread, 
--                                     ifp, 
++  irdp->t_advertise = thread_add_timer(zebrad.master,
++                                     irdp_send_thread,
++                                     ifp,
                                       timer);
  }
  
@@@ -270,7 -270,7 +270,7 @@@ irdp_if_stop(struct interface *ifp
  {
    struct zebra_if *zi=ifp->info;
    struct irdp_interface *irdp=&zi->irdp;
--  
++
    if (irdp == NULL) {
      zlog_warn ("Interface %s structure is NULL", ifp->name);
      return;
      return;
    }
  
--  if(! (irdp->flags & IF_BROADCAST)) 
++  if(! (irdp->flags & IF_BROADCAST))
      if_drop_group(ifp);
  
    irdp_advert_off(ifp);
@@@ -307,9 -307,9 +307,9 @@@ irdp_if_shutdown(struct interface *ifp
    irdp->flags |= IF_SHUTDOWN;
    irdp->flags &= ~IF_ACTIVE;
  
--  if(! (irdp->flags & IF_BROADCAST)) 
++  if(! (irdp->flags & IF_BROADCAST))
      if_drop_group(ifp);
--  
++
    /* Tell the hosts we are out of service */
    irdp_advert_off(ifp);
  }
@@@ -327,7 -327,7 +327,7 @@@ irdp_if_no_shutdown(struct interface *i
  
    irdp->flags &= ~IF_SHUTDOWN;
  
--  irdp_if_start(ifp, irdp->flags & IF_BROADCAST? FALSE : TRUE, FALSE); 
++  irdp_if_start(ifp, irdp->flags & IF_BROADCAST? FALSE : TRUE, FALSE);
  
  }
  
@@@ -344,30 -344,30 +344,30 @@@ void irdp_config_write (struct vty *vty
  
    if(irdp->flags & IF_ACTIVE || irdp->flags & IF_SHUTDOWN) {
  
--    if( irdp->flags & IF_SHUTDOWN) 
++    if( irdp->flags & IF_SHUTDOWN)
        vty_out (vty, " ip irdp shutdown %s",  VTY_NEWLINE);
  
--    if( irdp->flags & IF_BROADCAST) 
++    if( irdp->flags & IF_BROADCAST)
        vty_out (vty, " ip irdp broadcast%s",  VTY_NEWLINE);
--    else 
++    else
        vty_out (vty, " ip irdp multicast%s",  VTY_NEWLINE);
  
--    vty_out (vty, " ip irdp preference %ld%s",  
++    vty_out (vty, " ip irdp preference %ld%s",
             irdp->Preference, VTY_NEWLINE);
  
      for (ALL_LIST_ELEMENTS_RO (irdp->AdvPrefList, node, adv))
        vty_out (vty, " ip irdp address %s preference %d%s",
                      inet_2a(adv->ip.s_addr, b1),
--                    adv->pref, 
++                    adv->pref,
                      VTY_NEWLINE);
  
--    vty_out (vty, " ip irdp holdtime %d%s",  
++    vty_out (vty, " ip irdp holdtime %d%s",
             irdp->Lifetime, VTY_NEWLINE);
  
--    vty_out (vty, " ip irdp minadvertinterval %ld%s",  
++    vty_out (vty, " ip irdp minadvertinterval %ld%s",
             irdp->MinAdvertInterval, VTY_NEWLINE);
  
--    vty_out (vty, " ip irdp maxadvertinterval %ld%s",  
++    vty_out (vty, " ip irdp maxadvertinterval %ld%s",
             irdp->MaxAdvertInterval, VTY_NEWLINE);
  
    }
@@@ -469,14 -444,9 +444,10 @@@ DEFUN (ip_irdp_holdtime
         "Set holdtime value\n"
         "Holdtime value in seconds. Default is 1800 seconds\n")
  {
-   struct interface *ifp;
 +  int idx_number = 3;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct zebra_if *zi;
    struct irdp_interface *irdp;
-   ifp = (struct interface *) vty->index;
-   if(!ifp) {
-         return CMD_WARNING;
-   }
  
    zi=ifp->info;
    irdp=&zi->irdp;
@@@ -493,14 -463,9 +464,10 @@@ DEFUN (ip_irdp_minadvertinterval
         "Set minimum time between advertisement\n"
         "Minimum advertisement interval in seconds\n")
  {
-   struct interface *ifp;
 +  int idx_number = 3;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct zebra_if *zi;
    struct irdp_interface *irdp;
-   ifp = (struct interface *) vty->index;
-   if(!ifp) {
-         return CMD_WARNING;
-   }
  
    zi=ifp->info;
    irdp=&zi->irdp;
        return CMD_SUCCESS;
    }
  
--  vty_out (vty, "ICMP warning maxadvertinterval is greater or equal than minadvertinterval%s", 
++  vty_out (vty, "ICMP warning maxadvertinterval is greater or equal than minadvertinterval%s",
             VTY_NEWLINE);
  
--  vty_out (vty, "Please correct!%s", 
++  vty_out (vty, "Please correct!%s",
             VTY_NEWLINE);
    return CMD_WARNING;
  }
@@@ -527,14 -492,9 +494,10 @@@ DEFUN (ip_irdp_maxadvertinterval
         "Set maximum time between advertisement\n"
         "Maximum advertisement interval in seconds\n")
  {
-   struct interface *ifp;
 +  int idx_number = 3;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct zebra_if *zi;
    struct irdp_interface *irdp;
-   ifp = (struct interface *) vty->index;
-   if(!ifp) {
-         return CMD_WARNING;
-   }
  
    zi=ifp->info;
    irdp=&zi->irdp;
        return CMD_SUCCESS;
    }
  
--  vty_out (vty, "ICMP warning maxadvertinterval is greater or equal than minadvertinterval%s", 
++  vty_out (vty, "ICMP warning maxadvertinterval is greater or equal than minadvertinterval%s",
             VTY_NEWLINE);
  
--  vty_out (vty, "Please correct!%s", 
++  vty_out (vty, "Please correct!%s",
             VTY_NEWLINE);
    return CMD_WARNING;
  }
@@@ -567,14 -527,9 +530,10 @@@ DEFUN (ip_irdp_preference
         "Set default preference level for this interface\n"
         "Preference level\n")
  {
-   struct interface *ifp;
 +  int idx_number = 3;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct zebra_if *zi;
    struct irdp_interface *irdp;
-   ifp = (struct interface *) vty->index;
-   if(!ifp) {
-         return CMD_WARNING;
-   }
  
    zi=ifp->info;
    irdp=&zi->irdp;
@@@ -592,13 -547,11 +551,13 @@@ DEFUN (ip_irdp_address_preference
         "Set IRDP address for advertise\n"
         "Preference level\n")
  {
 +  int idx_ipv4 = 3;
 +  int idx_number = 5;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct listnode *node;
--  struct in_addr ip; 
++  struct in_addr ip;
    int pref;
    int ret;
-   struct interface *ifp;
    struct zebra_if *zi;
    struct irdp_interface *irdp;
    struct Adv *adv;
    zi=ifp->info;
    irdp=&zi->irdp;
  
 -  ret = inet_aton(argv[0], &ip);
 +  ret = inet_aton(argv[idx_ipv4]->arg, &ip);
    if(!ret) return CMD_WARNING;
  
 -  pref = atoi(argv[1]);
 +  pref = atoi(argv[idx_number]->arg);
  
    for (ALL_LIST_ELEMENTS_RO (irdp->AdvPrefList, node, adv))
--    if(adv->ip.s_addr == ip.s_addr) 
++    if(adv->ip.s_addr == ip.s_addr)
        return CMD_SUCCESS;
  
    adv = Adv_new();
@@@ -639,11 -587,10 +593,11 @@@ DEFUN (no_ip_irdp_address_preference
         "Select IRDP address\n"
         "Old preference level\n")
  {
 +  int idx_ipv4 = 4;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct listnode *node, *nnode;
--  struct in_addr ip; 
++  struct in_addr ip;
    int ret;
-   struct interface *ifp;
    struct zebra_if *zi;
    struct irdp_interface *irdp;
    struct Adv *adv;
    zi=ifp->info;
    irdp=&zi->irdp;
  
 -  ret = inet_aton(argv[0], &ip);
 -  if (!ret) 
 +  ret = inet_aton(argv[idx_ipv4]->arg, &ip);
-   if (!ret) 
++  if (!ret)
      return CMD_WARNING;
  
    for (ALL_LIST_ELEMENTS (irdp->AdvPrefList, node, nnode, adv))
            break;
          }
      }
--  
++
    return CMD_SUCCESS;
  }
  
index a5f62dfa03115b75d8eb4ce9154a3e36a39764fa,19f453b150b6229ab65be86feb275da56454863b..afcd5f02357fc90dabd5e77192e1abb4c4891af8
@@@ -16,7 -16,7 +16,7 @@@
   * You should have received a copy of the GNU General Public License
   * along with GNU Zebra; see the file COPYING.  If not, write to the Free
   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-- * 02111-1307, USA.  
++ * 02111-1307, USA.
   */
  
  #include <zebra.h>
@@@ -40,7 -40,7 +40,8 @@@
  #include "privs.h"
  #include "nexthop.h"
  #include "vrf.h"
 +#include "vty.h"
+ #include "mpls.h"
  
  #include "zebra/zserv.h"
  #include "zebra/zebra_ns.h"
@@@ -94,7 -142,7 +143,7 @@@ set_ifindex(struct interface *ifp, ifin
                       ifi_index, oifp->name, ifp->name);
          if (if_is_up(oifp))
            zlog_err("interface rename detected on up interface: index %d "
--                   "was renamed from %s to %s, results are uncertain!", 
++                   "was renamed from %s to %s, results are uncertain!",
                     ifi_index, oifp->name, ifp->name);
          if_delete_update(oifp);
          }
@@@ -243,7 -291,7 +292,7 @@@ netlink_request (int family, int type, 
    req.nlh.nlmsg_seq = ++nl->seq;
    req.g.rtgen_family = family;
  
--  /* linux appears to check capabilities on every message 
++  /* linux appears to check capabilities on every message
     * have to raise caps for every message sent
     */
    if (zserv_privs.change (ZPRIVS_RAISE))
@@@ -707,7 -755,7 +756,7 @@@ netlink_interface (struct sockaddr_nl *
    /* Looking up interface name. */
    memset (tb, 0, sizeof tb);
    netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
--  
++
  #ifdef IFLA_WIRELESS
    /* check for wireless messages to ignore */
    if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
@@@ -834,7 -882,7 +883,7 @@@ netlink_interface_addr (struct sockaddr
                               buf, BUFSIZ), ifa->ifa_prefixlen);
        if (tb[IFA_LABEL] && strcmp (ifp->name, RTA_DATA (tb[IFA_LABEL])))
          zlog_debug ("  IFA_LABEL     %s", (char *)RTA_DATA (tb[IFA_LABEL]));
--      
++
        if (tb[IFA_CACHEINFO])
          {
            struct ifa_cacheinfo *ci = RTA_DATA (tb[IFA_CACHEINFO]);
                        ci->ifa_prefered, ci->ifa_valid);
          }
      }
--  
++
    /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */
    if (tb[IFA_LOCAL] == NULL)
      tb[IFA_LOCAL] = tb[IFA_ADDRESS];
    if (tb[IFA_ADDRESS] == NULL)
      tb[IFA_ADDRESS] = tb[IFA_LOCAL];
--  
++
    /* local interface address */
    addr = (tb[IFA_LOCAL] ? RTA_DATA(tb[IFA_LOCAL]) : NULL);
  
@@@ -1124,7 -1177,7 +1178,7 @@@ netlink_route_change (struct sockaddr_n
    struct rtattr *tb[RTA_MAX + 1];
    u_char zebra_flags = 0;
    struct prefix p;
--  
++
    char anyaddr[16] = { 0 };
  
    int index;
@@@ -1400,7 -1458,7 +1459,7 @@@ netlink_link_change (struct sockaddr_n
        return 0;
      }
  #endif /* IFLA_WIRELESS */
--  
++
    if (tb[IFLA_IFNAME] == NULL)
      return -1;
    name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
@@@ -1638,7 -1696,7 +1697,7 @@@ netlink_route_read (struct zebra_ns *zn
    return 0;
  }
  
--/* Utility function  comes from iproute2. 
++/* Utility function  comes from iproute2.
     Authors:   Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
  int
  addattr_l (struct nlmsghdr *n, unsigned int maxlen, int type, void *data, int alen)
@@@ -1680,7 -1739,7 +1740,7 @@@ rta_addattr_l (struct rtattr *rta, unsi
    return 0;
  }
  
--/* Utility function comes from iproute2. 
++/* Utility function comes from iproute2.
     Authors:   Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
  int
  addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data)
@@@ -1765,8 -1843,8 +1844,8 @@@ netlink_talk (struct nlmsghdr *n, struc
      }
  
  
--  /* 
--   * Get reply from netlink socket. 
++  /*
++   * Get reply from netlink socket.
     * The reply should either be an acknowlegement or an error.
     */
    return netlink_parse_info (netlink_talk_filter, nl, zns, 0);
@@@ -1820,6 -1955,59 +1956,59 @@@ _netlink_route_build_singlepath
        return;
      }
  
 - 
+   label_buf[0] = '\0';
+   /* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP
+    * (in the case of LER)
+    */
+   nh_label = nexthop->nh_label;
+   if (rtmsg->rtm_family == AF_MPLS)
+     {
+       assert (nh_label);
+       assert (nh_label->num_labels == 1);
+     }
+   if (nh_label && nh_label->num_labels)
+     {
+       int i, num_labels = 0;
+       u_int32_t bos;
+       char label_buf1[20];
++
+       for (i = 0; i < nh_label->num_labels; i++)
+         {
+           if (nh_label->label[i] != MPLS_IMP_NULL_LABEL)
+             {
+               bos = ((i == (nh_label->num_labels - 1)) ? 1 : 0);
+               out_lse[i] = mpls_lse_encode (nh_label->label[i], 0, 0, bos);
+               if (!num_labels)
+                 sprintf (label_buf, "label %d", nh_label->label[i]);
+               else
+                 {
+                   sprintf (label_buf1, "/%d", nh_label->label[i]);
+                   strcat (label_buf, label_buf1);
+                 }
+               num_labels++;
+             }
+         }
+       if (num_labels)
+         {
+           if (rtmsg->rtm_family == AF_MPLS)
+             addattr_l (nlmsg, req_size, RTA_NEWDST,
+                        &out_lse, num_labels * sizeof(mpls_lse_t));
+           else
+             {
+               struct rtattr *nest;
+               u_int16_t encap = LWTUNNEL_ENCAP_MPLS;
+               addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE,
+                         &encap, sizeof (u_int16_t));
+               nest = addattr_nest(nlmsg, req_size, RTA_ENCAP);
+               addattr_l (nlmsg, req_size, MPLS_IPTUNNEL_DST,
+                          &out_lse, num_labels * sizeof(mpls_lse_t));
+               addattr_nest_end(nlmsg, nest);
+             }
+         }
+     }
    if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
      rtmsg->rtm_flags |= RTNH_F_ONLINK;
  
@@@ -2063,9 -2347,20 +2348,20 @@@ _netlink_route_debug
        zlog_debug ("netlink_route_multipath() (%s): %s %s vrf %u type %s",
                  routedesc,
                  lookup (nlmsg_str, cmd),
-                 prefix2str (p, buf, sizeof(buf)),
-                 zvrf->vrf_id, nexthop_type_to_str (nexthop->type));
+                 prefix2str (p, buf, sizeof(buf)), zvrf->vrf_id,
+                 (nexthop) ? nexthop_type_to_str (nexthop->type) : "UNK");
      }
 -}
++    }
+ static void
+ _netlink_mpls_debug(
+         int cmd,
+         u_int32_t label,
+         const char *routedesc)
+ {
+   if (IS_ZEBRA_DEBUG_KERNEL)
+     zlog_debug ("netlink_mpls_multipath() (%s): %s %u/20",
+                 routedesc, lookup (nlmsg_str, cmd), label);
  }
  
  static int
diff --cc zebra/rtadv.c
index 7edba559537122d2e80f1a4e9529e093dc5a28b8,3e0a19870226079d6381e336abbe17b8a96e9381..dcf31ff4502b52bdc63b57f7f9aece4edbe82a6c
@@@ -924,9 -917,8 +918,9 @@@ DEFUN (ipv6_nd_ra_interval_msec
         "Router Advertisement interval\n"
         "Router Advertisement interval in milliseconds\n")
  {
 +  int idx_number = 4;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    unsigned interval;
-   struct interface *ifp = (struct interface *) vty->index;
    struct zebra_if *zif = ifp->info;
    struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
    struct zebra_ns *zns;
@@@ -960,9 -952,8 +954,9 @@@ DEFUN (ipv6_nd_ra_interval
         "Router Advertisement interval\n"
         "Router Advertisement interval in seconds\n")
  {
 +  int idx_number = 3;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    unsigned interval;
-   struct interface *ifp = (struct interface *) vty->index;
    struct zebra_if *zif = ifp->info;
    struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
    struct zebra_ns *zns;
@@@ -994,13 -985,10 +988,13 @@@ DEFUN (no_ipv6_nd_ra_interval
         NO_STR
         "Interface IPv6 config commands\n"
         "Neighbor discovery\n"
 -       "Router Advertisement interval\n")
 +       "Router Advertisement interval\n"
 +       "Router Advertisement interval in seconds\n"
 +       "Specify millisecond router advertisement interval\n"
 +       "Router Advertisement interval in milliseconds\n")
  {
-   struct interface *ifp;
-   struct zebra_if *zif;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
+   struct zebra_if *zif = ifp->info;
    struct zebra_vrf *zvrf;
    struct zebra_ns *zns;
  
@@@ -1027,15 -1030,11 +1019,12 @@@ DEFUN (ipv6_nd_ra_lifetime
         "Router lifetime\n"
         "Router lifetime in seconds (0 stands for a non-default gw)\n")
  {
 +  int idx_number = 3;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
+   struct zebra_if *zif = ifp->info;
    int lifetime;
-   struct interface *ifp;
-   struct zebra_if *zif;
-   ifp = (struct interface *) vty->index;
-   zif = ifp->info;
  
 -  VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000);
 +  VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[idx_number]->arg, 0, 9000);
  
    /* The value to be placed in the Router Lifetime field
     * of Router Advertisements sent from the interface,
@@@ -1058,14 -1057,10 +1047,11 @@@ DEFUN (no_ipv6_nd_ra_lifetime
         NO_STR
         "Interface IPv6 config commands\n"
         "Neighbor discovery\n"
 -       "Router lifetime\n")
 +       "Router lifetime\n"
 +       "Router lifetime in seconds (0 stands for a non-default gw)\n")
  {
-   struct interface *ifp;
-   struct zebra_if *zif;
-   ifp = (struct interface *) vty->index;
-   zif = ifp->info;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
+   struct zebra_if *zif = ifp->info;
  
    zif->rtadv.AdvDefaultLifetime = -1;
  
@@@ -1080,10 -1084,9 +1066,10 @@@ DEFUN (ipv6_nd_reachable_time
         "Reachable time\n"
         "Reachable time in milliseconds\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_number = 3;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct zebra_if *zif = ifp->info;
 -  VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[0], 1, RTADV_MAX_REACHABLE_TIME);
 +  VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[idx_number]->arg, 1, RTADV_MAX_REACHABLE_TIME);
    return CMD_SUCCESS;
  }
  
@@@ -1093,14 -1096,10 +1079,11 @@@ DEFUN (no_ipv6_nd_reachable_time
         NO_STR
         "Interface IPv6 config commands\n"
         "Neighbor discovery\n"
 -       "Reachable time\n")
 +       "Reachable time\n"
 +       "Reachable time in milliseconds\n")
  {
-   struct interface *ifp;
-   struct zebra_if *zif;
-   ifp = (struct interface *) vty->index;
-   zif = ifp->info;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
+   struct zebra_if *zif = ifp->info;
  
    zif->rtadv.AdvReachableTime = 0;
  
@@@ -1115,10 -1123,9 +1098,10 @@@ DEFUN (ipv6_nd_homeagent_preference
         "Home Agent preference\n"
         "preference value (default is 0, least preferred)\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_number = 3;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct zebra_if *zif = ifp->info;
 -  VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[0], 0, 65535);
 +  VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[idx_number]->arg, 0, 65535);
    return CMD_SUCCESS;
  }
  
@@@ -1128,14 -1135,10 +1111,11 @@@ DEFUN (no_ipv6_nd_homeagent_preference
         NO_STR
         "Interface IPv6 config commands\n"
         "Neighbor discovery\n"
 -       "Home Agent preference\n")
 +       "Home Agent preference\n"
 +       "preference value (default is 0, least preferred)\n")
  {
-   struct interface *ifp;
-   struct zebra_if *zif;
-   ifp = (struct interface *) vty->index;
-   zif = ifp->info;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
+   struct zebra_if *zif = ifp->info;
  
    zif->rtadv.HomeAgentPreference = 0;
  
@@@ -1150,10 -1162,9 +1130,10 @@@ DEFUN (ipv6_nd_homeagent_lifetime
         "Home Agent lifetime\n"
         "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_number = 3;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct zebra_if *zif = ifp->info;
 -  VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[0], 0, RTADV_MAX_HALIFETIME);
 +  VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[idx_number]->arg, 0, RTADV_MAX_HALIFETIME);
    return CMD_SUCCESS;
  }
  
@@@ -1163,14 -1174,10 +1143,11 @@@ DEFUN (no_ipv6_nd_homeagent_lifetime
         NO_STR
         "Interface IPv6 config commands\n"
         "Neighbor discovery\n"
 -       "Home Agent lifetime\n")
 +       "Home Agent lifetime\n"
 +       "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
  {
-   struct interface *ifp;
-   struct zebra_if *zif;
-   ifp = (struct interface *) vty->index;
-   zif = ifp->info;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
+   struct zebra_if *zif = ifp->info;
  
    zif->rtadv.HomeAgentLifetime = -1;
  
@@@ -1336,46 -1329,18 +1289,43 @@@ DEFUN (ipv6_nd_prefix
         "Infinite valid lifetime\n"
         "Preferred lifetime in seconds\n"
         "Infinite preferred lifetime\n"
 +       "Set Router Address flag\n"
         "Do not use prefix for onlink determination\n"
         "Do not use prefix for autoconfiguration\n"
 -       "Set Router Address flag\n")
 +       "Do not use prefix for autoconfiguration\n"
 +       "Do not use prefix for onlink determination\n")
  {
 -  int i;
 +  /* prelude */
 +  char *prefix = argv[3]->arg;
 +  int lifetimes = (argc > 4) && (argv[4]->type == RANGE_TKN || strmatch (argv[4]->text, "infinite"));
 +  int routeropts = lifetimes ? argc > 6 : argc > 4;
 +
 +  int idx_routeropts = routeropts ? (lifetimes ? 6 : 4) : 0;
 +
 +  char *lifetime = NULL, *preflifetime = NULL;
 +  int routeraddr = 0, offlink = 0, noautoconf = 0;
 +  if (lifetimes)
 +  {
 +    lifetime     = argv[4]->type == RANGE_TKN ? argv[4]->arg : argv[4]->text;
 +    preflifetime = argv[5]->type == RANGE_TKN ? argv[5]->arg : argv[5]->text;
 +  }
 +  if (routeropts)
 +  {
 +    routeraddr = strmatch (argv[idx_routeropts]->text, "router-address");
 +    if (!routeraddr)
 +    {
 +      offlink    = (argc > idx_routeropts + 1 || strmatch (argv[idx_routeropts]->text, "off-link"));
 +      noautoconf = (argc > idx_routeropts + 1 || strmatch (argv[idx_routeropts]->text, "no-autoconfig"));
 +    }
 +  }
 +
 +  /* business */
+   VTY_DECLVAR_CONTEXT (interface, ifp);
+   struct zebra_if *zebra_if = ifp->info;
    int ret;
-   struct interface *ifp;
-   struct zebra_if *zebra_if;
 -  int cursor = 1;
    struct rtadv_prefix rp;
  
-   ifp = (struct interface *) vty->index;
-   zebra_if = ifp->info;
 -  ret = str2prefix_ipv6 (argv[0], &rp.prefix);
 +  ret = str2prefix_ipv6 (prefix, &rp.prefix);
    if (!ret)
      {
        vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
@@@ -1416,23 -1408,165 +1366,19 @@@ DEFUN (no_ipv6_nd_prefix
         "Infinite valid lifetime\n"
         "Preferred lifetime in seconds\n"
         "Infinite preferred lifetime\n"
 +       "Set Router Address flag\n"
         "Do not use prefix for onlink determination\n"
 -       "Do not use prefix for autoconfiguration\n")
 -
 -ALIAS (ipv6_nd_prefix,
 -       ipv6_nd_prefix_val_rev_cmd,
 -       "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
 -       "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n"
 -       "Valid lifetime in seconds\n"
 -       "Infinite valid lifetime\n"
 -       "Preferred lifetime in seconds\n"
 -       "Infinite preferred lifetime\n"
         "Do not use prefix for autoconfiguration\n"
 -       "Do not use prefix for onlink determination\n")
 -
 -ALIAS (ipv6_nd_prefix,
 -       ipv6_nd_prefix_val_rev_rtaddr_cmd,
 -       "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
 -       "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n"
 -       "Valid lifetime in seconds\n"
 -       "Infinite valid lifetime\n"
 -       "Preferred lifetime in seconds\n"
 -       "Infinite preferred lifetime\n"
         "Do not use prefix for autoconfiguration\n"
 -       "Do not use prefix for onlink determination\n"
 -       "Set Router Address flag\n")
 -
 -ALIAS (ipv6_nd_prefix,
 -       ipv6_nd_prefix_val_noauto_cmd,
 -       "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
 -       "(<0-4294967295>|infinite) (no-autoconfig|)",
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n"
 -       "Valid lifetime in seconds\n"
 -       "Infinite valid lifetime\n"
 -       "Preferred lifetime in seconds\n"
 -       "Infinite preferred lifetime\n"
 -       "Do not use prefix for autoconfiguration")
 -
 -ALIAS (ipv6_nd_prefix,
 -       ipv6_nd_prefix_val_offlink_cmd,
 -       "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
 -       "(<0-4294967295>|infinite) (off-link|)",
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n"
 -       "Valid lifetime in seconds\n"
 -       "Infinite valid lifetime\n"
 -       "Preferred lifetime in seconds\n"
 -       "Infinite preferred lifetime\n"
         "Do not use prefix for onlink determination\n")
 -
 -ALIAS (ipv6_nd_prefix,
 -       ipv6_nd_prefix_val_rtaddr_cmd,
 -       "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
 -       "(<0-4294967295>|infinite) (router-address|)",
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n"
 -       "Valid lifetime in seconds\n"
 -       "Infinite valid lifetime\n"
 -       "Preferred lifetime in seconds\n"
 -       "Infinite preferred lifetime\n"
 -       "Set Router Address flag\n")
 -
 -ALIAS (ipv6_nd_prefix,
 -       ipv6_nd_prefix_val_cmd,
 -       "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
 -       "(<0-4294967295>|infinite)",
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n"
 -       "Valid lifetime in seconds\n"
 -       "Infinite valid lifetime\n"
 -       "Preferred lifetime in seconds\n"
 -       "Infinite preferred lifetime\n")
 -
 -ALIAS (ipv6_nd_prefix,
 -       ipv6_nd_prefix_noval_cmd,
 -       "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n"
 -       "Do not use prefix for autoconfiguration\n"
 -       "Do not use prefix for onlink determination\n")
 -
 -ALIAS (ipv6_nd_prefix,
 -       ipv6_nd_prefix_noval_rev_cmd,
 -       "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n"
 -       "Do not use prefix for onlink determination\n"
 -       "Do not use prefix for autoconfiguration\n")
 -
 -ALIAS (ipv6_nd_prefix,
 -       ipv6_nd_prefix_noval_noauto_cmd,
 -       "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n"
 -       "Do not use prefix for autoconfiguration\n")
 -
 -ALIAS (ipv6_nd_prefix,
 -       ipv6_nd_prefix_noval_offlink_cmd,
 -       "ipv6 nd prefix X:X::X:X/M (off-link|)",
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n"
 -       "Do not use prefix for onlink determination\n")
 -
 -ALIAS (ipv6_nd_prefix,
 -       ipv6_nd_prefix_noval_rtaddr_cmd,
 -       "ipv6 nd prefix X:X::X:X/M (router-address|)",
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n"
 -       "Set Router Address flag\n")
 -
 -ALIAS (ipv6_nd_prefix,
 -       ipv6_nd_prefix_prefix_cmd,
 -       "ipv6 nd prefix X:X::X:X/M",
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n")
 -
 -DEFUN (no_ipv6_nd_prefix,
 -       no_ipv6_nd_prefix_cmd,
 -       "no ipv6 nd prefix IPV6PREFIX",
 -       NO_STR
 -       "Interface IPv6 config commands\n"
 -       "Neighbor discovery\n"
 -       "Prefix information\n"
 -       "IPv6 prefix\n")
  {
+   VTY_DECLVAR_CONTEXT (interface, ifp);
+   struct zebra_if *zebra_if = ifp->info;
    int ret;
-   struct interface *ifp;
-   struct zebra_if *zebra_if;
    struct rtadv_prefix rp;
 +  char *prefix = argv[4]->arg;
  
-   ifp = (struct interface *) vty->index;
-   zebra_if = ifp->info;
 -  ret = str2prefix_ipv6 (argv[0], &rp.prefix);
 +  ret = str2prefix_ipv6 (prefix, &rp.prefix);
    if (!ret)
      {
        vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
@@@ -1460,17 -1748,13 +1406,14 @@@ DEFUN (ipv6_nd_router_preference
         "Low default router preference\n"
         "Medium default router preference (default)\n")
  {
-   struct interface *ifp;
-   struct zebra_if *zif;
 +  int idx_high_medium_low = 3;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
+   struct zebra_if *zif = ifp->info;
    int i = 0;
  
-   ifp = (struct interface *) vty->index;
-   zif = ifp->info;
    while (0 != rtadv_pref_strs[i])
      {
 -      if (strncmp (argv[0], rtadv_pref_strs[i], 1) == 0)
 +      if (strncmp (argv[idx_high_medium_low]->arg, rtadv_pref_strs[i], 1) == 0)
        {
          zif->rtadv.DefaultPreference = i;
          return CMD_SUCCESS;
@@@ -1487,16 -1771,10 +1430,13 @@@ DEFUN (no_ipv6_nd_router_preference
         NO_STR
         "Interface IPv6 config commands\n"
         "Neighbor discovery\n"
 -       "Default router preference\n")
 +       "Default router preference\n"
 +       "High default router preference\n"
 +       "Medium default router preference (default)\n"
 +       "Low default router preference\n")
  {
-   struct interface *ifp;
-   struct zebra_if *zif;
-   ifp = (struct interface *) vty->index;
-   zif = ifp->info;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
+   struct zebra_if *zif = ifp->info;
  
    zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */
  
@@@ -1511,10 -1800,9 +1451,10 @@@ DEFUN (ipv6_nd_mtu
         "Advertised MTU\n"
         "MTU in bytes\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
 +  int idx_number = 3;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct zebra_if *zif = ifp->info;
 -  VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[0], 1, 65535);
 +  VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[idx_number]->arg, 1, 65535);
    return CMD_SUCCESS;
  }
  
@@@ -1524,10 -1812,9 +1464,10 @@@ DEFUN (no_ipv6_nd_mtu
         NO_STR
         "Interface IPv6 config commands\n"
         "Neighbor discovery\n"
 -       "Advertised MTU\n")
 +       "Advertised MTU\n"
 +       "MTU in bytes\n")
  {
-   struct interface *ifp = (struct interface *) vty->index;
+   VTY_DECLVAR_CONTEXT (interface, ifp);
    struct zebra_if *zif = ifp->info;
    zif->rtadv.AdvLinkMTU = 0;
    return CMD_SUCCESS;
index d3813d73560d59fccc58f54076e00ca4fa5b5eb3,828b61af919a5a49a7f72029cdbcd0a1cbf349a9..28293285469135dd4c9e09ac2331a6a94c8067e3
@@@ -124,10 -124,10 +124,9 @@@ DEFUN (test_interface_state
         "up\n"
         "down\n")
  {
-   struct interface *ifp;
 +  int idx_up_down = 1;
 -  if (argc < 1)
 -    return CMD_WARNING;
 -
+   VTY_DECLVAR_CONTEXT (interface, ifp);
-   ifp = vty->index;
 +  
    if (ifp->ifindex == IFINDEX_INTERNAL)
      {
        ifp->ifindex = ++test_ifindex;
index 220fddaf67983c99b33e1496e92cb07a0870f3a9,a5a953c51fda0ce204a6e18f760ccbd39a351c36..b2026c1e0c34fb0c954817cd810e5dbdfc44f18a
@@@ -1520,6 -1561,134 +1561,134 @@@ DEFUN (clear_zebra_fpm_stats
    return CMD_SUCCESS;
  }
  
 -DEFUN ( fpm_remote_ip, 
 -        fpm_remote_ip_cmd,
 -        "fpm connection ip A.B.C.D port <1-65535>",
+ /*
+  * update fpm connection information 
+  */
 -   fpm_server = inet_addr (argv[0]);
++DEFUN ( fpm_remote_ip,
++       fpm_remote_ip_cmd,
++        "fpm connection ip A.B.C.D port (1-65535)",
+         "fpm connection remote ip and port\n"
+         "Remote fpm server ip A.B.C.D\n"
+         "Enter ip ")
+ {
+    in_addr_t fpm_server;
+    uint32_t port_no;
 -   port_no = atoi (argv[1]);
++   fpm_server = inet_addr (argv[3]->arg);
+    if (fpm_server == INADDR_NONE)
+      return CMD_ERR_INCOMPLETE;
 -DEFUN ( no_fpm_remote_ip, 
 -        no_fpm_remote_ip_cmd,
 -        "no fpm connection ip A.B.C.D port <1-65535>",
++   port_no = atoi (argv[5]->arg);
+    if (port_no < TCP_MIN_PORT || port_no > TCP_MAX_PORT)
+      return CMD_ERR_INCOMPLETE;
+    zfpm_g->fpm_server = fpm_server;
+    zfpm_g->fpm_port = port_no;
+    return CMD_SUCCESS;
+ }
 -   if (zfpm_g->fpm_server != inet_addr (argv[0]) || 
 -              zfpm_g->fpm_port !=  atoi (argv[1]))
++DEFUN ( no_fpm_remote_ip,
++       no_fpm_remote_ip_cmd,
++        "no fpm connection ip A.B.C.D port (1-65535)",
+         "fpm connection remote ip and port\n"
+         "Connection\n"
+         "Remote fpm server ip A.B.C.D\n"
+         "Enter ip ")
+ {
++   if (zfpm_g->fpm_server != inet_addr (argv[4]->arg) || 
++              zfpm_g->fpm_port !=  atoi (argv[6]->arg))
+        return CMD_ERR_NO_MATCH;
+    zfpm_g->fpm_server = FPM_DEFAULT_IP;
+    zfpm_g->fpm_port = FPM_DEFAULT_PORT;
+    return CMD_SUCCESS;
+ }
+ /*
+  * zfpm_init_message_format
+  */
+ static inline void
+ zfpm_init_message_format (const char *format)
+ {
+   int have_netlink, have_protobuf;
+   have_netlink = have_protobuf = 0;
+ #ifdef HAVE_NETLINK
+   have_netlink = 1;
+ #endif
+ #ifdef HAVE_PROTOBUF
+   have_protobuf = 1;
+ #endif
+   zfpm_g->message_format = ZFPM_MSG_FORMAT_NONE;
+   if (!format)
+     {
+       if (have_netlink)
+       {
+         zfpm_g->message_format = ZFPM_MSG_FORMAT_NETLINK;
+       }
+       else if (have_protobuf)
+       {
+         zfpm_g->message_format = ZFPM_MSG_FORMAT_PROTOBUF;
+       }
+       return;
+     }
+   if (!strcmp ("netlink", format))
+     {
+       if (!have_netlink)
+       {
+         zlog_err ("FPM netlink message format is not available");
+         return;
+       }
+       zfpm_g->message_format = ZFPM_MSG_FORMAT_NETLINK;
+       return;
+     }
+   if (!strcmp ("protobuf", format))
+     {
+       if (!have_protobuf)
+       {
+         zlog_err ("FPM protobuf message format is not available");
+         return;
+       }
+       zfpm_g->message_format = ZFPM_MSG_FORMAT_PROTOBUF;
+       return;
+     }
+   zlog_warn ("Unknown fpm format '%s'", format);
+ }
+ /**
+  * fpm_remote_srv_write 
+  *
+  * Module to write remote fpm connection 
+  *
+  * Returns ZERO on success.
+  */
+ int fpm_remote_srv_write (struct vty *vty )
+ {
+    struct in_addr in;
+    in.s_addr = zfpm_g->fpm_server;
+    if (zfpm_g->fpm_server != FPM_DEFAULT_IP || 
+           zfpm_g->fpm_port != FPM_DEFAULT_PORT)
+       vty_out (vty,"fpm connection ip %s port %d%s", inet_ntoa (in),zfpm_g->fpm_port,VTY_NEWLINE);
+    return 0;
+ }
  /**
   * zfpm_init
   *
index 0000000000000000000000000000000000000000,6136e92cdd220a941a876d1c76e645ab42b3f154..061bb244b2357c7e20f05e030642d22febe6e93c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,881 +1,878 @@@
 -       "mpls lsp <16-1048575> (A.B.C.D|X:X::X:X) (<16-1048575>|explicit-null|implicit-null)",
+ /* Zebra MPLS VTY functions
+  * Copyright (C) 2002 Kunihiro Ishiguro
+  *
+  * This file is part of GNU Zebra.
+  *
+  * GNU Zebra is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU General Public License as published by the
+  * Free Software Foundation; either version 2, or (at your option) any
+  * later version.
+  *
+  * GNU Zebra is distributed in the hope that it will be useful, but
+  * WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with GNU Zebra; see the file COPYING.  If not, write to the 
+  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
+  * Boston, MA 02111-1307, USA.  
+  */
+ #include <zebra.h>
+ #include "memory.h"
+ #include "if.h"
+ #include "prefix.h"
+ #include "command.h"
+ #include "table.h"
+ #include "rib.h"
+ #include "nexthop.h"
+ #include "vrf.h"
+ #include "mpls.h"
+ #include "lib/json.h"
+ #include "zebra/zserv.h"
+ #include "zebra/zebra_vrf.h"
+ #include "zebra/zebra_mpls.h"
+ #include "zebra/zebra_rnh.h"
+ #include "zebra/redistribute.h"
+ #include "zebra/zebra_routemap.h"
+ #include "zebra/zebra_static.h"
+ static int
+ zebra_mpls_transit_lsp (struct vty *vty, int add_cmd, const char *inlabel_str,
+                       const char *gate_str, const char *outlabel_str,
+                         const char *flag_str)
+ {
+   struct zebra_vrf *zvrf;
+   int ret;
+   enum nexthop_types_t gtype;
+   union g_addr gate;
+   mpls_label_t label;
+   mpls_label_t in_label, out_label;
+   zvrf = vrf_info_lookup(VRF_DEFAULT);
+   if (!zvrf)
+     {
+       vty_out (vty, "%% Default VRF does not exist%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   if (!inlabel_str)
+     {
+       vty_out (vty, "%% No Label Information%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   out_label = MPLS_IMP_NULL_LABEL; /* as initialization */
+   label = atoi(inlabel_str);
+   if (!IS_MPLS_UNRESERVED_LABEL(label))
+     {
+       vty_out (vty, "%% Invalid label%s", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   if (add_cmd)
+     {
+       if (!gate_str)
+         {
+           vty_out (vty, "%% No Nexthop Information%s", VTY_NEWLINE);
+           return CMD_WARNING;
+         }
+       if (!outlabel_str)
+         {
+           vty_out (vty, "%% No Outgoing label Information%s", VTY_NEWLINE);
+           return CMD_WARNING;
+         }
+     }
+   in_label = label;
+   gtype = NEXTHOP_TYPE_BLACKHOLE; /* as initialization */
+   if (gate_str)
+     {
+       /* Gateway is a IPv4 or IPv6 nexthop. */
+       ret = inet_pton (AF_INET6, gate_str, &gate.ipv6);
+       if (ret)
+         gtype = NEXTHOP_TYPE_IPV6;
+       else
+         {
+           ret = inet_pton (AF_INET, gate_str, &gate.ipv4);
+           if (ret)
+             gtype = NEXTHOP_TYPE_IPV4;
+           else
+             {
+               vty_out (vty, "%% Invalid nexthop%s", VTY_NEWLINE);
+               return CMD_WARNING;
+             }
+         }
+     }
+   if (outlabel_str)
+     {
+       if (outlabel_str[0] == 'i')
+         out_label = MPLS_IMP_NULL_LABEL;
+       else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV4)
+         out_label = MPLS_V4_EXP_NULL_LABEL;
+       else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV6)
+         out_label = MPLS_V6_EXP_NULL_LABEL;
+       else
+         out_label = atoi(outlabel_str);
+     }
+   if (add_cmd)
+     {
+ #if defined(HAVE_CUMULUS)
+       /* Check that label value is consistent. */
+       if (!zebra_mpls_lsp_label_consistent (zvrf, in_label, out_label, gtype,
+                                             &gate, NULL, 0))
+         {
+           vty_out (vty, "%% Label value not consistent%s",
+                    VTY_NEWLINE);
+           return CMD_WARNING;
+         }
+ #endif /* HAVE_CUMULUS */
+       ret = zebra_mpls_static_lsp_add (zvrf, in_label, out_label, gtype,
+                                        &gate, NULL, 0);
+     }
+   else
+     ret = zebra_mpls_static_lsp_del (zvrf, in_label, gtype, &gate, NULL, 0);
+   if (ret)
+     {
+       vty_out (vty, "%% LSP cannot be %s%s",
+                add_cmd ? "added" : "deleted", VTY_NEWLINE);
+       return CMD_WARNING;
+     }
+   return CMD_SUCCESS;
+ }
+ DEFUN (mpls_transit_lsp,
+        mpls_transit_lsp_cmd,
 -  return zebra_mpls_transit_lsp (vty, 1, argv[0], argv[1], argv[2], NULL);
++       "mpls lsp (16-1048575) <A.B.C.D|X:X::X:X> <(16-1048575)|explicit-null|implicit-null>",
+        MPLS_STR
+        "Establish label switched path\n"
+        "Incoming MPLS label\n"
+        "IPv4 gateway address\n"
+        "IPv6 gateway address\n"
+        "Outgoing MPLS label\n"
+        "Use Explicit-Null label\n"
+        "Use Implicit-Null label\n")
+ {
 -       "no mpls lsp <16-1048575> (A.B.C.D|X:X::X:X)",
++  return zebra_mpls_transit_lsp (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL);
+ }
+ DEFUN (no_mpls_transit_lsp,
+        no_mpls_transit_lsp_cmd,
 -  return zebra_mpls_transit_lsp (vty, 0, argv[0], argv[1], NULL, NULL);
++       "no mpls lsp (16-1048575) <A.B.C.D|X:X::X:X>",
+        NO_STR
+        MPLS_STR
+        "Establish label switched path\n"
+        "Incoming MPLS label\n"
+        "IPv4 gateway address\n"
+        "IPv6 gateway address\n")
+ {
 -       "no mpls lsp <16-1048575> (A.B.C.D|X:X::X:X) (<16-1048575>|explicit-null|implicit-null)",
++  return zebra_mpls_transit_lsp (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL);
+ }
+ ALIAS (no_mpls_transit_lsp,
+        no_mpls_transit_lsp_out_label_cmd,
 -       "no mpls lsp <16-1048575>",
++       "no mpls lsp (16-1048575) <A.B.C.D|X:X::X:X> <(16-1048575)|explicit-null|implicit-null>",
+        NO_STR
+        MPLS_STR
+        "Establish label switched path\n"
+        "Incoming MPLS label\n"
+        "IPv4 gateway address\n"
+        "IPv6 gateway address\n"
+        "Outgoing MPLS label\n"
+        "Use Explicit-Null label\n"
+        "Use Implicit-Null label\n")
+  
+ DEFUN (no_mpls_transit_lsp_all,
+        no_mpls_transit_lsp_all_cmd,
 -  return zebra_mpls_transit_lsp (vty, 0, argv[0], NULL, NULL, NULL);
++       "no mpls lsp (16-1048575)",
+        NO_STR
+        MPLS_STR
+        "Establish label switched path\n"
+        "Incoming MPLS label\n")
+ {
 -       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) label WORD",
++  return zebra_mpls_transit_lsp (vty, 0, argv[3]->arg, NULL, NULL, NULL);
+ }
+ /* Static route configuration.  */
+ DEFUN (ip_route_label,
+        ip_route_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL,
 -                            NULL, NULL, argv[2]);
++       "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL,
++                            NULL, NULL, argv[5]->arg);
+ }
+ DEFUN (ip_route_tag_label,
+        ip_route_tag_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2],
 -                            NULL, NULL, argv[3]);
++       "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> tag (1-4294967295) label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg,
++                            NULL, NULL, argv[7]->arg);
+ }
+ /* Mask as A.B.C.D format.  */
+ DEFUN (ip_route_mask_label,
+        ip_route_mask_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL,
 -                            NULL, NULL, argv[3]);
++       "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL,
++                            NULL, NULL, argv[6]->arg);
+ }
+ DEFUN (ip_route_mask_tag_label,
+        ip_route_mask_tag_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3],
 -                            NULL, NULL, argv[4]);
++       "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> tag (1-4294967295) label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg,
++                            NULL, NULL, argv[8]->arg);
+ }
+ /* Distance option value.  */
+ DEFUN (ip_route_distance_label,
+        ip_route_distance_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL,
 -                            argv[2], NULL, argv[3]);
++       "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> (1-255) label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL,
++                            argv[4]->arg, NULL, argv[6]->arg);
+ }
+ DEFUN (ip_route_tag_distance_label,
+        ip_route_tag_distance_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2],
 -                            argv[3], NULL, argv[4]);
++       "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> tag (1-4294967295) (1-255) label WORD",
+        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"
+        "Distance value for this route\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg,
++                            argv[6]->arg, NULL, argv[8]->arg);
+ }
+ DEFUN (ip_route_mask_distance_label,
+        ip_route_mask_distance_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL,
 -                            argv[3], NULL, argv[4]);
++       "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> (1-255) label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL,
++                            argv[5]->arg, NULL, argv[7]->arg);
+ }
+ DEFUN (ip_route_mask_tag_distance_label,
+        ip_route_mask_tag_distance_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3],
 -                            argv[4], NULL, argv[5]);
++       "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> tag (1-4294967295) (1-255) label WORD",
+        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"
+        "Distance value for this route\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg,
++                            argv[7]->arg, NULL, argv[9]->arg);
+ }
+ DEFUN (no_ip_route_label,
+        no_ip_route_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL,
 -                            NULL, NULL, argv[2]);
++       "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL,
++                            NULL, NULL, argv[6]->arg);
+ }
+ DEFUN (no_ip_route_tag_label,
+        no_ip_route_tag_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2],
 -                            NULL, NULL, argv[3]);
++       "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> tag (1-4294967295) label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg,
++                            NULL, NULL, argv[8]->arg);
+ }
+ DEFUN (no_ip_route_mask_label,
+        no_ip_route_mask_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL,
 -                            NULL, NULL, argv[3]);
++       "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL,
++                            NULL, NULL, argv[7]->arg);
+ }
+ DEFUN (no_ip_route_mask_tag_label,
+        no_ip_route_mask_tag_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3],
 -                            NULL, NULL, argv[4]);
++       "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> tag (1-4294967295) label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg,
++                            NULL, NULL, argv[9]->arg);
+ }
+ DEFUN (no_ip_route_distance_label,
+        no_ip_route_distance_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL,
 -                            argv[2], NULL, argv[3]);
++       "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> (1-255) label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL,
++                            argv[5]->arg, NULL, argv[7]->arg);
+ }
+ DEFUN (no_ip_route_tag_distance_label,
+        no_ip_route_tag_distance_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2],
 -                            argv[3], NULL, argv[4]);
++       "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> tag (1-4294967295) (1-255) label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg,
++                            argv[7]->arg, NULL, argv[9]->arg);
+ }
+ DEFUN (no_ip_route_mask_distance_label,
+        no_ip_route_mask_distance_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL,
 -                            argv[3], NULL, argv[5]);
++       "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> (1-255)",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL,
++                            argv[6]->arg, NULL, NULL);
+ }
+ DEFUN (no_ip_route_mask_tag_distance_label,
+        no_ip_route_mask_tag_distance_label_cmd,
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3],
 -                            argv[4], NULL, argv[5]);
++       "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> tag (1-4294967295) (1-255) label WORD",
+        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"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) label WORD",
++  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg,
++                            argv[8]->arg, NULL, argv[10]->arg);
+ }
+ DEFUN (ipv6_route_label,
+        ipv6_route_label_cmd,
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, NULL, NULL, argv[2]);
++       "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> label WORD",
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> label WORD",
++  return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, NULL, NULL, NULL, NULL, NULL, argv[5]->arg);
+ }
+ DEFUN (ipv6_route_tag_label,
+        ipv6_route_tag_label_cmd,
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], NULL, NULL, argv[3]);
++       "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> tag (1-4294967295) label WORD",
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL, NULL, argv[3]);
++  return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, NULL, NULL, argv[5]->arg, NULL, NULL, argv[7]->arg);
+ }
+ DEFUN (ipv6_route_ifname_label,
+        ipv6_route_ifname_label_cmd,
+        "ipv6 route X:X::X:X/M X:X::X:X INTERFACE label WORD",
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> label WORD",
++  return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, NULL, argv[6]->arg);
+ }
+ DEFUN (ipv6_route_ifname_tag_label,
+        ipv6_route_ifname_tag_label_cmd,
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL, NULL, argv[4]);
++       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag (1-4294967295) label WORD",
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> label WORD",
++  return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg);
+ }
+ DEFUN (ipv6_route_pref_label,
+        ipv6_route_pref_label_cmd,
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, argv[2], NULL, argv[3]);
++       "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> (1-255) label WORD",
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Distance value for this prefix\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255> label WORD",
++  return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, NULL, NULL, NULL, argv[4]->arg, NULL, argv[6]->arg);
+ }
+ DEFUN (ipv6_route_pref_tag_label,
+        ipv6_route_pref_tag_label_cmd,
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], argv[3], NULL, argv[4]);
++       "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> tag (1-4294967295) (1-255) label WORD",
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        "Distance value for this prefix\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> label WORD",
++  return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, NULL, NULL, argv[5]->arg, argv[6]->arg, NULL, argv[8]->arg);
+ }
+ DEFUN (ipv6_route_ifname_pref_label,
+        ipv6_route_ifname_pref_label_cmd,
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3], NULL, argv[4]);
++       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (1-255) label WORD",
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Distance value for this prefix\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255> label WORD",
++  return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg);
+ }
+ DEFUN (ipv6_route_ifname_pref_tag_label,
+        ipv6_route_ifname_pref_tag_label_cmd,
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], NULL, argv[5]);
++       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag (1-4294967295) (1-255) label WORD",
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        "Distance value for this prefix\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) label WORD",
++  return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg);
+ }
+ DEFUN (no_ipv6_route_label,
+        no_ipv6_route_label_cmd,
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, NULL, NULL, argv[2]);
++       "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> label WORD",
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> label WORD",
++  return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, NULL, NULL, argv[6]->arg);
+ }
+ DEFUN (no_ipv6_route_tag_label,
+        no_ipv6_route_tag_label_cmd,
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], NULL, NULL, argv[3]);
++       "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> tag (1-4294967295) label WORD",
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL, NULL, argv[3]);
++  return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg);
+ }
+ DEFUN (no_ipv6_route_ifname_label,
+        no_ipv6_route_ifname_label_cmd,
+        "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE label WORD",
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> label WORD",
++  return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL, NULL, NULL, argv[7]->arg);
+ }
+ DEFUN (no_ipv6_route_ifname_tag_label,
+        no_ipv6_route_ifname_tag_label_cmd,
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL, NULL, argv[4]);
++       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag (1-4294967295) label WORD",
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> label WORD",
++  return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, NULL, NULL, argv[9]->arg);
+ }
+ DEFUN (no_ipv6_route_pref_label,
+        no_ipv6_route_pref_label_cmd,
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, argv[2], NULL, argv[3]);
++       "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> (1-255) label WORD",
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Distance value for this prefix\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255> label WORD",
++  return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg);
+ }
+ DEFUN (no_ipv6_route_pref_tag_label,
+        no_ipv6_route_pref_tag_label_cmd,
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], argv[3], NULL, argv[4]);
++       "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> tag (1-4294967295) (1-255) label WORD",
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        "Distance value for this prefix\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> label WORD",
++  return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg);
+ }
+ DEFUN (no_ipv6_route_ifname_pref_label,
+        no_ipv6_route_ifname_pref_label_cmd,
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, argv[3], NULL, argv[4]);
++       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (1-255) label WORD",
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Distance value for this prefix\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255> label WORD",
++  return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL, argv[6]->arg, NULL, argv[8]->arg);
+ }
+ DEFUN (no_ipv6_route_ifname_pref_tag_label,
+        no_ipv6_route_ifname_pref_tag_label_cmd,
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], NULL, argv[5]);
++       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag (1-4294967295) (1-255) label WORD",
+        NO_STR
+        IP_STR
+        "Establish static routes\n"
+        "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+        "IPv6 gateway address\n"
+        "IPv6 gateway interface name\n"
+        "Set tag for this route\n"
+        "Tag value\n"
+        "Distance value for this prefix\n"
+        "Specify label(s) for this route\n"
+        "One or more labels separated by '/'\n")
+ {
 -       "show mpls table {json}",
++  return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, argv[8]->arg, NULL, argv[10]->arg);
+ }
+ /* MPLS LSP configuration write function. */
+ static int
+ zebra_mpls_config (struct vty *vty)
+ {
+   int write = 0;
+   struct zebra_vrf *zvrf;
+   zvrf = vrf_info_lookup(VRF_DEFAULT);
+   if (!zvrf)
+     return 0;
+   write += zebra_mpls_write_lsp_config(vty, zvrf);
+   return write;
+ }
+ DEFUN (show_mpls_table,
+        show_mpls_table_cmd,
 -  u_char use_json = (argv[0] != NULL);
++       "show mpls table [json]",
+        SHOW_STR
+        MPLS_STR
+        "MPLS table\n"
+        "JavaScript Object Notation\n")
+ {
+   struct zebra_vrf *zvrf;
 -       "show mpls table <16-1048575> {json}",
++  u_char use_json = (argv[3]->arg != NULL);
+   zvrf = vrf_info_lookup(VRF_DEFAULT);
+   zebra_mpls_print_lsp_table(vty, zvrf, use_json);
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_mpls_table_lsp,
+        show_mpls_table_lsp_cmd,
 -  u_char use_json = (argv[1] != NULL);
++       "show mpls table (16-1048575) [json]",
+        SHOW_STR
+        MPLS_STR
+        "MPLS table\n"
+        "LSP to display information about\n"
+        "JavaScript Object Notation\n")
+ {
+   u_int32_t label;
+   struct zebra_vrf *zvrf;
 -  label = atoi(argv[0]);
++  u_char use_json = (argv[4]->arg != NULL);
+   zvrf = vrf_info_lookup(VRF_DEFAULT);
 -  install_element (ENABLE_NODE, &show_mpls_status_cmd);
++  label = atoi(argv[3]->arg);
+   zebra_mpls_print_lsp (vty, zvrf, label, use_json);
+   return CMD_SUCCESS;
+ }
+ DEFUN (show_mpls_status,
+        show_mpls_status_cmd,
+        "show mpls status",
+        SHOW_STR
+        "MPLS information\n"
+        "MPLS status\n")
+ {
+   vty_out (vty, "MPLS support enabled: %s%s", (mpls_enabled) ? "yes" :
+          "no (mpls kernel extensions not detected)", VTY_NEWLINE);
+   return CMD_SUCCESS;
+ }
+ /* MPLS node for MPLS LSP. */
+ static struct cmd_node mpls_node = { MPLS_NODE,  "",  1 };
+ /* MPLS VTY.  */
+ void
+ zebra_mpls_vty_init (void)
+ {
+   install_element (VIEW_NODE, &show_mpls_status_cmd);
 -  install_element (ENABLE_NODE, &show_mpls_table_cmd);
+   if (! mpls_enabled)
+     return;
+   install_node (&mpls_node, zebra_mpls_config);
+   install_element (CONFIG_NODE, &ip_route_label_cmd);
+   install_element (CONFIG_NODE, &ip_route_tag_label_cmd);
+   install_element (CONFIG_NODE, &ip_route_mask_label_cmd);
+   install_element (CONFIG_NODE, &ip_route_mask_tag_label_cmd);
+   install_element (CONFIG_NODE, &no_ip_route_label_cmd);
+   install_element (CONFIG_NODE, &no_ip_route_tag_label_cmd);
+   install_element (CONFIG_NODE, &no_ip_route_mask_label_cmd);
+   install_element (CONFIG_NODE, &no_ip_route_mask_tag_label_cmd);
+   install_element (CONFIG_NODE, &ip_route_distance_label_cmd);
+   install_element (CONFIG_NODE, &ip_route_tag_distance_label_cmd);
+   install_element (CONFIG_NODE, &ip_route_mask_distance_label_cmd);
+   install_element (CONFIG_NODE, &ip_route_mask_tag_distance_label_cmd);
+   install_element (CONFIG_NODE, &no_ip_route_distance_label_cmd);
+   install_element (CONFIG_NODE, &no_ip_route_tag_distance_label_cmd);
+   install_element (CONFIG_NODE, &no_ip_route_mask_distance_label_cmd);
+   install_element (CONFIG_NODE, &no_ip_route_mask_tag_distance_label_cmd);
+   install_element (CONFIG_NODE, &ipv6_route_label_cmd);
+   install_element (CONFIG_NODE, &ipv6_route_ifname_label_cmd);
+   install_element (CONFIG_NODE, &no_ipv6_route_label_cmd);
+   install_element (CONFIG_NODE, &no_ipv6_route_ifname_label_cmd);
+   install_element (CONFIG_NODE, &ipv6_route_pref_label_cmd);
+   install_element (CONFIG_NODE, &ipv6_route_ifname_pref_label_cmd);
+   install_element (CONFIG_NODE, &no_ipv6_route_pref_label_cmd);
+   install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_label_cmd);
+   install_element (CONFIG_NODE, &ipv6_route_tag_label_cmd);
+   install_element (CONFIG_NODE, &ipv6_route_ifname_tag_label_cmd);
+   install_element (CONFIG_NODE, &ipv6_route_pref_tag_label_cmd);
+   install_element (CONFIG_NODE, &ipv6_route_ifname_pref_tag_label_cmd);
+   install_element (CONFIG_NODE, &no_ipv6_route_tag_label_cmd);
+   install_element (CONFIG_NODE, &no_ipv6_route_ifname_tag_label_cmd);
+   install_element (CONFIG_NODE, &no_ipv6_route_pref_tag_label_cmd);
+   install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_tag_label_cmd);
+   install_element (CONFIG_NODE, &mpls_transit_lsp_cmd);
+   install_element (CONFIG_NODE, &no_mpls_transit_lsp_cmd);
+   install_element (CONFIG_NODE, &no_mpls_transit_lsp_out_label_cmd);
+   install_element (CONFIG_NODE, &no_mpls_transit_lsp_all_cmd);
+   install_element (VIEW_NODE, &show_mpls_table_cmd);
 -  install_element (ENABLE_NODE, &show_mpls_table_lsp_cmd);
+   install_element (VIEW_NODE, &show_mpls_table_lsp_cmd);
+ }
index fddc4fd7b1554013161436188a4ca0978f07d76b,9cfae6e7055be31b36be1fe1228b7e5fe25aba2e..9b407ed3921d8a131f21929b1b5cd47b94156484
@@@ -57,11 -56,9 +57,11 @@@ struct nh_rmap_ob
  
  static void zebra_route_map_set_delay_timer(u_int32_t value);
  
 +
 +
  /* Add zebra route map rule */
  static int
- zebra_route_match_add(struct vty *vty, struct route_map_index *index,
+ zebra_route_match_add(struct vty *vty,
                      const char *command, const char *arg,
                      route_map_event_t type)
  {
@@@ -160,45 -207,13 +162,13 @@@ route_match_tag (void *rule, struct pre
    return RMAP_NOMATCH;
  }
  
- /* Route map 'match tag' match statement. 'arg' is TAG value */
- static void *
- route_match_tag_compile (const char *arg)
- {
-   u_short *tag;
-   u_short tmp;
-   /* tag value shoud be integer. */
-   if (! all_digit (arg))
-     return NULL;
-   tmp = atoi(arg);
-   if (tmp < 1)
-     return NULL;
-   tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
-   if (!tag)
-     return tag;
-   *tag = tmp;
-   return tag;
- }
- /* Free route map's compiled 'match tag' value. */
- static void
- route_match_tag_free (void *rule)
- {
-   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
- }
  /* Route map commands for tag matching */
- struct route_map_rule_cmd route_match_tag_cmd =
+ static struct route_map_rule_cmd route_match_tag_cmd =
  {
 -  "tag",
 -  route_match_tag,
 +   "tag",
 +   route_match_tag,
-    route_match_tag_compile,
-    route_match_tag_free
+   route_map_rule_tag_compile,
+   route_map_rule_tag_free,
  };
  
  
@@@ -260,8 -506,8 +230,8 @@@ DEFUN (match_ip_address_prefix_len
         "Match prefix length of ip address\n"
         "Prefix length\n")
  {
-   return zebra_route_match_add (vty, vty->index, "ip address prefix-len",
+   return zebra_route_match_add (vty, "ip address prefix-len",
 -                              argv[0], RMAP_EVENT_MATCH_ADDED);
 +                              argv[4]->arg, RMAP_EVENT_MATCH_ADDED);
  }
  
  DEFUN (no_match_ip_address_prefix_len,
         MATCH_STR
         IP_STR
         "Match prefixlen of ip address of route\n"
 -       "prefix length of ip address\n")
 +       "Prefix length\n")
  {
 -  if (argc == 0)
 -    return zebra_route_match_delete (vty,
 -                                   "ip address prefix-len", NULL,
 -                                   RMAP_EVENT_MATCH_DELETED);
 -
 +  char *plen = (argc == 6) ? argv[5]->arg : NULL;
-   return zebra_route_match_delete (vty, vty->index,
+   return zebra_route_match_delete (vty,
 -                                 "ip address prefix-len", argv[0],
 +                                 "ip address prefix-len", plen,
                                   RMAP_EVENT_MATCH_DELETED);
  }
  
@@@ -289,8 -547,8 +259,8 @@@ DEFUN (match_ip_nexthop_prefix_len
         "Match prefixlen of given nexthop\n"
         "Prefix length\n")
  {
-   return zebra_route_match_add (vty, vty->index, "ip next-hop prefix-len",
+   return zebra_route_match_add (vty, "ip next-hop prefix-len",
 -                              argv[0], RMAP_EVENT_MATCH_ADDED);
 +                              argv[4]->arg, RMAP_EVENT_MATCH_ADDED);
  }
  
  DEFUN (no_match_ip_nexthop_prefix_len,
         MATCH_STR
         IP_STR
         "Match prefixlen of nexthop ip address\n"
 -       "Match prefix length of nexthop\n")
 +       "Match prefix length of nexthop\n"
 +       "Prefix length\n")
  {
 -  if (argc == 0)
 -    return zebra_route_match_delete (vty,
 -                                   "ip next-hop prefix-len", NULL,
 -                                   RMAP_EVENT_MATCH_DELETED);
 -
 +  char *plen = (argc == 6) ? argv[5]->arg : NULL;
-   return zebra_route_match_delete (vty, vty->index,
+   return zebra_route_match_delete (vty,
 -                                 "ip next-hop prefix-len", argv[0],
 +                                 "ip next-hop prefix-len", plen,
                                   RMAP_EVENT_MATCH_DELETED);
  }
  
@@@ -316,28 -583,41 +286,28 @@@ DEFUN (match_source_protocol
         MATCH_STR
         "Match protocol via which the route was learnt\n")
  {
 +  char *proto = argv[2]->text;
    int i;
  
 -  i = proto_name2num(argv[0]);
 +  i = proto_name2num(proto);
    if (i < 0)
      {
 -      vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
 -               VTY_NEWLINE);
 +      vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE);
        return CMD_WARNING;
      }
-   return zebra_route_match_add (vty, vty->index, "source-protocol", proto, RMAP_EVENT_MATCH_ADDED);
 -  return zebra_route_match_add (vty, "source-protocol",
 -                              argv[0], RMAP_EVENT_MATCH_ADDED);
++  return zebra_route_match_add (vty, "source-protocol", proto, RMAP_EVENT_MATCH_ADDED);
  }
  
  DEFUN (no_match_source_protocol,
         no_match_source_protocol_cmd,
 -       "no match source-protocol (bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static)",
 +       "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static>]",
         NO_STR
         MATCH_STR
 -       "No match protocol via which the route was learnt\n")
 +       "No match protocol via which the route was learnt\n"
 +       )
  {
 -  int i;
 -
 -  if (argc >= 1)
 -    {
 -      i = proto_name2num(argv[0]);
 -      if (i < 0)
 -      {
 -        vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
 -                 VTY_NEWLINE);
 -        return CMD_WARNING;
 -      }
 -    }
 -  return zebra_route_match_delete (vty,
 -                                 "source-protocol", argv[0] ? argv[0] : NULL,
 -                                 RMAP_EVENT_MATCH_DELETED);
 +  char *proto = (argc == 4) ? argv[3]->text : NULL;
-   return zebra_route_match_delete (vty, vty->index, "source-protocol", proto, RMAP_EVENT_MATCH_DELETED);
++  return zebra_route_match_delete (vty, "source-protocol", proto, RMAP_EVENT_MATCH_DELETED);
  }
  
  /* set functions */
@@@ -399,7 -678,7 +369,9 @@@ DEFUN (set_src
        vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
        return CMD_WARNING;
      }
-   return generic_set_add (vty, vty->index, "src", argv[idx_ip]->arg);
 -  return zebra_route_set_add (vty, "src", argv[0]);
++
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++  return generic_set_add (vty, index, "src", argv[idx_ip]->arg);
  }
  
  DEFUN (no_set_src,
         SET_STR
         "Source address for route\n")
  {
 -  if (argc == 0)
 -    return zebra_route_set_delete (vty, "src", NULL);
 -
 -  return zebra_route_set_delete (vty, "src", argv[0]);
 +  char *ip = (argc == 4) ? argv[3]->arg : NULL;
-   return generic_set_delete (vty, vty->index, "src", ip);
++  VTY_DECLVAR_CONTEXT (route_map_index, index);
++  return generic_set_delete (vty, index, "src", ip);
  }
  
  DEFUN (zebra_route_map_timer,
@@@ -1489,22 -1788,27 +1462,18 @@@ zebra_route_map_init (
  {
    install_element (CONFIG_NODE, &ip_protocol_cmd);
    install_element (CONFIG_NODE, &no_ip_protocol_cmd);
 -  install_element (CONFIG_NODE, &no_ip_protocol_val_cmd);
    install_element (VIEW_NODE, &show_ip_protocol_cmd);
--  install_element (ENABLE_NODE, &show_ip_protocol_cmd);
    install_element (CONFIG_NODE, &ipv6_protocol_cmd);
    install_element (CONFIG_NODE, &no_ipv6_protocol_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_protocol_val_cmd);
    install_element (VIEW_NODE, &show_ipv6_protocol_cmd);
--  install_element (ENABLE_NODE, &show_ipv6_protocol_cmd);
    install_element (CONFIG_NODE, &ip_protocol_nht_rmap_cmd);
    install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_cmd);
 -  install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_val_cmd);
    install_element (VIEW_NODE, &show_ip_protocol_nht_cmd);
--  install_element (ENABLE_NODE, &show_ip_protocol_nht_cmd);
    install_element (CONFIG_NODE, &ipv6_protocol_nht_rmap_cmd);
    install_element (CONFIG_NODE, &no_ipv6_protocol_nht_rmap_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_protocol_nht_rmap_val_cmd);
    install_element (VIEW_NODE, &show_ipv6_protocol_nht_cmd);
--  install_element (ENABLE_NODE, &show_ipv6_protocol_nht_cmd);
    install_element (CONFIG_NODE, &zebra_route_map_timer_cmd);
    install_element (CONFIG_NODE, &no_zebra_route_map_timer_cmd);
 -  install_element (CONFIG_NODE, &no_zebra_route_map_timer_val_cmd);
  
    route_map_init ();
    route_map_init_vty ();
index d05b6e13acbd6a1a0ffbc129e4883110136343e9,a691048b2cfd6448eae0604c757608cf1ec370e7..d336b81520f9f1bb70211f8bcb16b64dd7830929
@@@ -203,8 -238,13 +239,13 @@@ static_nexthop_same (struct nexthop *ne
        && si->type == STATIC_IPV6_GATEWAY_IFINDEX
        && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)
        && nexthop->ifindex == si->ifindex)
-     return 1;
+     gw_match = 1;
+   if (!gw_match)
 -    return 0;
 +  return 0;
+   /* Check match on label(s), if any */
+   return static_nexthop_label_same (nexthop, &si->snh_label);
  }
  
  /* Uninstall static route from RIB. */
@@@ -280,13 -320,21 +321,21 @@@ static_uninstall_route (afi_t afi, safi
            /* If there are other active nexthops, do an update. */
            if (rib->nexthop_active_num > 1)
              {
 -                rib_install_kernel (rn, rib, 1);
+               /* Update route in kernel if it's in fib */
+               if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
 -                redistribute_update (&rn->p, rib, NULL);
 +              rib_install_kernel (rn, rib, 1);
+               /* Update redistribution if it's selected */
+               if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED))
 +              redistribute_update (&rn->p, rib, NULL);
              }
            else
              {
 -                redistribute_delete (&rn->p, rib);
+               /* Remove from redistribute if selected route becomes inactive */
+               if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED))
 -                rib_uninstall_kernel (rn, rib);
 +              redistribute_delete (&rn->p, rib);
+               /* Remove from kernel if fib route becomes inactive */
+               if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
 +              rib_uninstall_kernel (rn, rib);
              }
          }
  
Simple merge
index b3164839fab3a54d0b18c5b0d0060792c7472587,12084968b7f3389754c3f32f8c175ca2525811b2..03ff5b8763e16c637f7cead296c87c61ebb93eac
@@@ -14,9 -14,9 +14,9 @@@
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
-- * along with GNU Zebra; see the file COPYING.  If not, write to the 
-- * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
-- * Boston, MA 02111-1307, USA.  
++ * along with GNU Zebra; see the file COPYING.  If not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
   */
  
  #include <zebra.h>
@@@ -152,7 -171,7 +171,7 @@@ zebra_static_ipv4 (struct vty *vty, saf
  
      return CMD_SUCCESS;
    }
--  
++
    /* When gateway is A.B.C.D format, gate is treated as nexthop
       address other case gate is treated as interface name. */
    ret = inet_aton (gate_str, &gate);
@@@ -191,12 -214,18 +214,12 @@@ DEFUN (ip_mroute_dist
         "Nexthop interface name\n"
         "Distance\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, argv[0], NULL, argv[1],
 -                          NULL, NULL, argc > 2 ? argv[2] : NULL, NULL, NULL);
 -}
 +  char *destprefix = argv[2]->arg;
 +  char *nexthop = argv[3]->arg;
 +  char *distance = (argc == 5) ? argv[4]->arg : NULL;
  
-   return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, destprefix, NULL, nexthop, NULL, NULL, distance, NULL);
 -ALIAS (ip_mroute_dist,
 -       ip_mroute_cmd,
 -       "ip mroute A.B.C.D/M (A.B.C.D|INTERFACE)",
 -       IP_STR
 -       "Configure static unicast route into MRIB for multicast RPF lookup\n"
 -       "IP destination prefix (e.g. 10.0.0.0/8)\n"
 -       "Nexthop address\n"
 -       "Nexthop interface name\n")
++  return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL);
 +}
  
  DEFUN (no_ip_mroute_dist,
         no_ip_mroute_dist_cmd,
         "Nexthop interface name\n"
         "Distance\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, argv[0], NULL, argv[1],
 -                          NULL, NULL, argc > 2 ? argv[2] : NULL, NULL, NULL);
 -}
 +  char *destprefix = argv[3]->arg;
 +  char *nexthop = argv[4]->arg;
 +  char *distance = (argc == 6) ? argv[5]->arg : NULL;
  
-   return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, destprefix, NULL, nexthop, NULL, NULL, distance, NULL);
 -ALIAS (no_ip_mroute_dist,
 -       no_ip_mroute_cmd,
 -       "no ip mroute A.B.C.D/M (A.B.C.D|INTERFACE)",
 -       NO_STR
 -       IP_STR
 -       "Configure static unicast route into MRIB for multicast RPF lookup\n"
 -       "IP destination prefix (e.g. 10.0.0.0/8)\n"
 -       "Nexthop address\n"
 -       "Nexthop interface name\n")
++  return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL);
 +}
  
  DEFUN (ip_multicast_mode,
         ip_multicast_mode_cmd,
@@@ -307,39 -348,24 +330,47 @@@ DEFUN (show_ip_rpf_addr
    return CMD_SUCCESS;
  }
  
 -/* Static route configuration.  */
 -DEFUN (ip_route, 
 -       ip_route_cmd,
 -       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
 -       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")
 +static void
 +zebra_vty_ip_route_tdv_helper (int argc, struct cmd_token *argv[],
 +                             int idx_curr, char **tag,
-                              char **distance, char **vrf)
++                             char **distance, char **vrf, char **labels)
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL,
 -                            NULL, NULL, NULL);
 +  *distance = NULL;
 +  while (idx_curr < argc)
 +  {
 +    if (strmatch (argv[idx_curr]->text, "tag"))
 +      {
-         *tag = argv[idx_curr+1]->arg;
++        if (tag)
++          *tag = argv[idx_curr+1]->arg;
 +        idx_curr += 2;
 +      }
 +    else if (strmatch (argv[idx_curr]->text, "vrf"))
 +      {
-         *vrf = argv[idx_curr+1]->arg;
++        if (vrf)
++          *vrf = argv[idx_curr+1]->arg;
++        idx_curr += 2;
++      }
++    else if (strmatch (argv[idx_curr]->text, "label"))
++      {
++        if (labels)
++          *labels = argv[idx_curr+1]->arg;
 +        idx_curr += 2;
 +      }
 +    else
 +      {
-         *distance = argv[idx_curr]->arg;
++        if (distance)
++          *distance = argv[idx_curr]->arg;
 +        idx_curr++;
 +      }
 +  }
 +
 +  return;
  }
  
 -DEFUN (ip_route_tag,
 -       ip_route_tag_cmd,
 -       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295>",
 +/* Static route configuration.  */
 +DEFUN (ip_route,
 +       ip_route_cmd,
-        "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         IP_STR
         "Establish static routes\n"
         "IP destination prefix (e.g. 10.0.0.0/8)\n"
         "IP gateway interface name\n"
         "Null interface\n"
         "Set tag for this route\n"
 -       "One or more labels separated by '/'\n")
 +       "Tag value\n"
 +       "Distance value for this route\n"
 +       VRF_CMD_HELP_STR)
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2],
 -                            NULL, NULL, NULL);
 +  int idx_ipv4_prefixlen = 2;
 +  int idx_ipv4_ifname_null = 3;
 +  int idx_curr = 4;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
 +                          argv[idx_ipv4_prefixlen]->arg,
 +                          NULL,
 +                          argv[idx_ipv4_ifname_null]->arg,
 +                          NULL,
-                           tag, distance, vrf);
++                          tag, distance, vrf, NULL);
  }
  
  DEFUN (ip_route_flags,
         ip_route_flags_cmd,
-        "ip route A.B.C.D/M <A.B.C.D|INTERFACE> <reject|blackhole> [tag (1-65535)] [(1-255)] [vrf NAME]",
 -       "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], NULL,
 -                            NULL, NULL, NULL);
 -}
 -
 -DEFUN (ip_route_flags_tag,
 -       ip_route_flags_tag_cmd,
 -       "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295>",
++       "ip route A.B.C.D/M <A.B.C.D|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         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")
 -
 +       "Tag value\n"
 +       "Distance value for this route\n"
-        VRF_CMD_HELP_STR)
++        VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], argv[3],
 -                            NULL, NULL, NULL);
 +  int idx_ipv4_prefixlen = 2;
 +  int idx_ipv4_ifname = 3;
 +  int idx_reject_blackhole = 4;
 +  int idx_curr = 5;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
 +                          argv[idx_ipv4_prefixlen]->arg,
 +                          NULL,
 +                          argv[idx_ipv4_ifname]->arg,
 +                          argv[idx_reject_blackhole]->arg,
-                             tag, distance, vrf);
++                            tag, distance, vrf, NULL);
  }
  
  DEFUN (ip_route_flags2,
         ip_route_flags2_cmd,
-        "ip route A.B.C.D/M <reject|blackhole> [tag (1-65535)] [(1-255)] [vrf NAME]",
 -       "ip route A.B.C.D/M (reject|blackhole)",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], NULL,
 -                            NULL, NULL, NULL);
 -}
 -
 -DEFUN (ip_route_flags2_tag,
 -       ip_route_flags2_tag_cmd,
 -       "ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295>",
++       "ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         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")
 -
 +       "Tag value\n"
 +       "Distance value for this route\n"
-        VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], argv[2],
 -                            NULL, NULL, NULL);
 +  int idx_ipv4_prefixlen = 2;
 +  int idx_reject_blackhole = 3;
 +  int idx_curr = 4;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
 +                          argv[idx_ipv4_prefixlen]->arg,
 +                          NULL,
 +                          NULL,
 +                          argv[idx_reject_blackhole]->arg,
-                           tag, distance, vrf);
++                          tag, distance, vrf, NULL);
  }
  
  /* Mask as A.B.C.D format.  */
  DEFUN (ip_route_mask,
         ip_route_mask_cmd,
-        "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-65535)] [(1-255)] [vrf NAME]",
 -       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL,
 -                            NULL, NULL, NULL);
 -}
 -
 -DEFUN (ip_route_mask_tag,
 -       ip_route_mask_tag_cmd,
 -       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295>",
++       "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         IP_STR
         "Establish static routes\n"
         "IP destination prefix\n"
         "IP gateway interface name\n"
         "Null interface\n"
         "Set tag for this route\n"
 -       "Tag value\n")
 -
 +       "Tag value\n"
 +       "Distance value for this route\n"
-        VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3],
 -                            NULL, NULL, NULL);
 +  int idx_ipv4 = 2;
 +  int idx_ipv4_2 = 3;
 +  int idx_ipv4_ifname_null = 4;
 +  int idx_curr = 5;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
 +                          argv[idx_ipv4]->arg,
 +                          argv[idx_ipv4_2]->arg,
 +                          argv[idx_ipv4_ifname_null]->arg,
-                           NULL, tag, distance, vrf);
++                          NULL, tag, distance, vrf, NULL);
  }
  
  DEFUN (ip_route_mask_flags,
         ip_route_mask_flags_cmd,
-        "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE> <reject|blackhole> [tag (1-65535)] [(1-255)] [vrf NAME]",
 -       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], NULL,
 -                            NULL, NULL, NULL);
 -}
 -
 -DEFUN (ip_route_mask_flags_tag,
 -       ip_route_mask_flags_tag_cmd,
 -       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295>",
++       "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         IP_STR
         "Establish static routes\n"
         "IP destination prefix\n"
         "Emit an ICMP unreachable when matched\n"
         "Silently discard pkts when matched\n"
         "Set tag for this route\n"
 -       "Tag value\n")
 -
 +       "Tag value\n"
 +       "Distance value for this route\n"
-        VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], argv[4],
 -                            NULL, NULL, NULL);
 +  int idx_ipv4 = 2;
 +  int idx_ipv4_2 = 3;
 +  int idx_ipv4_ifname = 4;
 +  int idx_reject_blackhole = 5;
 +  int idx_curr = 6;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
 +                          argv[idx_ipv4]->arg,
 +                          argv[idx_ipv4_2]->arg,
 +                          argv[idx_ipv4_ifname]->arg,
 +                          argv[idx_reject_blackhole]->arg,
-                           tag, distance, vrf);
++                          tag, distance, vrf, NULL);
  }
  
 +
  DEFUN (ip_route_mask_flags2,
         ip_route_mask_flags2_cmd,
-        "ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-65535)] [(1-255)] [vrf NAME]",
 -       "ip route A.B.C.D A.B.C.D (reject|blackhole)",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], NULL,
 -                            NULL, NULL, NULL);
 -}
 -
 -DEFUN (ip_route_mask_flags2_tag,
 -       ip_route_mask_flags2_tag_cmd,
 -       "ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295>",
++       "ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         IP_STR
         "Establish static routes\n"
         "IP destination prefix\n"
         "Emit an ICMP unreachable when matched\n"
         "Silently discard pkts when matched\n"
         "Set tag for this route\n"
 -       "Tag value\n")
 +       "Tag value\n"
 +       "Distance value for this route\n"
-        VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], argv[3],
 -                            NULL, NULL, NULL);
 -}
 +  int idx_ipv4 = 2;
 +  int idx_ipv4_2 = 3;
 +  int idx_reject_blackhole = 4;
 +  int idx_curr = 5;
 +  char *tag, *distance, *vrf;
  
 -/* Distance option value.  */
 -DEFUN (ip_route_distance,
 -       ip_route_distance_cmd,
 -       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL,
 -                            argv[2], NULL, NULL);
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
 +                          argv[idx_ipv4]->arg,
 +                          argv[idx_ipv4_2]->arg,
 +                          NULL,
 +                          argv[idx_reject_blackhole]->arg,
-                           tag, distance, vrf);
++                          tag, distance, vrf, NULL);
  }
  
 -DEFUN (ip_route_tag_distance,
 -       ip_route_tag_distance_cmd,
 -       "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255>",
 +DEFUN (no_ip_route,
 +       no_ip_route_cmd,
-        "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
 +       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"
 -       "Set tag for this route\n"
 +       "Tag of this route\n"
         "Tag value\n"
 -       "Distance value for this route\n")
 -
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2],
 -                            argv[3], NULL, NULL);
 -}
 -
 -DEFUN (ip_route_flags_distance,
 -       ip_route_flags_distance_cmd,
 -       "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
 -       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")
 +       "Distance value for this route\n"
-        VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], NULL,
 -                            argv[3], NULL, NULL);
 -}
 +  int idx_ipv4_prefixlen = 3;
 +  int idx_ipv4_ifname_null = 4;
 +  int idx_curr = 5;
 +  char *tag, *distance, *vrf;
  
 -DEFUN (ip_route_flags_tag_distance,
 -       ip_route_flags_tag_distance_cmd,
 -       "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], argv[3],
 -                            argv[4], NULL, NULL);
 -}
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
  
 -DEFUN (ip_route_flags_distance2,
 -       ip_route_flags_distance2_cmd,
 -       "ip route A.B.C.D/M (reject|blackhole) <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], NULL,
 -                            argv[2], NULL, NULL);
 +  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
 +                          argv[idx_ipv4_prefixlen]->arg,
 +                          NULL,
 +                          argv[idx_ipv4_ifname_null]->arg,
 +                          NULL,
-                           tag, distance, vrf);
++                          tag, distance, vrf, NULL);
  }
  
 -DEFUN (ip_route_flags_tag_distance2,
 -       ip_route_flags_tag_distance2_cmd,
 -       "ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> <1-255>",
 +DEFUN (no_ip_route_flags2,
 +       no_ip_route_flags2_cmd,
-        "no ip route A.B.C.D/M <reject|blackhole> [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "no ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
 +       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"
 -       "Set tag for this route\n"
 +       "Tag of this route\n"
         "Tag value\n"
 -       "Distance value for this route\n")
 +       "Distance value for this route\n"
-        VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], argv[2],
 -                            argv[3], NULL, NULL);
 -}
 +  int idx_ipv4_prefixlen = 3;
 +  int idx_curr = 5;
 +  char *tag, *distance, *vrf;
  
 -DEFUN (ip_route_mask_distance,
 -       ip_route_mask_distance_cmd,
 -       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL,
 -                            argv[3], NULL, NULL);
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
 +                          argv[idx_ipv4_prefixlen]->arg,
 +                          NULL, NULL, NULL,
-                           tag, distance, vrf);
++                          tag, distance, vrf, NULL);
  }
  
 -DEFUN (ip_route_mask_tag_distance,
 -       ip_route_mask_tag_distance_cmd,
 -       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255>",
 +DEFUN (no_ip_route_mask,
 +       no_ip_route_mask_cmd,
-        "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
 +       NO_STR
         IP_STR
         "Establish static routes\n"
         "IP destination prefix\n"
         "IP gateway address\n"
         "IP gateway interface name\n"
         "Null interface\n"
 -       "Set tag for this route\n"
 +       "Tag of this route\n"
         "Tag value\n"
 -       "Distance value for this route\n")
 +       "Distance value for this route\n"
-        VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3],
 -                            argv[4], NULL, NULL);
 +  int idx_ipv4 = 3;
 +  int idx_ipv4_2 = 4;
 +  int idx_ipv4_ifname_null = 5;
 +  int idx_curr = 6;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
 +                          argv[idx_ipv4]->arg,
 +                          argv[idx_ipv4_2]->arg,
 +                          argv[idx_ipv4_ifname_null]->arg,
 +                          NULL,
-                           tag, distance, vrf);
++                          tag, distance, vrf, NULL);
  }
  
 -DEFUN (ip_route_mask_flags_tag_distance,
 -       ip_route_mask_flags_tag_distance_cmd,
 -       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)  tag <1-4294967295> <1-255>",
 +DEFUN (no_ip_route_mask_flags2,
 +       no_ip_route_mask_flags2_cmd,
-        "no ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "no ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
 +       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"
 -       "Set tag for this route\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)
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n")
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], argv[4],
 -                            argv[5], NULL, NULL);
 -}
 +  int idx_ipv4 = 3;
 +  int idx_ipv4_2 = 4;
 +  int idx_curr = 6;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
  
-                           tag, distance, vrf);
 +  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
 +                          argv[idx_ipv4]->arg,
 +                          argv[idx_ipv4_2]->arg,
 +                          NULL, NULL,
++                          tag, distance, vrf, NULL);
 +}
  
 -DEFUN (ip_route_mask_flags_distance,
 -       ip_route_mask_flags_distance_cmd,
 -       "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
 +DEFUN (no_ip_route_flags,
 +       no_ip_route_flags_cmd,
-        "no ip route A.B.C.D/M <A.B.C.D|INTERFACE> <reject|blackhole> [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "no ip route A.B.C.D/M <A.B.C.D|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
 +       NO_STR
         IP_STR
         "Establish static routes\n"
 -       "IP destination prefix\n"
 -       "IP destination prefix mask\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")
 +       "Tag of this route\n"
 +       "Tag value\n"
 +       "Distance value for this route\n"
-        VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], NULL,
 -                            argv[4], NULL, NULL);
 +  int idx_ipv4_prefixlen = 3;
 +  int idx_ipv4_ifname = 4;
 +  int idx_reject_blackhole = 5;
 +  int idx_curr = 6;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
 +                          argv[idx_ipv4_prefixlen]->arg,
 +                          NULL,
 +                          argv[idx_ipv4_ifname]->arg,
 +                          argv[idx_reject_blackhole]->arg,
-                           tag, distance, vrf);
++                          tag, distance, vrf, NULL);
  }
  
 -DEFUN (ip_route_mask_flags_distance2,
 -       ip_route_mask_flags_distance2_cmd,
 -       "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
 +DEFUN (no_ip_route_mask_flags,
 +       no_ip_route_mask_flags_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 NAME]",
++       "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
 +       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], NULL,
 -                            argv[3], NULL, NULL);
 -}
 -
 -DEFUN (ip_route_mask_flags_tag_distance2,
 -       ip_route_mask_flags_tag_distance2_cmd,
 -       "ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> <1-255>",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IP destination prefix\n"
 -       "IP destination prefix mask\n"
 -       "Set tag for this route\n"
 +       "Tag of this route\n"
         "Tag value\n"
         "Distance value for this route\n"
-        VRF_CMD_HELP_STR)
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n")
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], argv[3],
 -                            argv[4], NULL, NULL);
 -}
 +  int idx_ipv4 = 3;
 +  int idx_ipv4_2 = 4;
 +  int idx_ipv4_ifname = 5;
 +  int idx_reject_blackhole = 6;
 +  int idx_curr = 7;
 +  char *tag, *distance, *vrf;
  
 -DEFUN (no_ip_route, 
 -       no_ip_route_cmd,
 -       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL,
 -                            NULL, NULL, NULL);
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); 
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
 +                          argv[idx_ipv4]->arg,
 +                          argv[idx_ipv4_2]->arg,
 +                          argv[idx_ipv4_ifname]->arg,
 +                          argv[idx_reject_blackhole]->arg,
-                           tag, distance, vrf);
++                          tag, distance, vrf, NULL);
  }
  
 -DEFUN (no_ip_route_tag,
 -       no_ip_route_tag_cmd,
 -       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2],
 -                            NULL, NULL, NULL);
 -}
 -
 -ALIAS (no_ip_route,
 -       no_ip_route_flags_cmd,
 -       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)",
 -       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")
 -
 -ALIAS (no_ip_route_tag,
 -       no_ip_route_flags_tag_cmd,
 -       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295>",
 -       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")
 -
 -DEFUN (no_ip_route_flags2,
 -       no_ip_route_flags2_cmd,
 -       "no ip route A.B.C.D/M (reject|blackhole)",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, NULL, NULL,
 -                            NULL, NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_flags2_tag,
 -       no_ip_route_flags2_tag_cmd,
 -       "no ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, NULL, argv[1],
 -                            NULL, NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_mask,
 -       no_ip_route_mask_cmd,
 -       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL,
 -                            NULL, NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_mask_tag,
 -       no_ip_route_mask_tag_cmd,
 -       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3],
 -                            NULL, NULL, NULL);
 -}
 -
 -ALIAS (no_ip_route_mask,
 -       no_ip_route_mask_flags_cmd,
 -       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)",
 -       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")
 -
 -ALIAS (no_ip_route_mask_tag,
 -       no_ip_route_mask_flags_tag_cmd,
 -       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295>",
 -       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")
 -
 -DEFUN (no_ip_route_mask_flags2,
 -       no_ip_route_mask_flags2_cmd,
 -       "no ip route A.B.C.D A.B.C.D (reject|blackhole)",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, NULL, NULL,
 -                            NULL, NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_mask_flags2_tag,
 -       no_ip_route_mask_flags2_tag_cmd,
 -       "no ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, NULL, argv[2],
 -                            NULL, NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_distance,
 -       no_ip_route_distance_cmd,
 -       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL,
 -                            argv[2], NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_tag_distance,
 -       no_ip_route_tag_distance_cmd,
 -       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2],
 -                            argv[3], NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_flags_distance,
 -       no_ip_route_flags_distance_cmd,
 -       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], NULL,
 -                            argv[3], NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_flags_tag_distance,
 -       no_ip_route_flags_tag_distance_cmd,
 -       "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], argv[3],
 -                            argv[4], NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_flags_distance2,
 -       no_ip_route_flags_distance2_cmd,
 -       "no ip route A.B.C.D/M (reject|blackhole) <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], NULL,
 -                            argv[2], NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_flags_tag_distance2,
 -       no_ip_route_flags_tag_distance2_cmd,
 -       "no ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], argv[2],
 -                            argv[3], NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_mask_distance,
 -       no_ip_route_mask_distance_cmd,
 -       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL,
 -                            argv[3], NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_mask_tag_distance,
 -       no_ip_route_mask_tag_distance_cmd,
 -       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3],
 -                            argv[4], NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_mask_flags_distance,
 -       no_ip_route_mask_flags_distance_cmd,
 -       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], argv[3], NULL,
 -                            argv[4], NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_mask_flags_tag_distance,
 -       no_ip_route_mask_flags_tag_distance_cmd,
 -       "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], argv[3], argv[4],
 -                            argv[5], NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_mask_flags_distance2,
 -       no_ip_route_mask_flags_distance2_cmd,
 -       "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, argv[2], NULL,
 -                            argv[3], NULL, NULL);
 -}
 -
 -DEFUN (no_ip_route_mask_flags_tag_distance2,
 -       no_ip_route_mask_flags_tag_distance2_cmd,
 -       "no ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> <1-255>",
 -       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")
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, argv[2], argv[3],
 -                            argv[4], NULL, NULL);
 -}
 -
 -/* 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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL,
 -                          NULL, NULL, argv[2], NULL);
 -}
 -
 -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-4294967295> " 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, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL,
 -                          argv[2], NULL, argv[3], NULL);
 -}
 -
 -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, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
 -                          argv[2], NULL, NULL, argv[3], NULL);
 -}
 -
 -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-4294967295> " 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)
 -
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
 -                          argv[2], argv[3], NULL, argv[4], NULL);
 -}
 -
 -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, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1],
 -                          NULL, NULL, argv[2], NULL);
 -}
 -
 -DEFUN (ip_route_flags2_tag_vrf,
 -       ip_route_flags2_tag_vrf_cmd,
 -       "ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> " 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)
 -
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1],
 -                          argv[2], NULL, argv[3], NULL);
 -}
 -
 -/* 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, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
 -                          NULL, NULL, NULL, argv[3], NULL);
 -}
 -
 -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-4294967295> " 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)
 -
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
 -                          NULL, argv[3], NULL, argv[4], NULL);
 -}
 -
 -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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
 -                          argv[3], NULL, NULL, argv[4], NULL);
 -}
 -
 -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-4294967295> " 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)
 -
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
 -                          argv[3], argv[4], NULL, argv[5], NULL);
 -}
 -
 -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
 -       "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, SAFI_UNICAST, 1, argv[0], argv[1], NULL,
 -                          argv[2], NULL, NULL, argv[3], NULL);
 -}
 -
 -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-4294967295> " VRF_CMD_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"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL,
 -                          argv[2], argv[3], NULL, argv[4], NULL);
 -}
 -
 -/* 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
 -       "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, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL,
 -                          NULL, argv[2], argv[3], NULL);
 -}
 -
 -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-4294967295> <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"
 -       "Null interface\n"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       "Distance value for this route\n"
 -       VRF_CMD_HELP_STR)
 -
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL,
 -                          argv[2], argv[3], argv[4], NULL);
 -}
 -
 -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
 -       "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, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
 -                          argv[2], NULL, argv[3], argv[4], NULL);
 -}
 -
 -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-4294967295> <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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
 -                          argv[2], argv[3], argv[4],argv[5], NULL);
 -}
 -
 -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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1],
 -                          NULL, argv[2], argv[3], NULL);
 -}
 -
 -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-4294967295> <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"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       "Distance value for this route\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1],
 -                          argv[2], argv[3], argv[4], NULL);
 -}
 -
 -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
 -       "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, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
 -                          NULL, NULL, argv[3], argv[4], NULL);
 -}
 -
 -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-4294967295> <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"
 -       "Null interface\n"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       "Distance value for this route\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
 -                          NULL, argv[3], argv[4], argv[5], NULL);
 -}
 -
 -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-4294967295> <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"
 -       "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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
 -                          argv[3], argv[4], argv[5], argv[6], NULL);
 -}
 -
 -
 -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, SAFI_UNICAST, 1, argv[0], argv[1], argv[2],
 -                          argv[3], NULL, argv[4], argv[5], NULL);
 -}
 -
 -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
 -       "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, SAFI_UNICAST, 1, argv[0], argv[1], NULL,
 -                          argv[2], NULL, argv[3], argv[4], NULL);
 -}
 -
 -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-4294967295> <1-255> " VRF_CMD_STR,
 -       IP_STR
 -       "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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL,
 -                          argv[2], argv[3], argv[4], argv[5], NULL);
 -}
 -
 -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
 -       "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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL,
 -                          NULL, NULL, argv[2], NULL);
 -}
 -
 -DEFUN (no_ip_route_flags_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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1],
 -                          argv[2], NULL, NULL, argv[3], NULL);
 -}
 -
 -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-4294967295> " 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, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL,
 -                          argv[2], NULL, argv[3], NULL);
 -}
 -
 -DEFUN (no_ip_route_flags_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-4294967295> " 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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1],
 -                          argv[2], argv[3], NULL, argv[4], NULL);
 -}
 -
 -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, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1],
 -                          NULL, NULL, argv[2], NULL);
 -}
 -
 -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-4294967295> " 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, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1],
 -                          argv[2], NULL, argv[3], NULL);
 -}
 -
 -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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
 -                          NULL, NULL, NULL, argv[3], NULL);
 -}
 -
 -DEFUN (no_ip_route_mask_flags_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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
 -                          argv[3], NULL, NULL, argv[4], NULL);
 -}
 -
 -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-4294967295> " 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, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
 -                          NULL, argv[3], NULL, argv[4], NULL);
 -}
 -
 -DEFUN (no_ip_route_mask_flags_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-4294967295> " 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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
 -                          argv[3], argv[4], NULL, argv[5], NULL);
 -}
 -
 -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, SAFI_UNICAST, 0, argv[0], argv[1], NULL,
 -                          argv[2], NULL, NULL, argv[3], NULL);
 -}
 -
 -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-4294967295> " 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)
 -{
 -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL,
 -                          argv[2], argv[3], NULL, argv[4], NULL);
 -}
 -
 -
 -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, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL,
 -                          NULL, argv[2], argv[3], NULL);
 -}
 -
 -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-4294967295> <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, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL,
 -                          argv[2], argv[3], argv[4], NULL);
 -}
 -
 -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, SAFI_UNICAST, 0, argv[0], NULL, argv[1],
 -                          argv[2], NULL, argv[3], argv[4], NULL);
 -}
 -
 -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-4294967295> <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, SAFI_UNICAST, 0, argv[0], NULL, argv[1],
 -                          argv[2], argv[3], argv[4],argv[5], NULL);
 -}
 -
 -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, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1],
 -                          NULL, argv[2], argv[3], NULL);
 -}
 -
 -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-4294967295> <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, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1],
 -                          argv[2] , argv[3], argv[4], NULL);
 -}
 -
 -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, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
 -                          NULL, NULL, argv[3], argv[4], NULL);
 -}
 -
 -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-4294967295> <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, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
 -                          NULL, argv[3], argv[4], argv[5], NULL);
 -}
 -
 -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, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
 -                          argv[3], NULL, argv[4], argv[5], NULL);
 -}
 -
 -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-4294967295> <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, SAFI_UNICAST, 0, argv[0], argv[1], argv[2],
 -                          argv[3], argv[4], argv[5], argv[6], NULL);
 -}
 -
 -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, SAFI_UNICAST, 0, argv[0], argv[1], NULL,
 -                          argv[2], NULL, argv[3], argv[4], NULL);
 -}
 -
 -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-4294967295> <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, SAFI_UNICAST, 0, argv[0], argv[1], NULL,
 -                          argv[2], argv[3], argv[4], argv[5], NULL);
 -}
 -
 -/* New RIB.  Detailed information for IPv4 route. */
 -static void
 -vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
 -{
 -  struct rib *rib;
 -  struct nexthop *nexthop, *tnexthop;
 -  int recursing;
 -  char buf[PREFIX_STRLEN];
 -  struct zebra_vrf *zvrf;
 -
 -  RNODE_FOREACH_RIB (rn, rib)
 -    {
 -      const char *mcast_info = "";
 -      if (mcast)
 -        {
 -          rib_table_info_t *info = rn->table->info;
 -          mcast_info = (info->safi == SAFI_MULTICAST)
 -                       ? " using Multicast RIB"
 -                       : " using Unicast RIB";
 -        }
 -      
 -      vty_out (vty, "Routing entry for %s%s%s",
 -             prefix2str (&rn->p, buf, sizeof(buf)), mcast_info,
 -             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 %"ROUTE_TAG_PRI, rib->tag);
 -       if (rib->mtu)
 -        vty_out (vty, ", mtu %u", rib->mtu);
 -      if (rib->vrf_id != VRF_DEFAULT)
 -        {
 -          zvrf = vrf_info_lookup(rib->vrf_id);
 -          vty_out (vty, ", vrf %s", zvrf->name);
 -        }
 -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
 -      vty_out (vty, ", best");
 -      else if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
 -        vty_out (vty, ", fib");
 -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_FIB_OVERRIDE))
 -        vty_out (vty, ", fib-override");
 -      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);
 -
 -      if (rib->type == ZEBRA_ROUTE_RIP
 -        || rib->type == ZEBRA_ROUTE_OSPF
 -        || 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, "%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;
 -          case NEXTHOP_TYPE_IPV6:
 -          case NEXTHOP_TYPE_IPV6_IFINDEX:
 -            vty_out (vty, " %s",
 -                     inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
 -            if (nexthop->ifindex)
 -              vty_out (vty, ", via %s",
 -                         ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 -            break;
 -          case NEXTHOP_TYPE_IFINDEX:
 -            vty_out (vty, " directly connected, %s",
 -                     ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 -            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:
 -              if (nexthop->src.ipv4.s_addr)
 -                {
 -                if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
 -                    sizeof addrstr))
 -                    vty_out (vty, ", src %s", addrstr);
 -                }
 -              break;
 -            case NEXTHOP_TYPE_IPV6:
 -            case NEXTHOP_TYPE_IPV6_IFINDEX:
 -              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;
 -            default:
 -             break;
 -            }
 -
 -          /* Label information */
 -          if (nexthop->nh_label && nexthop->nh_label->num_labels)
 -            {
 -              vty_out (vty, " label %s",
 -                       mpls_label2str (nexthop->nh_label->num_labels,
 -                                   nexthop->nh_label->label,  buf, BUFSIZ));
 -            }
 -
 -        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,
 -                   json_object *json)
 -{
 -  struct nexthop *nexthop, *tnexthop;
 -  int recursing;
 -  int len = 0;
 -  char buf[BUFSIZ];
 -  json_object *json_nexthops = NULL;
 -  json_object *json_nexthop = NULL;
 -  json_object *json_route = NULL;
 -
 -  if (json)
 -    {
 -      json_route = json_object_new_object();
 -      json_nexthops = json_object_new_array();
 -
 -      json_object_string_add(json_route, "prefix", prefix2str (&rn->p, buf, sizeof buf));
 -      json_object_string_add(json_route, "protocol", zebra_route_string(rib->type));
 -
 -      if (rib->instance)
 -        json_object_int_add(json_route, "instance", rib->instance);
 -
 -      if (rib->vrf_id)
 -        json_object_int_add(json_route, "vrfId", rib->vrf_id);
 -
 -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
 -        json_object_boolean_true_add(json_route, "selected");
 -
 -      if (rib->type != ZEBRA_ROUTE_CONNECT && rib->type != ZEBRA_ROUTE_KERNEL)
 -        {
 -          json_object_int_add(json_route, "distance", rib->distance);
 -          json_object_int_add(json_route, "metric", rib->metric);
 -        }
 -
 -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
 -        json_object_boolean_true_add(json_route, "blackhole");
 -
 -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
 -        json_object_boolean_true_add(json_route, "reject");
 -
 -      if (rib->type == ZEBRA_ROUTE_RIP
 -          || rib->type == ZEBRA_ROUTE_OSPF
 -          || 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);
 -
 -          if (uptime < ONE_DAY_SECOND)
 -            sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
 -          else if (uptime < ONE_WEEK_SECOND)
 -            sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, tm->tm_min);
 -          else
 -            sprintf(buf, "%02dw%dd%02dh", tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
 -
 -          json_object_string_add(json_route, "uptime", buf);
 -        }
 -
 -      for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
 -        {
 -          json_nexthop = json_object_new_object();
 -
 -          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
 -            json_object_boolean_true_add(json_nexthop, "fib");
 -
 -          switch (nexthop->type)
 -            {
 -            case NEXTHOP_TYPE_IPV4:
 -            case NEXTHOP_TYPE_IPV4_IFINDEX:
 -              json_object_string_add(json_nexthop, "ip", inet_ntoa (nexthop->gate.ipv4));
 -              json_object_string_add(json_nexthop, "afi", "ipv4");
 -
 -              if (nexthop->ifindex)
 -                {
 -                  json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
 -                  json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 -                }
 -              break;
 -            case NEXTHOP_TYPE_IPV6:
 -            case NEXTHOP_TYPE_IPV6_IFINDEX:
 -              json_object_string_add(json_nexthop, "ip", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
 -              json_object_string_add(json_nexthop, "afi", "ipv6");
 -
 -              if (nexthop->ifindex)
 -                {
 -                  json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
 -                  json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 -                }
 -              break;
 -
 -            case NEXTHOP_TYPE_IFINDEX:
 -              json_object_boolean_true_add(json_nexthop, "directlyConnected");
 -              json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
 -              json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 -              break;
 -            case NEXTHOP_TYPE_BLACKHOLE:
 -              json_object_boolean_true_add(json_nexthop, "blackhole");
 -              break;
 -            default:
 -              break;
 -            }
 -
 -          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
 -            json_object_boolean_true_add(json_nexthop, "active");
 -
 -          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
 -            json_object_boolean_true_add(json_nexthop, "onLink");
 -
 -          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
 -            json_object_boolean_true_add(json_nexthop, "recursive");
 -
 -          switch (nexthop->type)
 -            {
 -              case NEXTHOP_TYPE_IPV4:
 -              case NEXTHOP_TYPE_IPV4_IFINDEX:
 -                if (nexthop->src.ipv4.s_addr)
 -                  {
 -                    if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
 -                      json_object_string_add(json_nexthop, "source", buf);
 -                  }
 -                break;
 -              case NEXTHOP_TYPE_IPV6:
 -              case NEXTHOP_TYPE_IPV6_IFINDEX:
 -                if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
 -                  {
 -                    if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
 -                      json_object_string_add(json_nexthop, "source", buf);
 -                  }
 -                break;
 -              default:
 -                break;
 -            }
 -
 -          json_object_array_add(json_nexthops, json_nexthop);
 -        }
 -
 -      json_object_object_add(json_route, "nexthops", json_nexthops);
 -      json_object_array_add(json, json_route);
 -      return;
 -    }
 -
 -  /* 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",
 -                        CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
 -                        ? '>' : CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)
 -                        ? '!' : ' ',
 -                        CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
 -                        ? '*' : ' ',
 -                        prefix2str (&rn->p, buf, sizeof buf));
 -
 -        /* 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_vrf (nexthop->ifindex, rib->vrf_id));
 -        break;
 -        case NEXTHOP_TYPE_IPV6:
 -      case NEXTHOP_TYPE_IPV6_IFINDEX:
 -        vty_out (vty, " via %s",
 -                 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
 -        if (nexthop->ifindex)
 -          vty_out (vty, ", %s",
 -                     ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 -        break;
 -
 -      case NEXTHOP_TYPE_IFINDEX:
 -        vty_out (vty, " is directly connected, %s",
 -                 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 -        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:
 -            if (nexthop->src.ipv4.s_addr)
 -              {
 -              if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
 -                  vty_out (vty, ", src %s", buf);
 -              }
 -            break;
 -          case NEXTHOP_TYPE_IPV6:
 -          case NEXTHOP_TYPE_IPV6_IFINDEX:
 -            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;
 -          default:
 -          break;
 -        }
 -
 -      /* Label information */
 -      if (nexthop->nh_label && nexthop->nh_label->num_labels)
 -        {
 -        vty_out (vty, " label %s",
 -                 mpls_label2str (nexthop->nh_label->num_labels,
 -                                 nexthop->nh_label->label,  buf, BUFSIZ));
 -        }
 -
 -      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_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);
 -
 -        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 {json}",
 -       SHOW_STR
 -       IP_STR
 -       "IP routing table\n")
 -{
 -  return do_show_ip_route (vty, VRF_DEFAULT_NAME, SAFI_UNICAST, use_json(argc, argv));
 -}
 -
 -static int
 -do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
 -                  u_char use_json)
 -{
 -  struct route_table *table;
 -  struct route_node *rn;
 -  struct rib *rib;
 -  int first = 1;
 -  struct zebra_vrf *zvrf = NULL;
 -  char buf[BUFSIZ];
 -  json_object *json = NULL;
 -  json_object *json_prefix = NULL;
 -
 -  if (!(zvrf = zebra_vrf_list_lookup_by_name (vrf_name)))
 -    {
 -      if (use_json)
 -        vty_out (vty, "{}%s", VTY_NEWLINE);
 -      else
 -        vty_out (vty, "vrf %s not defined%s", vrf_name, VTY_NEWLINE);
 -      return CMD_SUCCESS;
 -    }
 -
 -  if (zvrf->vrf_id == VRF_UNKNOWN)
 -    {
 -      if (use_json)
 -        vty_out (vty, "{}%s", VTY_NEWLINE);
 -      else
 -        vty_out (vty, "vrf %s inactive%s", vrf_name, VTY_NEWLINE);
 -      return CMD_SUCCESS;
 -    }
 -
 -  table = zebra_vrf_table (AFI_IP, safi, zvrf->vrf_id);
 -  if (! table)
 -    {
 -      if (use_json)
 -        vty_out (vty, "{}%s", VTY_NEWLINE);
 -      return CMD_SUCCESS;
 -    }
 -
 -  if (use_json)
 -    {
 -      json = json_object_new_object();
 -
 -      /* Show all IPv4 routes. */
 -      for (rn = route_top (table); rn; rn = route_next (rn))
 -        {
 -          RNODE_FOREACH_RIB (rn, rib)
 -            {
 -              if (!json_prefix)
 -                json_prefix = json_object_new_array();
 -              vty_show_ip_route (vty, rn, rib, json_prefix);
 -            }
 -
 -          if (json_prefix)
 -            {
 -              prefix2str (&rn->p, buf, sizeof buf);
 -              json_object_object_add(json, buf, json_prefix);
 -              json_prefix = NULL;
 -            }
 -        }
 -
 -      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
 -      json_object_free(json);
 -    }
 -  else
 -    {
 -      /* 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, NULL);
 -            }
 -        }
 -    }
 -
 -  return CMD_SUCCESS;
 -}
 -
 -DEFUN (show_ip_route_vrf,
 -       show_ip_route_vrf_cmd,
 -       "show ip route  " VRF_CMD_STR " {json}",
 -       SHOW_STR
 -       IP_STR
 -       "IP routing table\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  u_char uj = use_json(argc, argv);
 -
 -  if (argc == 1 && uj)
 -    return do_show_ip_route (vty, NULL, SAFI_UNICAST, uj);
 -  else
 -    return do_show_ip_route (vty, argv[0], SAFI_UNICAST, uj);
 -}
 -
 -DEFUN (show_ip_nht,
 -       show_ip_nht_cmd,
 -       "show ip nht",
 -       SHOW_STR
 -       IP_STR
 -       "IP nexthop tracking table\n")
 -{
 -  vrf_id_t vrf_id = VRF_DEFAULT;
 -
 -  if (argc)
 -    VRF_GET_ID (vrf_id, argv[0]);
 -
 -  zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
 -  return CMD_SUCCESS;
 -}
 -
 -ALIAS (show_ip_nht,
 -       show_ip_nht_vrf_cmd,
 -       "show ip nht " VRF_CMD_STR,
 -       SHOW_STR
 -       IP_STR
 -       "IP nexthop tracking table\n"
 -       VRF_CMD_HELP_STR)
 -
 -DEFUN (show_ip_nht_vrf_all,
 -       show_ip_nht_vrf_all_cmd,
 -       "show ip nht " VRF_ALL_CMD_STR,
 -       SHOW_STR
 -       IP_STR
 -       "IP nexthop tracking table\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_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
 -        zebra_print_rnh_table(zvrf->vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
 -      }
 -
 -  return CMD_SUCCESS;
 -}
 -
 -DEFUN (show_ipv6_nht,
 -       show_ipv6_nht_cmd,
 -       "show ipv6 nht",
 -       SHOW_STR
 -       IPV6_STR
 -       "IPv6 nexthop tracking table\n")
 -{
 -  vrf_id_t vrf_id = VRF_DEFAULT;
 -
 -  if (argc)
 -    VRF_GET_ID (vrf_id, argv[0]);
 -
 -  zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
 -  return CMD_SUCCESS;
 -}
 -
 -ALIAS (show_ipv6_nht,
 -       show_ipv6_nht_vrf_cmd,
 -       "show ipv6 nht " VRF_CMD_STR,
 -       SHOW_STR
 -       IPV6_STR
 -       "IPv6 nexthop tracking table\n"
 -       VRF_CMD_HELP_STR)
 -
 -DEFUN (show_ipv6_nht_vrf_all,
 -       show_ipv6_nht_vrf_all_cmd,
 -       "show ipv6 nht " VRF_ALL_CMD_STR,
 -       SHOW_STR
 -       IP_STR
 -       "IPv6 nexthop tracking table\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_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
 -        zebra_print_rnh_table(zvrf->vrf_id, 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-4294967295>",
 -       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;
 -  route_tag_t tag = 0;
 -  vrf_id_t vrf_id = VRF_DEFAULT;
 -
 -  if (argc > 1)
 -    {
 -      tag = atol(argv[1]);
 -      VRF_GET_ID (vrf_id, argv[0]);
 -    }
 -  else
 -    tag = atol(argv[0]);
 -
 -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
 -  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, NULL);
 -      }
 -  return CMD_SUCCESS;
 -}
 -
 -ALIAS (show_ip_route_tag,
 -       show_ip_route_vrf_tag_cmd,
 -       "show ip route " VRF_CMD_STR " tag <1-4294967295>",
 -       SHOW_STR
 -       IP_STR
 -       "IP routing table\n"
 -       VRF_CMD_HELP_STR
 -       "Show only routes with tag\n"
 -       "Tag value\n")
--
 -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")
 +/* New RIB.  Detailed information for IPv4 route. */
 +static void
 +vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
  {
 -  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;
 -
 -  if (argc > 1)
 -    {
 -      ret = str2prefix (argv[1], &p);
 -      VRF_GET_ID (vrf_id, argv[0]);
 -    }
 -  else
 -    ret = str2prefix (argv[0], &p);
 +  struct nexthop *nexthop, *tnexthop;
 +  int recursing;
 +  char buf[PREFIX_STRLEN];
 +  struct zebra_vrf *zvrf;
  
 -  if (! ret)
 +  RNODE_FOREACH_RIB (rn, rib)
      {
 -      vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 -
 -  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, NULL);
 -      }
 -  return CMD_SUCCESS;
 -}
 -
 -ALIAS (show_ip_route_prefix_longer,
 -       show_ip_route_vrf_prefix_longer_cmd,
 -       "show ip route " VRF_CMD_STR " A.B.C.D/M longer-prefixes",
 -       SHOW_STR
 -       IP_STR
 -       "IP routing table\n"
 -       VRF_CMD_HELP_STR
 -       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
 -       "Show route matching the specified Network/Mask pair only\n")
 -
 -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)
 -    VRF_GET_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, NULL);
 -        }
 -      }
 -  return CMD_SUCCESS;
 -}
 +      const char *mcast_info = "";
 +      if (mcast)
 +        {
 +          rib_table_info_t *info = rn->table->info;
 +          mcast_info = (info->safi == SAFI_MULTICAST)
 +                       ? " using Multicast RIB"
 +                       : " using Unicast RIB";
 +        }
-       
 -ALIAS (show_ip_route_supernets,
 -       show_ip_route_vrf_supernets_cmd,
 -       "show ip route " VRF_CMD_STR " supernets-only",
 -       SHOW_STR
 -       IP_STR
 -       "IP routing table\n"
 -       VRF_CMD_HELP_STR
 -       "Show supernet entries only\n")
 +      vty_out (vty, "Routing entry for %s%s%s",
 +             prefix2str (&rn->p, buf, sizeof(buf)), mcast_info,
 +             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 (rib->mtu)
 +        vty_out (vty, ", mtu %u", rib->mtu);
 +      if (rib->vrf_id != VRF_DEFAULT)
 +        {
 +          zvrf = vrf_info_lookup(rib->vrf_id);
 +          vty_out (vty, ", vrf %s", zvrf->name);
 +        }
 +      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);
  
 -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;
 +      if (rib->type == ZEBRA_ROUTE_RIP
 +        || rib->type == ZEBRA_ROUTE_OSPF
 +        || rib->type == ZEBRA_ROUTE_ISIS
 +        || rib->type == ZEBRA_ROUTE_TABLE
 +        || rib->type == ZEBRA_ROUTE_BGP)
 +      {
 +        time_t uptime;
 +        struct tm *tm;
  
 -  if (argc > 1)
 -    {
 -      type = proto_redistnum (AFI_IP, argv[1]);
 -      VRF_GET_ID (vrf_id, argv[0]);
 -     }
 -  else
 -    type = proto_redistnum (AFI_IP, argv[0]);
 +        uptime = time (NULL);
 +        uptime -= rib->uptime;
 +        tm = gmtime (&uptime);
  
 -  if (type < 0)
 -    {
 -      vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 +        vty_out (vty, "  Last update ");
  
 -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
 -  if (! table)
 -    return CMD_SUCCESS;
 +        if (uptime < ONE_DAY_SECOND)
-           vty_out (vty,  "%02d:%02d:%02d", 
++          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", 
++          vty_out (vty, "%dd%02dh%02dm",
 +                   tm->tm_yday, tm->tm_hour, tm->tm_min);
 +        else
-           vty_out (vty, "%02dw%dd%02dh", 
++          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);
 +      }
  
 -  /* Show matched type IPv4 routes. */
 -  for (rn = route_top (table); rn; rn = route_next (rn))
 -    RNODE_FOREACH_RIB (rn, rib)
 -      if (rib->type == type)
 +      for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
        {
 -        if (first)
 -          {
 -            vty_out (vty, SHOW_ROUTE_V4_HEADER);
 -            first = 0;
 -          }
 -        vty_show_ip_route (vty, rn, rib, NULL);
 -      }
 -  return CMD_SUCCESS;
 -}
 +          char addrstr[32];
  
 -ALIAS (show_ip_route_protocol,
 -       show_ip_route_vrf_protocol_cmd,
 -       "show ip route " VRF_CMD_STR "  " QUAGGA_IP_REDIST_STR_ZEBRA,
 -       SHOW_STR
 -       IP_STR
 -       "IP routing table\n"
 -       VRF_CMD_HELP_STR
 -       QUAGGA_IP_REDIST_HELP_STR_ZEBRA)
 +        vty_out (vty, "  %c%s",
 +                 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
 +                 recursing ? "  " : "");
  
 -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;
 +        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;
 +          case NEXTHOP_TYPE_IPV6:
 +          case NEXTHOP_TYPE_IPV6_IFINDEX:
 +            vty_out (vty, " %s",
 +                     inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
 +            if (nexthop->ifindex)
 +              vty_out (vty, ", via %s",
 +                         ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 +            break;
 +          case NEXTHOP_TYPE_IFINDEX:
 +            vty_out (vty, " directly connected, %s",
 +                     ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 +            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");
  
 -  VTY_GET_INTEGER ("Instance", instance, argv[0]);
 +        if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
 +          vty_out (vty, " onlink");
  
 -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
 -  if (! table)
 -    return CMD_SUCCESS;
 +        if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
 +          vty_out (vty, " (recursive)");
  
 -  /* 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, NULL);
 +        switch (nexthop->type)
 +            {
 +            case NEXTHOP_TYPE_IPV4:
 +            case NEXTHOP_TYPE_IPV4_IFINDEX:
 +              if (nexthop->src.ipv4.s_addr)
 +                {
 +                if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
 +                    sizeof addrstr))
 +                    vty_out (vty, ", src %s", addrstr);
 +                }
 +              break;
 +            case NEXTHOP_TYPE_IPV6:
 +            case NEXTHOP_TYPE_IPV6_IFINDEX:
 +              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;
 +            default:
 +             break;
 +            }
 +        vty_out (vty, "%s", VTY_NEWLINE);
        }
 -  return CMD_SUCCESS;
 +      vty_out (vty, "%s", VTY_NEWLINE);
 +    }
  }
  
 -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")
 +static void
 +vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
 +                   json_object *json)
  {
 -  int ret;
 -  struct prefix_ipv4 p;
 -  struct route_table *table;
 -  struct route_node *rn;
 -  vrf_id_t vrf_id = VRF_DEFAULT;
 -
 -  if (argc > 1)
 -    {
 -      VRF_GET_ID (vrf_id, argv[0]);
 -      ret = str2prefix_ipv4 (argv[1], &p);
 -    }
 -  else
 -    ret = str2prefix_ipv4 (argv[0], &p);
 +  struct nexthop *nexthop, *tnexthop;
 +  int recursing;
 +  int len = 0;
 +  char buf[BUFSIZ];
 +  json_object *json_nexthops = NULL;
 +  json_object *json_nexthop = NULL;
 +  json_object *json_route = NULL;
  
 -  if (ret <= 0)
 +  if (json)
      {
 -      vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 -
 -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
 -  if (! table)
 -    return CMD_SUCCESS;
 +      json_route = json_object_new_object();
 +      json_nexthops = json_object_new_array();
  
 -  rn = route_node_match (table, (struct prefix *) &p);
 -  if (! rn)
 -    {
 -      vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 +      json_object_string_add(json_route, "prefix", prefix2str (&rn->p, buf, sizeof buf));
 +      json_object_string_add(json_route, "protocol", zebra_route_string(rib->type));
  
 -  vty_show_ip_route_detail (vty, rn, 0);
 +      if (rib->instance)
 +        json_object_int_add(json_route, "instance", rib->instance);
  
 -  route_unlock_node (rn);
 +      if (rib->vrf_id)
 +        json_object_int_add(json_route, "vrfId", rib->vrf_id);
  
 -  return CMD_SUCCESS;
 -}
 +      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
 +        json_object_boolean_true_add(json_route, "selected");
  
 -ALIAS (show_ip_route_addr,
 -       show_ip_route_vrf_addr_cmd,
 -       "show ip route "  VRF_CMD_STR " A.B.C.D",
 -       SHOW_STR
 -       IP_STR
 -       "IP routing table\n"
 -       VRF_CMD_HELP_STR
 -       "Network in the IP routing table to display\n")
 +      if (rib->type != ZEBRA_ROUTE_CONNECT && rib->type != ZEBRA_ROUTE_KERNEL)
 +        {
 +          json_object_int_add(json_route, "distance", rib->distance);
 +          json_object_int_add(json_route, "metric", rib->metric);
 +        }
  
 -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;
 +      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
 +        json_object_boolean_true_add(json_route, "blackhole");
  
 -  if (argc > 1)
 -    {
 -      VRF_GET_ID (vrf_id, argv[0]);
 -      ret = str2prefix_ipv4 (argv[1], &p);
 -    }
 -  else
 -    ret = str2prefix_ipv4 (argv[0], &p);
 +      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
 +        json_object_boolean_true_add(json_route, "reject");
  
 -  if (ret <= 0)
 -    {
 -      vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
 +      if (rib->type == ZEBRA_ROUTE_RIP
 +          || rib->type == ZEBRA_ROUTE_OSPF
 +          || rib->type == ZEBRA_ROUTE_ISIS
 +          || rib->type == ZEBRA_ROUTE_TABLE
 +          || rib->type == ZEBRA_ROUTE_BGP)
 +        {
 +          time_t uptime;
 +          struct tm *tm;
  
 -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
 -  if (! table)
 -    return CMD_SUCCESS;
 +          uptime = time (NULL);
 +          uptime -= rib->uptime;
 +          tm = gmtime (&uptime);
  
 -  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;
 -    }
 +          if (uptime < ONE_DAY_SECOND)
 +            sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
 +          else if (uptime < ONE_WEEK_SECOND)
 +            sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, tm->tm_min);
 +          else
 +            sprintf(buf, "%02dw%dd%02dh", tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
  
 -  vty_show_ip_route_detail (vty, rn, 0);
 +          json_object_string_add(json_route, "uptime", buf);
 +        }
  
 -  route_unlock_node (rn);
 +      for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
 +        {
 +          json_nexthop = json_object_new_object();
  
 -  return CMD_SUCCESS;
 -}
 +          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
 +            json_object_boolean_true_add(json_nexthop, "fib");
  
 -ALIAS (show_ip_route_prefix,
 -       show_ip_route_vrf_prefix_cmd,
 -       "show ip route " VRF_CMD_STR " A.B.C.D/M",
 -       SHOW_STR
 -       IP_STR
 -       "IP routing table\n"
 -       VRF_CMD_HELP_STR
 -       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
 +          switch (nexthop->type)
 +            {
 +            case NEXTHOP_TYPE_IPV4:
 +            case NEXTHOP_TYPE_IPV4_IFINDEX:
 +              json_object_string_add(json_nexthop, "ip", inet_ntoa (nexthop->gate.ipv4));
 +              json_object_string_add(json_nexthop, "afi", "ipv4");
  
 -static void
 -vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
 -{
 -  struct route_node *rn;
 -  struct rib *rib;
 -#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;
 -  u_int32_t is_ibgp;
 +              if (nexthop->ifindex)
 +                {
 +                  json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
 +                  json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 +                }
 +              break;
 +            case NEXTHOP_TYPE_IPV6:
 +            case NEXTHOP_TYPE_IPV6_IFINDEX:
 +              json_object_string_add(json_nexthop, "ip", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
 +              json_object_string_add(json_nexthop, "afi", "ipv6");
  
 -  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)
 -      {
 -        is_ibgp = (rib->type == ZEBRA_ROUTE_BGP &&
 -                   CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP));
 +              if (nexthop->ifindex)
 +                {
 +                  json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
 +                  json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 +                }
 +              break;
  
 -        rib_cnt[ZEBRA_ROUTE_TOTAL]++;
 -        if (is_ibgp)
 -          rib_cnt[ZEBRA_ROUTE_IBGP]++;
 -        else
 -          rib_cnt[rib->type]++;
 +            case NEXTHOP_TYPE_IFINDEX:
 +              json_object_boolean_true_add(json_nexthop, "directlyConnected");
 +              json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
 +              json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 +              break;
 +            case NEXTHOP_TYPE_BLACKHOLE:
 +              json_object_boolean_true_add(json_nexthop, "blackhole");
 +              break;
 +            default:
 +              break;
 +            }
  
 -        if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
 -          {
 -            fib_cnt[ZEBRA_ROUTE_TOTAL]++;
 +          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
 +            json_object_boolean_true_add(json_nexthop, "active");
  
 -            if (is_ibgp)
 -              fib_cnt[ZEBRA_ROUTE_IBGP]++;
 -            else
 -              fib_cnt[rib->type]++;
 -          }
 -      }
 +          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
 +            json_object_boolean_true_add(json_nexthop, "onLink");
  
 -  vty_out (vty, "%-20s %-20s %s  (vrf %s)%s",
 -           "Route Source", "Routes", "FIB",
 -           ((rib_table_info_t *)table->info)->zvrf->name,
 -           VTY_NEWLINE);
 +          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
 +            json_object_boolean_true_add(json_nexthop, "recursive");
  
 -  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
 -    {
 -      if ((rib_cnt[i] > 0) ||
 -        (i == ZEBRA_ROUTE_BGP && rib_cnt[ZEBRA_ROUTE_IBGP] > 0))
 -        {
 -          if (i == ZEBRA_ROUTE_BGP)
 +          switch (nexthop->type)
              {
 -              vty_out (vty, "%-20s %-20d %-20d %s", "ebgp",
 -                       rib_cnt[ZEBRA_ROUTE_BGP], fib_cnt[ZEBRA_ROUTE_BGP],
 -                       VTY_NEWLINE);
 -              vty_out (vty, "%-20s %-20d %-20d %s", "ibgp",
 -                       rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP],
 -                       VTY_NEWLINE);
 +              case NEXTHOP_TYPE_IPV4:
 +              case NEXTHOP_TYPE_IPV4_IFINDEX:
 +                if (nexthop->src.ipv4.s_addr)
 +                  {
 +                    if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
 +                      json_object_string_add(json_nexthop, "source", buf);
 +                  }
 +                break;
 +              case NEXTHOP_TYPE_IPV6:
 +              case NEXTHOP_TYPE_IPV6_IFINDEX:
 +                if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
 +                  {
 +                    if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
 +                      json_object_string_add(json_nexthop, "source", buf);
 +                  }
 +                break;
 +              default:
 +                break;
              }
 -          else
 -            vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i),
 -                     rib_cnt[i], fib_cnt[i], VTY_NEWLINE);
 +
 +          json_object_array_add(json_nexthops, json_nexthop);
          }
 +
 +      json_object_object_add(json_route, "nexthops", json_nexthops);
 +      json_object_array_add(json, json_route);
 +      return;
      }
  
 -  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);
 -}
 +  /* 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",
 +                        CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
 +                        ? '>' : ' ',
 +                        CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
 +                        ? '*' : ' ',
 +                        prefix2str (&rn->p, buf, sizeof buf));
  
 -/*
 - * 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;
 +        /* Distance and metric display. */
-         if (rib->type != ZEBRA_ROUTE_CONNECT 
++        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_vrf (nexthop->ifindex, rib->vrf_id));
 +        break;
 +        case NEXTHOP_TYPE_IPV6:
 +      case NEXTHOP_TYPE_IPV6_IFINDEX:
 +        vty_out (vty, " via %s",
 +                 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
 +        if (nexthop->ifindex)
 +          vty_out (vty, ", %s",
 +                     ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 +        break;
 +
 +      case NEXTHOP_TYPE_IFINDEX:
 +        vty_out (vty, " is directly connected, %s",
 +                 ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
 +        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:
 +            if (nexthop->src.ipv4.s_addr)
 +              {
 +              if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
 +                  vty_out (vty, ", src %s", buf);
 +              }
 +            break;
 +          case NEXTHOP_TYPE_IPV6:
 +          case NEXTHOP_TYPE_IPV6_IFINDEX:
 +            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;
 +          default:
 +          break;
 +        }
  
 -  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)
 -      {
 +      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
 +               vty_out (vty, ", bh");
 +      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
 +               vty_out (vty, ", rej");
  
 -       /*
 -        * 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]++;
 -            }
 -           }
 -      }
 +      if (rib->type == ZEBRA_ROUTE_RIP
 +        || rib->type == ZEBRA_ROUTE_OSPF
 +        || rib->type == ZEBRA_ROUTE_ISIS
 +        || rib->type == ZEBRA_ROUTE_TABLE
 +        || rib->type == ZEBRA_ROUTE_BGP)
 +      {
 +        time_t uptime;
 +        struct tm *tm;
  
 -  vty_out (vty, "%-20s %-20s %s  (vrf %s)%s",
 -           "Route Source", "Prefix Routes", "FIB",
 -           ((rib_table_info_t *)table->info)->zvrf->name,
 -           VTY_NEWLINE);
 +        uptime = time (NULL);
 +        uptime -= rib->uptime;
 +        tm = gmtime (&uptime);
  
 -  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);
 -          }
 +        if (uptime < ONE_DAY_SECOND)
-           vty_out (vty,  ", %02d:%02d:%02d", 
++          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", 
++          vty_out (vty, ", %dd%02dh%02dm",
 +                   tm->tm_yday, tm->tm_hour, tm->tm_min);
          else
-           vty_out (vty, ", %02dw%dd%02dh", 
 -          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, "%s", 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",
 +DEFUN (show_ip_route,
 +       show_ip_route_cmd,
 +       "show ip route [json]",
         SHOW_STR
         IP_STR
 -       "IP routing table\n"
 -       "Summary of all routes\n")
 +       "IP routing table\n")
  {
 -  struct route_table *table;
 -  vrf_id_t vrf_id = VRF_DEFAULT;
 -
 -  if (argc > 0)
 -    VRF_GET_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;
 +  return do_show_ip_route (vty, VRF_DEFAULT_NAME, SAFI_UNICAST, use_json(argc, argv));
  }
  
 -ALIAS (show_ip_route_summary,
 -       show_ip_route_vrf_summary_cmd,
 -       "show ip route " VRF_CMD_STR " summary",
 -       SHOW_STR
 -       IP_STR
 -       "IP routing table\n"
 -       VRF_CMD_HELP_STR
 -       "Summary of all routes\n")
 -
 -/* 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")
 +static int
 +do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi,
 +                  u_char use_json)
  {
    struct route_table *table;
 -  vrf_id_t vrf_id = VRF_DEFAULT;
 +  struct route_node *rn;
 +  struct rib *rib;
 +  int first = 1;
 +  struct zebra_vrf *zvrf = NULL;
 +  char buf[BUFSIZ];
 +  json_object *json = NULL;
 +  json_object *json_prefix = NULL;
 +
 +  if (!(zvrf = zebra_vrf_list_lookup_by_name (vrf_name)))
 +    {
 +      if (use_json)
 +        vty_out (vty, "{}%s", VTY_NEWLINE);
 +      else
 +        vty_out (vty, "vrf %s not defined%s", vrf_name, VTY_NEWLINE);
 +      return CMD_SUCCESS;
 +    }
  
 -  if (argc > 0)
 -    VRF_GET_ID (vrf_id, argv[0]);
 +  if (zvrf->vrf_id == VRF_UNKNOWN)
 +    {
 +      if (use_json)
 +        vty_out (vty, "{}%s", VTY_NEWLINE);
 +      else
 +        vty_out (vty, "vrf %s inactive%s", vrf_name, VTY_NEWLINE);
 +      return CMD_SUCCESS;
 +    }
  
 -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
 +  table = zebra_vrf_table (AFI_IP, safi, zvrf->vrf_id);
    if (! table)
 -    return CMD_SUCCESS;
 +    {
 +      if (use_json)
 +        vty_out (vty, "{}%s", VTY_NEWLINE);
 +      return CMD_SUCCESS;
 +    }
  
 -  vty_show_ip_route_summary_prefix (vty, table);
 +  if (use_json)
 +    {
 +      json = json_object_new_object();
 +
 +      /* Show all IPv4 routes. */
 +      for (rn = route_top (table); rn; rn = route_next (rn))
 +        {
 +          RNODE_FOREACH_RIB (rn, rib)
 +            {
 +              if (!json_prefix)
 +                json_prefix = json_object_new_array();
 +              vty_show_ip_route (vty, rn, rib, json_prefix);
 +            }
 +
 +          if (json_prefix)
 +            {
 +              prefix2str (&rn->p, buf, sizeof buf);
 +              json_object_object_add(json, buf, json_prefix);
 +              json_prefix = NULL;
 +            }
 +        }
 +
-       vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
++      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
 +      json_object_free(json);
 +    }
 +  else
 +    {
 +      /* 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, NULL);
 +            }
 +        }
 +    }
  
    return CMD_SUCCESS;
  }
@@@ -1382,9 -3479,9 +1434,9 @@@ DEFUN (no_ipv6_nht_default_route
    return CMD_SUCCESS;
  }
  
 -DEFUN (show_ip_route_vrf_all_protocol,
 -       show_ip_route_vrf_all_protocol_cmd,
 -       "show ip route " VRF_ALL_CMD_STR "  " QUAGGA_IP_REDIST_STR_ZEBRA,
 +DEFUN (show_ip_route_tag,
 +       show_ip_route_tag_cmd,
-        "show ip route [vrf NAME] tag (1-65535)",
++       "show ip route [vrf NAME] tag (1-4294967295)",
         SHOW_STR
         IP_STR
         "IP routing table\n"
    struct route_table *table;
    struct route_node *rn;
    struct rib *rib;
 -  struct zebra_vrf *zvrf;
 -  vrf_iter_t iter;
    int first = 1;
-   u_short tag = 0;
 -  int vrf_header = 1;
++  route_tag_t tag = 0;
 +  vrf_id_t vrf_id = VRF_DEFAULT;
-  
 -  type = proto_redistnum (AFI_IP, argv[0]);
 -  if (type < 0)
 +  if (strmatch(argv[idx_vrf]->text, "vrf"))
      {
 -      vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
 -      return CMD_WARNING;
 +      VRF_GET_ID (vrf_id, argv[idx_name]->arg);
-       tag = atoi(argv[idx_tag]->arg);
++      tag = atol(argv[idx_tag]->arg);
      }
 -
 -  for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
 +  else
      {
 -      if ((zvrf = vrf_iter2info (iter)) == NULL ||
 -          (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
 -        continue;
 +      idx_tag -= 2;
-       tag = atoi(argv[idx_tag]->arg);
++      tag = atol(argv[idx_tag]->arg);
 +    }
  
 -      /* 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;
 -                }
 +  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
 +  if (! table)
 +    return CMD_SUCCESS;
  
 -              if (vrf_header)
 -                {
 -                  vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
 -                  vrf_header = 0;
 -                }
 -              vty_show_ip_route (vty, rn, rib, NULL);
 -            }
 -      vrf_header = 1;
 -    }
 +  /* 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, NULL);
 +      }
    return CMD_SUCCESS;
  }
 -
 -DEFUN (show_ip_route_vrf_all_addr,
 -       show_ip_route_vrf_all_addr_cmd,
 -       "show ip route " VRF_ALL_CMD_STR "  A.B.C.D",
 +
 +DEFUN (show_ip_route_prefix_longer,
 +       show_ip_route_prefix_longer_cmd,
 +       "show ip route [vrf NAME] A.B.C.D/M longer-prefixes",
         SHOW_STR
         IP_STR
         "IP routing table\n"
@@@ -1862,642 -3853,826 +1914,657 @@@ vty_show_ip_route_summary_prefix (struc
        }
      }
  
 -  if (add_cmd)
 -    static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate,
 -                    ifindex, ifname, flag, tag, distance, zvrf, &snh_label);
 -  else
 -    static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate,
 -                       ifindex, tag, distance, zvrf, &snh_label);
 -
 -  return CMD_SUCCESS;
 -}
 -
 -DEFUN (ipv6_route,
 -       ipv6_route_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, NULL, NULL, NULL);
 -}
 -
 -DEFUN (ipv6_route_tag,
 -       ipv6_route_tag_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295>",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], NULL, NULL, NULL);
 +  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);
  }
  
 -DEFUN (ipv6_route_flags,
 -       ipv6_route_flags_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
 +/* Show route summary.  */
 +DEFUN (show_ip_route_summary,
 +       show_ip_route_summary_cmd,
 +       "show ip route [vrf NAME] summary",
 +       SHOW_STR
         IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n")
 +       "IP routing table\n"
 +       VRF_CMD_HELP_STR
 +       "Summary of all routes\n")
  {
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, NULL, NULL, NULL);
 -}
 +  struct route_table *table;
 +  vrf_id_t vrf_id = VRF_DEFAULT;
  
 -DEFUN (ipv6_route_flags_tag,
 -       ipv6_route_flags_tag_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295>",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 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")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], NULL, NULL, NULL);
 -}
 +  if (strmatch(argv[3]->text, "vrf"))
 +    VRF_GET_ID (vrf_id, argv[4]->arg);
  
 -DEFUN (ipv6_route_ifname,
 -       ipv6_route_ifname_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL, NULL, NULL);
 -}
 -DEFUN (ipv6_route_ifname_tag,
 -       ipv6_route_ifname_tag_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295>",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL, NULL, NULL);
 -}
 +  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
 +  if (! table)
 +    return CMD_SUCCESS;
  
 -DEFUN (ipv6_route_ifname_flags,
 -       ipv6_route_ifname_flags_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, NULL, NULL, NULL);
 -}
 +  vty_show_ip_route_summary (vty, table);
  
 -DEFUN (ipv6_route_ifname_flags_tag,
 -       ipv6_route_ifname_flags_tag_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295>",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 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")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, NULL, NULL);
 +  return CMD_SUCCESS;
  }
  
 -DEFUN (ipv6_route_pref,
 -       ipv6_route_pref_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Distance value for this prefix\n")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, argv[2], NULL, NULL);
 -}
  
 -DEFUN (ipv6_route_pref_tag,
 -       ipv6_route_pref_tag_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255>",
 +/* Show route summary prefix.  */
 +DEFUN (show_ip_route_summary_prefix,
 +       show_ip_route_summary_prefix_cmd,
 +       "show ip route [vrf NAME] summary prefix",
 +       SHOW_STR
         IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       "Distance value for this prefix\n")
 +       "IP routing table\n"
 +       VRF_CMD_HELP_STR
 +       "Summary of all routes\n"
 +       "Prefix routes\n")
  {
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], argv[3], NULL, NULL);
 -}
 +  struct route_table *table;
 +  vrf_id_t vrf_id = VRF_DEFAULT;
  
 -DEFUN (ipv6_route_flags_pref,
 -       ipv6_route_flags_pref_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n"
 -       "Distance value for this prefix\n")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, argv[3], NULL, NULL);
 -}
 +  if (strmatch(argv[3]->text, "vrf"))
 +    VRF_GET_ID (vrf_id, argv[4]->arg);
  
 -DEFUN (ipv6_route_flags_pref_tag,
 -       ipv6_route_flags_pref_tag_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 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 prefix\n")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], NULL, NULL);
 -}
 +  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
 +  if (! table)
 +    return CMD_SUCCESS;
  
 -DEFUN (ipv6_route_ifname_pref,
 -       ipv6_route_ifname_pref_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Distance value for this prefix\n")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3], NULL, NULL);
 -}
 +  vty_show_ip_route_summary_prefix (vty, table);
  
 -DEFUN (ipv6_route_ifname_pref_tag,
 -       ipv6_route_ifname_pref_tag_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255>",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       "Distance value for this prefix\n")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], NULL, NULL);
 +  return CMD_SUCCESS;
  }
  
 -DEFUN (ipv6_route_ifname_flags_pref,
 -       ipv6_route_ifname_flags_pref_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n"
 -       "Distance value for this prefix\n")
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], NULL, NULL);
 -}
  
 -DEFUN (ipv6_route_ifname_flags_pref_tag,
 -       ipv6_route_ifname_flags_pref_tag_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> <1-255>",
 +DEFUN (show_ip_route_vrf_all,
 +       show_ip_route_vrf_all_cmd,
 +       "show ip route vrf all",
 +       SHOW_STR
         IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 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 prefix\n")
 +       "IP routing table\n"
 +       VRF_ALL_CMD_HELP_STR)
  {
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], NULL, NULL);
 -}
 +  struct route_table *table;
 +  struct route_node *rn;
 +  struct rib *rib;
 +  struct zebra_vrf *zvrf;
 +  vrf_iter_t iter;
 +  int first = 1;
 +  int vrf_header = 1;
  
 -DEFUN (no_ipv6_route,
 -       no_ipv6_route_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n")
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, NULL, NULL, NULL);
 -}
 +  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;
  
 -DEFUN (no_ipv6_route_tag,
 -       no_ipv6_route_tag_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295>",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n")
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], NULL, NULL, NULL);
 -}
 +      /* 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;
 +              }
  
 -DEFUN (no_ipv6_route_flags,
 -       no_ipv6_route_flags_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n")
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, NULL, NULL, NULL);
 +            if (vrf_header)
 +              {
 +                vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
 +                vrf_header = 0;
 +              }
 +            vty_show_ip_route (vty, rn, rib, NULL);
 +          }
 +      vrf_header  = 1;
 +    }
 +
 +  return CMD_SUCCESS;
  }
  
 -DEFUN (no_ipv6_route_flags_tag,
 -       no_ipv6_route_flags_tag_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295>",
 -       NO_STR
 +DEFUN (show_ip_route_vrf_all_tag,
 +       show_ip_route_vrf_all_tag_cmd,
-        "show ip route vrf all tag (1-65535)",
++       "show ip route vrf all tag (1-4294967295)",
 +       SHOW_STR
         IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n"
 -       "Set tag for this route\n"
 +       "IP routing table\n"
 +       VRF_ALL_CMD_HELP_STR
 +       "Show only routes with tag\n"
         "Tag value\n")
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], NULL, NULL, NULL);
 -}
 +  int idx_number = 6;
 +  struct route_table *table;
 +  struct route_node *rn;
 +  struct rib *rib;
 +  struct zebra_vrf *zvrf;
 +  vrf_iter_t iter;
 +  int first = 1;
 +  int vrf_header = 1;
-   u_short tag = 0;
++  route_tag_t tag = 0;
  
 -DEFUN (no_ipv6_route_ifname,
 -       no_ipv6_route_ifname_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n")
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL, NULL, NULL);
 -}
 +  if (argv[idx_number]->arg)
-     tag = atoi(argv[idx_number]->arg);
++    tag = atol(argv[idx_number]->arg);
  
 -DEFUN (no_ipv6_route_ifname_tag,
 -       no_ipv6_route_ifname_tag_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295>",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n")
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL, NULL, NULL);
 -}
 +  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;
  
 -DEFUN (no_ipv6_route_ifname_flags,
 -       no_ipv6_route_ifname_flags_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n")
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, NULL, NULL, NULL);
 -}
 +      /* 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;
  
 -DEFUN (no_ipv6_route_ifname_flags_tag,
 -       no_ipv6_route_ifname_flags_tag_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295>",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 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")
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, NULL, NULL);
 -}
 +            if (first)
 +              {
 +                vty_out (vty, SHOW_ROUTE_V4_HEADER);
 +                first = 0;
 +              }
  
 -DEFUN (no_ipv6_route_pref,
 -       no_ipv6_route_pref_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Distance value for this prefix\n")
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, argv[2], NULL, NULL);
 +            if (vrf_header)
 +              {
 +                vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
 +                vrf_header = 0;
 +              }
 +            vty_show_ip_route (vty, rn, rib, NULL);
 +          }
 +      vrf_header = 1;
 +    }
 +  return CMD_SUCCESS;
  }
  
 -DEFUN (no_ipv6_route_pref_tag,
 -       no_ipv6_route_pref_tag_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255>",
 -       NO_STR
 +DEFUN (show_ip_route_vrf_all_prefix_longer,
 +       show_ip_route_vrf_all_prefix_longer_cmd,
 +       "show ip route vrf all A.B.C.D/M longer-prefixes",
 +       SHOW_STR
         IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       "Distance value for this prefix\n")
 +       "IP routing table\n"
 +       VRF_ALL_CMD_HELP_STR
 +       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
 +       "Show route matching the specified Network/Mask pair only\n")
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], argv[3], NULL, NULL);
 -}
 +  int idx_ipv4_prefixlen = 5;
 +  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;
 +  int vrf_header = 1;
  
 -DEFUN (no_ipv6_route_flags_pref,
 -       no_ipv6_route_flags_pref_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n"
 -       "Distance value for this prefix\n")
 -{
 -  /* We do not care about argv[2] */
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, argv[3], NULL, NULL);
 -}
 +  ret = str2prefix (argv[idx_ipv4_prefixlen]->arg, &p);
 +  if (! ret)
 +    {
 +      vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
 +      return CMD_WARNING;
 +    }
  
 -DEFUN (no_ipv6_route_flags_pref_tag,
 -       no_ipv6_route_flags_pref_tag_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 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 prefix\n")
 -{
 -  /* We do not care about argv[2] */
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], NULL, NULL);
 -}
 +  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;
  
 -DEFUN (no_ipv6_route_ifname_pref,
 -       no_ipv6_route_ifname_pref_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Distance value for this prefix\n")
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, argv[3], NULL, NULL);
 -}
 +      /* 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;
 +                }
  
 -DEFUN (no_ipv6_route_ifname_pref_tag,
 -       no_ipv6_route_ifname_pref_tag_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255>",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       "Distance value for this prefix\n")
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], NULL, NULL);
 -}
 +              if (vrf_header)
 +                {
 +                  vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
 +                  vrf_header = 0;
 +                }
 +              vty_show_ip_route (vty, rn, rib, NULL);
 +            }
 +      vrf_header = 1;
 +    }
  
 -DEFUN (no_ipv6_route_ifname_flags_pref,
 -       no_ipv6_route_ifname_flags_pref_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n"
 -       "Distance value for this prefix\n")
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], NULL, NULL);
 +  return CMD_SUCCESS;
  }
  
 -DEFUN (no_ipv6_route_ifname_flags_pref_tag,
 -       no_ipv6_route_ifname_flags_pref_tag_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> <1-255>",
 -       NO_STR
 +DEFUN (show_ip_route_vrf_all_supernets,
 +       show_ip_route_vrf_all_supernets_cmd,
 +       "show ip route vrf all supernets-only",
 +       SHOW_STR
         IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 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 prefix\n")
 +       "IP routing table\n"
 +       VRF_ALL_CMD_HELP_STR
 +       "Show supernet entries only\n")
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], NULL, NULL);
 -}
 +  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;
 +  int vrf_header = 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;
 +                  }
 +                if (vrf_header)
 +                  {
 +                    vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
 +                    vrf_header = 0;
 +                  }
 +                vty_show_ip_route (vty, rn, rib, NULL);
 +              }
 +          }
 +      vrf_header = 1;
 +    }
  
 -DEFUN (ipv6_route_vrf,
 -       ipv6_route_vrf_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) " VRF_CMD_STR,
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, NULL, argv[2], NULL);
 +  return CMD_SUCCESS;
  }
  
 -DEFUN (ipv6_route_tag_vrf,
 -       ipv6_route_tag_vrf_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> " VRF_CMD_STR,
 +DEFUN (show_ip_route_vrf_all_protocol,
 +       show_ip_route_vrf_all_protocol_cmd,
 +       "show ip route vrf all <kernel|connected|static|rip|ospf|isis|bgp|pim|table>",
 +       SHOW_STR
         IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       VRF_CMD_HELP_STR)
 +       "IP routing table\n"
 +       VRF_ALL_CMD_HELP_STR
 +       QUAGGA_IP_REDIST_HELP_STR_ZEBRA"\n")
  {
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], NULL, argv[3], NULL);
 -}
 +  int type;
 +  struct route_table *table;
 +  struct route_node *rn;
 +  struct rib *rib;
 +  struct zebra_vrf *zvrf;
 +  vrf_iter_t iter;
 +  int first = 1;
 +  int vrf_header = 1;
  
 -DEFUN (ipv6_route_flags_vrf,
 -       ipv6_route_flags_vrf_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) " VRF_CMD_STR,
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, NULL, argv[3], NULL);
 -}
 +  type = proto_redistnum (AFI_IP, argv[6]->arg);
 +  if (type < 0)
 +    {
 +      vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
 +      return CMD_WARNING;
 +    }
  
 -DEFUN (ipv6_route_flags_tag_vrf,
 -       ipv6_route_flags_tag_vrf_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 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)
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], NULL, argv[4], NULL);
 -}
 +  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;
  
 -DEFUN (ipv6_route_ifname_vrf,
 -       ipv6_route_ifname_vrf_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE " VRF_CMD_STR,
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL, argv[3], NULL);
 -}
 -DEFUN (ipv6_route_ifname_tag_vrf,
 -       ipv6_route_ifname_tag_vrf_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> " VRF_CMD_STR,
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL, argv[4], NULL);
 -}
 +      /* 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;
 +                }
  
 -DEFUN (ipv6_route_ifname_flags_vrf,
 -       ipv6_route_ifname_flags_vrf_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) " VRF_CMD_STR,
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, NULL, argv[4], NULL);
 -}
 +              if (vrf_header)
 +                {
 +                  vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE);
 +                  vrf_header = 0;
 +                }
 +              vty_show_ip_route (vty, rn, rib, NULL);
 +            }
 +      vrf_header = 1;
 +    }
  
 -DEFUN (ipv6_route_ifname_flags_tag_vrf,
 -       ipv6_route_ifname_flags_tag_vrf_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 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)
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, argv[5], NULL);
 +  return CMD_SUCCESS;
  }
  
 -DEFUN (ipv6_route_pref_vrf,
 -       ipv6_route_pref_vrf_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> " VRF_CMD_STR,
 +DEFUN (show_ip_route_vrf_all_addr,
 +       show_ip_route_vrf_all_addr_cmd,
 +       "show ip route vrf all A.B.C.D",
 +       SHOW_STR
         IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Distance value for this prefix\n"
 -       VRF_CMD_HELP_STR)
 +       "IP routing table\n"
 +       VRF_ALL_CMD_HELP_STR
 +       "Network in the IP routing table to display\n")
  {
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, argv[2], argv[3], NULL);
 -}
 +  int idx_ipv4 = 5;
 +  int ret;
 +  struct prefix_ipv4 p;
 +  struct route_table *table;
 +  struct route_node *rn;
 +  struct zebra_vrf *zvrf;
 +  vrf_iter_t iter;
  
 -DEFUN (ipv6_route_pref_tag_vrf,
 -       ipv6_route_pref_tag_vrf_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255> " VRF_CMD_STR,
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       "Distance value for this prefix\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], argv[3], argv[4], NULL);
 -}
 +  ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p);
 +  if (ret <= 0)
 +    {
 +      vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE);
 +      return CMD_WARNING;
 +    }
  
 -DEFUN (ipv6_route_flags_pref_vrf,
 -       ipv6_route_flags_pref_vrf_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR,
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n"
 -       "Distance value for this prefix\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, argv[3], argv[4], NULL);
 -}
 +  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;
  
 -DEFUN (ipv6_route_flags_pref_tag_vrf,
 -       ipv6_route_flags_pref_tag_vrf_cmd,
 -       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 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 prefix\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], argv[5], NULL);
 -}
 +      rn = route_node_match (table, (struct prefix *) &p);
 +      if (! rn)
 +        continue;
  
 -DEFUN (ipv6_route_ifname_pref_vrf,
 -       ipv6_route_ifname_pref_vrf_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> " VRF_CMD_STR,
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Distance value for this prefix\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3], argv[4], NULL);
 +      vty_show_ip_route_detail (vty, rn, 0);
 +
 +      route_unlock_node (rn);
 +    }
 +
 +  return CMD_SUCCESS;
  }
  
 -DEFUN (ipv6_route_ifname_pref_tag_vrf,
 -       ipv6_route_ifname_pref_tag_vrf_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255> " VRF_CMD_STR,
 +DEFUN (show_ip_route_vrf_all_prefix,
 +       show_ip_route_vrf_all_prefix_cmd,
 +       "show ip route vrf all A.B.C.D/M",
 +       SHOW_STR
         IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       "Distance value for this prefix\n"
 -       VRF_CMD_HELP_STR)
 +       "IP routing table\n"
 +       VRF_ALL_CMD_HELP_STR
 +       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
  {
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], argv[5], NULL);
 -}
 +  int idx_ipv4_prefixlen = 5;
 +  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[idx_ipv4_prefixlen]->arg, &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, 0);
 +
 +      route_unlock_node (rn);
 +    }
  
 -DEFUN (ipv6_route_ifname_flags_pref_vrf,
 -       ipv6_route_ifname_flags_pref_vrf_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255> " VRF_CMD_STR,
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n"
 -       "Distance value for this prefix\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], argv[5], NULL);
 +  return CMD_SUCCESS;
  }
  
 -DEFUN (ipv6_route_ifname_flags_pref_tag_vrf,
 -       ipv6_route_ifname_flags_pref_tag_vrf_cmd,
 -       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
 +DEFUN (show_ip_route_vrf_all_summary,
 +       show_ip_route_vrf_all_summary_cmd,
 +       "show ip route vrf all summary ",
 +       SHOW_STR
         IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 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 prefix\n"
 -       VRF_CMD_HELP_STR)
 +       "IP routing table\n"
 +       VRF_ALL_CMD_HELP_STR
 +       "Summary of all routes\n")
  {
 -  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], NULL);
 -}
 +  struct zebra_vrf *zvrf;
 +  vrf_iter_t iter;
  
 -DEFUN (no_ipv6_route_vrf,
 -       no_ipv6_route_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) " VRF_CMD_STR,
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, NULL, argv[2], NULL);
 +  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 (no_ipv6_route_tag_vrf,
 -       no_ipv6_route_tag_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> " VRF_CMD_STR,
 -       NO_STR
 +DEFUN (show_ip_route_vrf_all_summary_prefix,
 +       show_ip_route_vrf_all_summary_prefix_cmd,
 +       "show ip route vrf all summary prefix",
 +       SHOW_STR
         IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Set tag for this route\n"
 -       "Tag value\n"
 -       VRF_CMD_HELP_STR)
 +       "IP routing table\n"
 +       VRF_ALL_CMD_HELP_STR
 +       "Summary of all routes\n"
 +       "Prefix routes\n")
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], NULL, argv[3], NULL);
 +  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;
  }
  
 -DEFUN (no_ipv6_route_flags_vrf,
 -       no_ipv6_route_flags_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) " VRF_CMD_STR,
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n"
 -       VRF_CMD_HELP_STR)
 +/* Write IPv4 static route configuration. */
 +static int
 +static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, NULL, argv[3], NULL);
 +  struct route_node *rn;
 +  struct static_route *si;
 +  struct route_table *stable;
 +  struct zebra_vrf *zvrf;
 +  char buf[PREFIX_STRLEN];
 +  int write =0;
 +  struct listnode *node;
 +
 +  for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf))
 +    {
 +      if ((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", cmd, prefix2str (&rn->p, buf, sizeof buf));
 +
 +            switch (si->type)
 +              {
 +              case STATIC_IPV4_GATEWAY:
 +                vty_out (vty, " %s", inet_ntoa (si->addr.ipv4));
 +                break;
 +              case STATIC_IFINDEX:
 +                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 %s", zvrf ? zvrf->name : "");
 +
 +            vty_out (vty, "%s", VTY_NEWLINE);
 +
 +            write = 1;
 +          }
 +    }
 +  return write;
  }
  
 -DEFUN (no_ipv6_route_flags_tag_vrf,
 -       no_ipv6_route_flags_tag_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 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)
 +/* General fucntion for IPv6 static route. */
- static int
++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)
++                  const char *gate_str, const char *ifname,
++                  const char *flag_str, const char *tag_str,
++                  const char *distance_str, const char *vrf_id_str,
++                  const char *label_str)
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], NULL, argv[4], NULL);
 -}
 +  int ret;
 +  u_char distance;
 +  struct prefix p;
 +  struct in6_addr *gate = NULL;
 +  struct in6_addr gate_addr;
 +  u_char type = 0;
 +  u_char flag = 0;
-   u_short tag = 0;
++  route_tag_t tag = 0;
 +  unsigned int ifindex = 0;
 +  struct interface *ifp = NULL;
 +  struct zebra_vrf *zvrf;
-   
++  struct static_nh_label snh_label;
++
 +  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);
++    tag = atol(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);
 +
 +  /* VRF id */
 +  zvrf = zebra_vrf_list_lookup_by_name (vrf_id_str);
 +
 +  if (!zvrf)
 +    {
 +      vty_out (vty, "%% vrf %s is not defined%s", vrf_id_str, VTY_NEWLINE);
 +      return CMD_WARNING;
 +    }
 +
++  /* Labels */
++  memset (&snh_label, 0, sizeof (struct static_nh_label));
++  if (label_str)
++    {
++      if (mpls_str2label (label_str, &snh_label.num_labels,
++                          snh_label.label))
++        {
++          vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE);
++          return CMD_WARNING;
++        }
++    }
++
 +  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;
-       }
++        {
++          vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
++          return CMD_WARNING;
++        }
 +      type = STATIC_IPV6_GATEWAY_IFINDEX;
 +      gate = &gate_addr;
 +      ifp = if_lookup_by_name_vrf (ifname, zvrf->vrf_id);
 +      if (!ifp)
-       {
-         vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE);
-         return CMD_WARNING;
-       }
++        {
++          vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE);
++          return CMD_WARNING;
++        }
 +      ifindex = ifp->ifindex;
 +    }
 +  else
 +    {
 +      if (ret == 1)
-       {
-         type = STATIC_IPV6_GATEWAY;
-         gate = &gate_addr;
-       }
++        {
++          type = STATIC_IPV6_GATEWAY;
++          gate = &gate_addr;
++        }
 +      else
-       {
-         type = STATIC_IFINDEX;
-         ifp = if_lookup_by_name_vrf (gate_str, zvrf->vrf_id);
-         if (!ifp)
-           {
-             vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE);
++        {
++          type = STATIC_IFINDEX;
++          ifp = if_lookup_by_name_vrf (gate_str, zvrf->vrf_id);
++          if (!ifp)
++            {
++              vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE);
 +              ifindex = IFINDEX_DELETED;
-           }
++            }
 +          else
-           ifindex = ifp->ifindex;
-         ifname = gate_str;
-       }
++            ifindex = ifp->ifindex;
++          ifname = gate_str;
++        }
 +    }
 +
 +  if (add_cmd)
-     static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate, ifindex, ifname, flag, tag, distance, zvrf);
++    static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate,
++                      ifindex, ifname, flag, tag, distance, zvrf, &snh_label);
 +  else
-     static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate, ifindex, tag, distance, zvrf);
++    static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate,
++                         ifindex, tag, distance, zvrf, &snh_label);
  
 -DEFUN (no_ipv6_route_ifname_vrf,
 -       no_ipv6_route_ifname_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE " VRF_CMD_STR,
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL, argv[3], NULL);
 +  return CMD_SUCCESS;
  }
  
 -DEFUN (no_ipv6_route_ifname_tag_vrf,
 -       no_ipv6_route_ifname_tag_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> " VRF_CMD_STR,
 -       NO_STR
 +DEFUN (ipv6_route,
 +       ipv6_route_cmd,
-        "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         IP_STR
         "Establish static routes\n"
         "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
         "IPv6 gateway interface name\n"
         "Set tag for this route\n"
         "Tag value\n"
 -       VRF_CMD_HELP_STR)
 +       "Distance value for this prefix\n"
-        VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL, argv[4], NULL);
 -}
 +  int idx_ipv6_prefixlen = 2;
 +  int idx_ipv6_ifname = 3;
 +  int idx_curr = 4;
 +  char *tag, *distance, *vrf;
  
 -DEFUN (no_ipv6_route_ifname_flags_vrf,
 -       no_ipv6_route_ifname_flags_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) " VRF_CMD_STR,
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, NULL, argv[4], NULL);
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return static_ipv6_func (vty, 1,
 +                         argv[idx_ipv6_prefixlen]->arg,
 +                         argv[idx_ipv6_ifname]->arg,
 +                         NULL, NULL,
-                          tag, distance, vrf);
++                         tag, distance, vrf, NULL);
  }
  
 -DEFUN (no_ipv6_route_ifname_flags_tag_vrf,
 -       no_ipv6_route_ifname_flags_tag_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR,
 -       NO_STR
 +DEFUN (ipv6_route_flags,
 +       ipv6_route_flags_cmd,
-        "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         IP_STR
         "Establish static routes\n"
         "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
         "IPv6 gateway interface name\n"
         "Emit an ICMP unreachable when matched\n"
         "Silently discard pkts when matched\n"
 +       "Silently discard pkts when matched\n"
         "Set tag for this route\n"
         "Tag value\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, argv[5], NULL);
 -}
 -
 -DEFUN (no_ipv6_route_pref_vrf,
 -       no_ipv6_route_pref_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> " VRF_CMD_STR,
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
         "Distance value for this prefix\n"
--       VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, argv[2], argv[3], NULL);
 +  int idx_ipv6_prefixlen = 2;
 +  int idx_ipv6_ifname = 3;
 +  int idx_reject_blackhole = 4;
 +  int idx_curr = 5;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return static_ipv6_func (vty, 1,
 +                         argv[idx_ipv6_prefixlen]->arg,
 +                         argv[idx_ipv6_ifname]->arg,
 +                         NULL,
 +                         argv[idx_reject_blackhole]->arg,
-                          tag, distance, vrf);
++                         tag, distance, vrf, NULL);
  }
  
 -DEFUN (no_ipv6_route_pref_tag_vrf,
 -       no_ipv6_route_pref_tag_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255> " VRF_CMD_STR,
 -       NO_STR
 +DEFUN (ipv6_route_ifname,
 +       ipv6_route_ifname_cmd,
-        "ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         IP_STR
         "Establish static routes\n"
         "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
         "Set tag for this route\n"
         "Tag value\n"
         "Distance value for this prefix\n"
--       VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], argv[3], argv[4], NULL);
 -}
 +  int idx_ipv6_prefixlen = 2;
 +  int idx_ipv6 = 3;
 +  int idx_interface = 4;
 +  int idx_curr = 5;
 +  char *tag, *distance, *vrf;
  
 -DEFUN (no_ipv6_route_flags_pref_vrf,
 -       no_ipv6_route_flags_pref_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR,
 -       NO_STR
 -       IP_STR
 -       "Establish static routes\n"
 -       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
 -       "IPv6 gateway address\n"
 -       "IPv6 gateway interface name\n"
 -       "Emit an ICMP unreachable when matched\n"
 -       "Silently discard pkts when matched\n"
 -       "Distance value for this prefix\n"
 -       VRF_CMD_HELP_STR)
 -{
 -  /* We do not care about argv[2] */
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, argv[3], argv[4], NULL);
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return static_ipv6_func (vty, 1,
 +                         argv[idx_ipv6_prefixlen]->arg,
 +                         argv[idx_ipv6]->arg,
 +                         argv[idx_interface]->arg,
 +                         NULL,
-                          tag, distance, vrf);
++                         tag, distance, vrf, NULL);
  }
  
 -DEFUN (no_ipv6_route_flags_pref_tag_vrf,
 -       no_ipv6_route_flags_pref_tag_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
 -       NO_STR
 +DEFUN (ipv6_route_ifname_flags,
 +       ipv6_route_ifname_flags_cmd,
-        "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <reject|blackhole> [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         IP_STR
         "Establish static routes\n"
         "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
         "Set tag for this route\n"
         "Tag value\n"
         "Distance value for this prefix\n"
--       VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  /* We do not care about argv[2] */
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], argv[5], NULL);
 +  int idx_ipv6_prefixlen = 2;
 +  int idx_ipv6 = 3;
 +  int idx_interface = 4;
 +  int idx_reject_blackhole = 5;
 +  int idx_curr = 6;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return static_ipv6_func (vty, 1,
 +                         argv[idx_ipv6_prefixlen]->arg,
 +                         argv[idx_ipv6]->arg,
 +                         argv[idx_interface]->arg,
 +                         argv[idx_reject_blackhole]->arg,
-                          tag, distance, vrf);
++                         tag, distance, vrf, NULL);
  }
  
 -DEFUN (no_ipv6_route_ifname_pref_vrf,
 -       no_ipv6_route_ifname_pref_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> " VRF_CMD_STR,
 +DEFUN (no_ipv6_route,
 +       no_ipv6_route_cmd,
-        "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         NO_STR
         IP_STR
         "Establish static routes\n"
         "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
         "IPv6 gateway address\n"
         "IPv6 gateway interface name\n"
 +       "Set tag for this route\n"
 +       "Tag value\n"
         "Distance value for this prefix\n"
--       VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, argv[3], argv[4], NULL);
 +  int idx_ipv6_prefixlen = 3;
 +  int idx_ipv6_ifname = 4;
 +  int idx_curr = 5;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return static_ipv6_func (vty, 0,
 +                         argv[idx_ipv6_prefixlen]->arg,
 +                         argv[idx_ipv6_ifname]->arg,
 +                         NULL, NULL,
-                          tag, distance, vrf);
++                         tag, distance, vrf, NULL);
  }
  
 -DEFUN (no_ipv6_route_ifname_pref_tag_vrf,
 -       no_ipv6_route_ifname_pref_tag_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255> " VRF_CMD_STR,
 +DEFUN (no_ipv6_route_flags,
 +       no_ipv6_route_flags_cmd,
-        "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         NO_STR
         IP_STR
         "Establish static routes\n"
         "Set tag for this route\n"
         "Tag value\n"
         "Distance value for this prefix\n"
--       VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], argv[5], NULL);
 +  int idx_ipv6_prefixlen = 3;
 +  int idx_ipv6_ifname = 4;
 +  int idx_reject_blackhole = 5;
 +  int idx_curr = 5;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return static_ipv6_func (vty, 0,
 +                         argv[idx_ipv6_prefixlen]->arg,
 +                         argv[idx_ipv6_ifname]->arg,
 +                         NULL,
 +                         argv[idx_reject_blackhole]->arg,
-                          tag, distance, vrf);
++                         tag, distance, vrf, NULL);
  }
  
 -DEFUN (no_ipv6_route_ifname_flags_pref_vrf,
 -       no_ipv6_route_ifname_flags_pref_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255> " VRF_CMD_STR,
 +DEFUN (no_ipv6_route_ifname,
 +       no_ipv6_route_ifname_cmd,
-        "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         NO_STR
         IP_STR
         "Establish static routes\n"
         "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
         "IPv6 gateway address\n"
         "IPv6 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 prefix\n"
--       VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], argv[5], NULL);
 +  int idx_ipv6_prefixlen = 3;
 +  int idx_ipv6 = 4;
 +  int idx_interface = 5;
 +  int idx_curr = 6;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return static_ipv6_func (vty, 0,
 +                         argv[idx_ipv6_prefixlen]->arg,
 +                         argv[idx_ipv6]->arg,
 +                         argv[idx_interface]->arg,
 +                         NULL,
-                          tag, distance, vrf);
++                         tag, distance, vrf, NULL);
  }
  
 -DEFUN (no_ipv6_route_ifname_flags_pref_tag_vrf,
 -       no_ipv6_route_ifname_flags_pref_tag_vrf_cmd,
 -       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR,
 +DEFUN (no_ipv6_route_ifname_flags,
 +       no_ipv6_route_ifname_flags_cmd,
-        "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <reject|blackhole> [tag (1-65535)] [(1-255)] [vrf NAME]",
++       "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
         NO_STR
         IP_STR
         "Establish static routes\n"
         "Set tag for this route\n"
         "Tag value\n"
         "Distance value for this prefix\n"
--       VRF_CMD_HELP_STR)
++       VRF_CMD_HELP_STR
++       "Specify labels for this route\n"
++       "One or more labels separated by '/'\n")
  {
 -  return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], NULL);
 +  int idx_ipv6_prefixlen = 3;
 +  int idx_ipv6 = 4;
 +  int idx_interface = 5;
 +  int idx_reject_blackhole = 6;
 +  int idx_curr = 7;
 +  char *tag, *distance, *vrf;
 +
 +  tag = distance = vrf = NULL;
-   zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf);
++  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
 +
 +  return static_ipv6_func (vty, 0,
 +                         argv[idx_ipv6_prefixlen]->arg,
 +                         argv[idx_ipv6]->arg,
 +                         argv[idx_interface]->arg,
 +                         argv[idx_reject_blackhole]->arg,
-                          tag, distance, vrf);
++                         tag, distance, vrf, NULL);
  }
  
  DEFUN (show_ipv6_route,
    return CMD_SUCCESS;
  }
  
 -ALIAS (show_ipv6_route,
 -       show_ipv6_route_vrf_cmd,
 -       "show ipv6 route  " VRF_CMD_STR " {json}",
 -       SHOW_STR
 -       IP_STR
 -       "IPv6 routing table\n"
 -       VRF_CMD_HELP_STR)
 -
  DEFUN (show_ipv6_route_tag,
         show_ipv6_route_tag_cmd,
-        "show ipv6 route [vrf NAME] tag (1-65535)",
 -       "show ipv6 route tag <1-4294967295>",
++       "show ipv6 route [vrf NAME] tag (1-4294967295)",
         SHOW_STR
         IP_STR
         "IPv6 routing table\n"
    struct route_node *rn;
    struct rib *rib;
    int first = 1;
-   u_short tag = 0;
+   route_tag_t tag = 0;
    vrf_id_t vrf_id = VRF_DEFAULT;
  
 -  if (argc > 1)
 +  if (strmatch(argv[idx_vrf]->text, "vrf"))
      {
 -      VRF_GET_ID (vrf_id, argv[0]);
 -      tag = atol(argv[1]);
 +      VRF_GET_ID (vrf_id, argv[idx_name]->arg);
-       tag = atoi(argv[idx_tag]->arg);
++      tag = atol(argv[idx_tag]->arg);
      }
    else
 -    tag = atol(argv[0]);
 +    {
 +      idx_tag -= 2;
-       tag = atoi(argv[idx_tag]->arg);
++      tag = atol(argv[idx_tag]->arg);
 +    }
  
    table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
    if (! table)
@@@ -3240,7 -5403,7 +3322,7 @@@ DEFUN (show_ipv6_route_vrf_all
  
  DEFUN (show_ipv6_route_vrf_all_tag,
         show_ipv6_route_vrf_all_tag_cmd,
-        "show ipv6 route vrf all tag (1-65535)",
 -       "show ipv6 route " VRF_ALL_CMD_STR " tag <1-4294967295>",
++       "show ipv6 route vrf all tag (1-4294967295)",
         SHOW_STR
         IP_STR
         "IPv6 routing table\n"
    vrf_iter_t iter;
    int first = 1;
    int vrf_header = 1;
-   u_short tag = 0;
+   route_tag_t tag = 0;
  
 -  if (argv[0])
 -    tag = atol(argv[0]);
 +  if (argv[idx_number]->arg)
-     tag = atoi(argv[idx_number]->arg);
++    tag = atol(argv[idx_number]->arg);
  
    for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
      {
@@@ -3857,12 -6122,64 +3929,11 @@@ zebra_vty_init (void
  
    /* Commands for VRF */
  
 -  install_element (CONFIG_NODE, &ip_route_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_flags_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_flags_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_flags2_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_flags2_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_mask_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_mask_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_mask_flags_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_mask_flags_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_mask_flags2_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_mask_flags2_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_flags_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_flags_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_flags2_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_flags2_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_mask_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_mask_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_mask_flags_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_mask_flags2_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_mask_flags2_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_tag_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_flags_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_flags_tag_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_flags_distance2_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_flags_tag_distance2_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_mask_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_mask_tag_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_mask_flags_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_mask_flags_tag_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_vrf_cmd);
 -  install_element (CONFIG_NODE, &ip_route_mask_flags_tag_distance2_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_tag_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_flags_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_flags_tag_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_flags_distance2_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_flags_tag_distance2_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_mask_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_mask_tag_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance2_vrf_cmd);
 +  install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
 +  install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
  
    install_element (VIEW_NODE, &show_ip_route_vrf_cmd);
-   install_element (ENABLE_NODE, &show_ip_route_vrf_cmd);
 -  install_element (VIEW_NODE, &show_ip_route_vrf_addr_cmd);
 -  install_element (VIEW_NODE, &show_ip_route_vrf_tag_cmd);
 -  install_element (VIEW_NODE, &show_ip_route_vrf_prefix_cmd);
 -  install_element (VIEW_NODE, &show_ip_route_vrf_prefix_longer_cmd);
 -  install_element (VIEW_NODE, &show_ip_route_vrf_protocol_cmd);
 -  install_element (VIEW_NODE, &show_ip_route_vrf_supernets_cmd);
 -  install_element (VIEW_NODE, &show_ip_route_vrf_summary_cmd);
 -  install_element (VIEW_NODE, &show_ip_route_vrf_summary_prefix_cmd);
++  install_element (VIEW_NODE, &show_ip_route_vrf_cmd);
  
    install_element (VIEW_NODE, &show_ip_route_vrf_all_cmd);
    install_element (VIEW_NODE, &show_ip_route_vrf_all_tag_cmd);
    install_element (VIEW_NODE, &show_ip_route_vrf_all_supernets_cmd);
    install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_cmd);
    install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd);
-   install_element (ENABLE_NODE, &show_ip_route_vrf_all_cmd);
-   install_element (ENABLE_NODE, &show_ip_route_vrf_all_tag_cmd);
-   install_element (ENABLE_NODE, &show_ip_route_vrf_all_addr_cmd);
-   install_element (ENABLE_NODE, &show_ip_route_vrf_all_prefix_cmd);
-   install_element (ENABLE_NODE, &show_ip_route_vrf_all_prefix_longer_cmd);
-   install_element (ENABLE_NODE, &show_ip_route_vrf_all_protocol_cmd);
-   install_element (ENABLE_NODE, &show_ip_route_vrf_all_supernets_cmd);
-   install_element (ENABLE_NODE, &show_ip_route_vrf_all_summary_cmd);
-   install_element (ENABLE_NODE, &show_ip_route_vrf_all_summary_prefix_cmd);
  
 -#ifdef HAVE_IPV6
    install_element (CONFIG_NODE, &ipv6_route_cmd);
    install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
    install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
    install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
    install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
    install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_tag_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_summary_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_summary_prefix_cmd);
  
    install_element (VIEW_NODE, &show_ipv6_mroute_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_mroute_cmd);
  
    /* Commands for VRF */
 -
 -  install_element (CONFIG_NODE, &ipv6_route_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_flags_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_ifname_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_ifname_flags_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_flags_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_pref_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_flags_pref_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_ifname_pref_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_pref_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_flags_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_ifname_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_ifname_flags_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_pref_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_flags_pref_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_ifname_pref_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_flags_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_pref_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_tag_vrf_cmd);
 -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_tag_vrf_cmd);
 -
 -
 -  install_element (VIEW_NODE, &show_ipv6_route_vrf_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_route_vrf_tag_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_route_vrf_summary_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_route_vrf_summary_prefix_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_route_vrf_protocol_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_route_vrf_addr_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_route_vrf_prefix_cmd);
 -  install_element (VIEW_NODE, &show_ipv6_route_vrf_prefix_longer_cmd);
 -
    install_element (VIEW_NODE, &show_ipv6_route_vrf_all_cmd);
    install_element (VIEW_NODE, &show_ipv6_route_vrf_all_tag_cmd);
    install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_cmd);
    install_element (VIEW_NODE, &show_ipv6_route_vrf_all_addr_cmd);
    install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_cmd);
    install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_longer_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_tag_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_protocol_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_addr_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_prefix_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_prefix_longer_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_summary_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_summary_prefix_cmd);
  
 -  install_element (VIEW_NODE, &show_ipv6_mroute_vrf_cmd);
 -
    install_element (VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
-   install_element (ENABLE_NODE, &show_ipv6_mroute_vrf_all_cmd);
 -#endif /* HAVE_IPV6 */
  }
diff --cc zebra/zserv.c
index 98908fb67e07251f4e92e170fc6507229a62707d,da52f93a284e1533a25a53d4575572af389f71eb..a0f46aadc933cf1a9d216266c99b53436ab2af36
@@@ -713,27 -714,30 +714,30 @@@ zsend_redistribute_route (int cmd, stru
            stream_putc (s, 1);
            stream_putl (s, nexthop->ifindex);
  
 -          break;
+         /* ldpd needs all nexthops */
+         if (client->proto != ZEBRA_ROUTE_LDP)
 +          break;
          }
      }
  
-   /* Metric */
-   if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD || cmd == ZEBRA_REDISTRIBUTE_IPV6_ADD)
-     {
+   /* Distance */
 -  SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
 -  stream_putc (s, rib->distance);
 +      SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
 +      stream_putc (s, rib->distance);
+   /* Metric */
 -  SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
 -  stream_putl (s, rib->metric);
 +      SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
 +      stream_putl (s, rib->metric);
  
-       /* tag */
+   /* Tag */
 -  if (rib->tag)
 -    {
 -      SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG);
 +      if (rib->tag)
 +        {
 +          SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG);
-           stream_putw(s, rib->tag);
+       stream_putl(s, rib->tag);
 -    }
 +        }
+   /* MTU */
 -  SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU);
 -  stream_putl (s, rib->mtu);
 +      SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU);
 +      stream_putl (s, rib->mtu);
-     }
  
    /* write real message flags value */
    stream_putc_at (s, messmark, zapi_flags);
diff --cc zebra/zserv.h
Simple merge