]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_route.c
redhat: Fix missing packages in requirements section of README
[mirror_frr.git] / bgpd / bgp_route.c
index 1b17dc36b5bcb5fe9a232f0936c479c8da9daa41..b19fe96376b4b2e1cd1189aa0dc44d7230f7870d 100644 (file)
@@ -27,7 +27,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "command.h"
 #include "stream.h"
 #include "filter.h"
-#include "str.h"
 #include "log.h"
 #include "routemap.h"
 #include "buffer.h"
@@ -62,6 +61,12 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #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[];
@@ -77,7 +82,7 @@ bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct prefix
   if (!table)
     return NULL;
   
-  if (safi == SAFI_MPLS_VPN)
+  if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
     {
       prn = bgp_node_get (table, (struct prefix *) prd);
 
@@ -90,7 +95,7 @@ bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct prefix
 
   rn = bgp_node_get (table, p);
 
-  if (safi == SAFI_MPLS_VPN)
+  if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
     rn->prn = prn;
 
   return rn;
@@ -132,6 +137,13 @@ bgp_info_extra_get (struct bgp_info *ri)
   return ri->extra;
 }
 
+/* Allocate new bgp info structure. */
+struct bgp_info *
+bgp_info_new (void)
+{
+  return XCALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
+}
+
 /* Free bgp route information. */
 static void
 bgp_info_free (struct bgp_info *binfo)
@@ -228,7 +240,7 @@ bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri)
 /* undo the effects of a previous call to bgp_info_delete; typically
    called when a route is deleted and then quickly re-added before the
    deletion has been processed */
-static void
+void
 bgp_info_restore (struct bgp_node *rn, struct bgp_info *ri)
 {
   bgp_info_unset_flag (rn, ri, BGP_INFO_REMOVED);
@@ -332,7 +344,7 @@ bgp_info_path_with_addpath_rx_str (struct bgp_info *ri, char *buf)
 static int
 bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
              int *paths_eq, struct bgp_maxpaths_cfg *mpath_cfg, int debug,
-              char *pfx_buf)
+              const char *pfx_buf)
 {
   struct attr *newattr, *existattr;
   struct attr_extra *newattre, *existattre;
@@ -376,7 +388,11 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
     }
 
   if (debug)
-    bgp_info_path_with_addpath_rx_str (exist, exist_buf);
+    {
+      bgp_info_path_with_addpath_rx_str (exist, exist_buf);
+      zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
+                 pfx_buf, new_buf, new->flags, exist_buf, exist->flags);
+    }
 
   newattr = new->attr;
   existattr = exist->attr;
@@ -615,8 +631,9 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
     {
       if (peer_sort (new->peer) == BGP_PEER_IBGP
          && peer_sort (exist->peer) == BGP_PEER_IBGP
-         && CHECK_FLAG (mpath_cfg->ibgp_flags,
-                        BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))
+         && (mpath_cfg == NULL ||
+              CHECK_FLAG (mpath_cfg->ibgp_flags,
+                          BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN)))
        {
          newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
          existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
@@ -705,6 +722,15 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
        * TODO: If unequal cost ibgp multipath is enabled we can
        * mark the paths as equal here instead of returning
        */
+      if (debug)
+        {
+          if (ret == 1)
+            zlog_debug("%s: %s wins over %s after IGP metric comparison",
+                       pfx_buf, new_buf, exist_buf);
+          else
+            zlog_debug("%s: %s loses to %s after IGP metric comparison",
+                       pfx_buf, new_buf, exist_buf);
+        }
       return ret;
     }
 
@@ -834,6 +860,30 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
   return 1;
 }
 
+/* Compare two bgp route entity.  Return -1 if new is preferred, 1 if exist
+ * is preferred, or 0 if they are the same (usually will only occur if
+ * multipath is enabled 
+ * This version is compatible with */
+int
+bgp_info_cmp_compatible (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
+                         afi_t afi, safi_t safi)
+{
+  int paths_eq;
+  int ret;
+  ret = bgp_info_cmp (bgp, new, exist, &paths_eq, NULL, 0, __func__);
+
+  if (paths_eq)
+    ret = 0;
+  else 
+    {
+      if (ret == 1)
+        ret = -1;
+      else 
+        ret = 1;
+    }
+  return ret;
+}
+
 static enum filter_type
 bgp_input_filter (struct peer *peer, struct prefix *p, struct attr *attr,
                  afi_t afi, safi_t safi)
@@ -967,8 +1017,8 @@ bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
   filter = &peer->filter[afi][safi];
 
   /* Apply default weight value. */
-  if (peer->weight)
-    (bgp_attr_extra_get (attr))->weight = peer->weight;
+  if (peer->weight[afi][safi])
+    (bgp_attr_extra_get (attr))->weight = peer->weight[afi][safi];
 
   if (rmap_name)
     {
@@ -1024,8 +1074,8 @@ bgp_output_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
   filter = &peer->filter[afi][safi];
 
   /* Apply default weight value. */
-  if (peer->weight)
-    (bgp_attr_extra_get (attr))->weight = peer->weight;
+  if (peer->weight[afi][safi])
+    (bgp_attr_extra_get (attr))->weight = peer->weight[afi][safi];
 
   if (rmap_name)
     {
@@ -1146,6 +1196,7 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
   int reflect;
   afi_t afi;
   safi_t safi;
+  int samepeer_safe = 0;       /* for synthetic mplsvpns routes */
 
   if (DISABLE_BGP_ANNOUNCE)
     return 0;
@@ -1162,6 +1213,22 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
   bgp = SUBGRP_INST(subgrp);
   riattr = bgp_info_mpath_count (ri) ? bgp_info_mpath_attr (ri) : ri->attr;
 
+#if ENABLE_BGP_VNC
+  if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN) &&
+      ((ri->type == ZEBRA_ROUTE_BGP_DIRECT) ||
+       (ri->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
+
+    /*
+     * direct and direct_ext type routes originate internally even
+     * though they can have peer pointers that reference other systems
+     */
+    char    buf[BUFSIZ];
+    prefix2str(p, buf, BUFSIZ);
+    zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__, buf);
+    samepeer_safe = 1;
+  }
+#endif
+
   /* With addpath we may be asked to TX all kinds of paths so make sure
    * ri is valid */
   if (!CHECK_FLAG (ri->flags, BGP_INFO_VALID) ||
@@ -1298,7 +1365,7 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
     reflect = 0;
 
   /* IBGP reflection check. */
-  if (reflect)
+  if (reflect && !samepeer_safe)
     {
       /* A route from a Client peer. */
       if (CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
@@ -1367,13 +1434,19 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
     SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
 
 #ifdef HAVE_IPV6
+#define NEXTHOP_IS_V6 (\
+    (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
+     (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
+    ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
+     attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
+
   /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
    * the peer (group) is configured to receive link-local nexthop unchanged
    * and it is available in the prefix OR we're not reflecting the route and
    * the peer (group) to whom we're going to announce is on a shared network
    * and this is either a self-originated route or the peer is EBGP.
    */
-  if (p->family == AF_INET6 || peer_cap_enhe(peer))
+  if (NEXTHOP_IS_V6)
     {
       attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
       if ((CHECK_FLAG (peer->af_flags[afi][safi],
@@ -1520,17 +1593,6 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn,
   char pfx_buf[PREFIX2STR_BUFFER];
   char path_buf[PATH_ADDPATH_STR_BUFFER];
 
-  result->old = result->new = NULL;
-  
-  if (rn->info == NULL)
-    {
-      char buf[PREFIX2STR_BUFFER];
-      zlog_warn ("%s: Called for route_node %s with no routing entries!",
-                 __func__,
-                 prefix2str (&(bgp_node_to_rnode (rn)->p), buf, sizeof(buf)));
-      return;
-    }
-  
   bgp_mp_list_init (&mp_list);
   do_mpath = (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
 
@@ -1595,7 +1657,7 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn,
             {
               bgp_info_path_with_addpath_rx_str (new_select, path_buf);
               zlog_debug("%s: %s is the bestpath from AS %d",
-                         pfx_buf, path_buf, aspath_get_firstas(new_select->attr->aspath));
+                         pfx_buf, path_buf, aspath_get_first_as(new_select->attr->aspath));
             }
         }
     }
@@ -1644,14 +1706,19 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn,
   /* Now that we know which path is the bestpath see if any of the other paths
    * qualify as multipaths
    */
-  if (do_mpath && new_select)
+  if (debug)
     {
-      if (debug)
-        {
-          bgp_info_path_with_addpath_rx_str (new_select, path_buf);
-          zlog_debug("%s: %s is the bestpath, now find multipaths", pfx_buf, path_buf);
-        }
+      if (new_select)
+        bgp_info_path_with_addpath_rx_str (new_select, path_buf);
+      else
+        sprintf (path_buf, "NONE");
+      zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
+                 pfx_buf, path_buf,
+                 old_select ? old_select->peer->host : "NONE");
+    }
 
+  if (do_mpath && new_select)
+    {
       for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1); ri = nextri)
         {
 
@@ -1663,7 +1730,7 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn,
               if (debug)
                 zlog_debug("%s: %s is the bestpath, add to the multipath list",
                            pfx_buf, path_buf);
-             bgp_mp_list_add (&mp_list, ri);
+              bgp_mp_list_add (&mp_list, ri);
               continue;
             }
 
@@ -1734,6 +1801,7 @@ subgroup_process_announce_selected (struct update_subgroup *subgrp,
                              PEER_STATUS_ORF_WAIT_REFRESH))
     return 0;
 
+  memset(&extra, 0, sizeof(struct attr_extra));
   /* It's initialized in bgp_announce_check() */
   attr.extra = &extra;
 
@@ -1755,6 +1823,57 @@ subgroup_process_announce_selected (struct update_subgroup *subgrp,
   return 0;
 }
 
+/*
+ * Clear IGP changed flag and attribute changed flag for a route (all paths).
+ * This is called at the end of route processing.
+ */
+static void
+bgp_zebra_clear_route_change_flags (struct bgp_node *rn)
+{
+  struct bgp_info *ri;
+
+  for (ri = rn->info; ri; ri = ri->next)
+    {
+       if (BGP_INFO_HOLDDOWN (ri))
+          continue;
+        UNSET_FLAG (ri->flags, BGP_INFO_IGP_CHANGED);
+        UNSET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
+    }
+}
+
+/*
+ * Has the route changed from the RIB's perspective? This is invoked only
+ * if the route selection returns the same best route as earlier - to
+ * determine if we need to update zebra or not.
+ */
+static int
+bgp_zebra_has_route_changed (struct bgp_node *rn, struct bgp_info *selected)
+{
+  struct bgp_info *mpinfo;
+
+  /* If this is multipath, check all selected paths for any nexthop change or
+   * attribute change. Some attribute changes (e.g., community) aren't of
+   * relevance to the RIB, but we'll update zebra to ensure we handle the
+   * case of BGP nexthop change. This is the behavior when the best path has
+   * an attribute change anyway.
+   */
+  if (CHECK_FLAG (selected->flags, BGP_INFO_IGP_CHANGED) ||
+      CHECK_FLAG (selected->flags, BGP_INFO_MULTIPATH_CHG))
+    return 1;
+
+  /* If this is multipath, check all selected paths for any nexthop change */
+  for (mpinfo = bgp_info_mpath_first (selected); mpinfo;
+       mpinfo = bgp_info_mpath_next (mpinfo))
+    {
+      if (CHECK_FLAG (mpinfo->flags, BGP_INFO_IGP_CHANGED)
+          || CHECK_FLAG (mpinfo->flags, BGP_INFO_ATTR_CHANGED))
+        return 1;
+    }
+
+  /* Nothing has changed from the RIB's perspective. */
+  return 0;
+}
+
 struct bgp_process_queue
 {
   struct bgp *bgp;
@@ -1805,11 +1924,16 @@ bgp_process_main (struct work_queue *wq, void *data)
       !CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED) &&
       !bgp->addpath_tx_used[afi][safi])
     {
-      if (CHECK_FLAG (old_select->flags, BGP_INFO_IGP_CHANGED) ||
-          CHECK_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG))
-        bgp_zebra_announce (p, old_select, bgp, afi, safi);
-          
+      if (bgp_zebra_has_route_changed (rn, old_select))
+        {
+#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);
       return WQ_SUCCESS;
     }
@@ -1840,6 +1964,21 @@ bgp_process_main (struct work_queue *wq, void *data)
       UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
     }
 
+#if ENABLE_BGP_VNC
+  if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
+    if (old_select != new_select) {
+      if (old_select) {
+        vnc_import_bgp_exterior_del_route(bgp, p, old_select);
+        vnc_import_bgp_del_route(bgp, p, old_select);
+      }
+      if (new_select) {
+        vnc_import_bgp_exterior_add_route(bgp, p, new_select);
+        vnc_import_bgp_add_route(bgp, p, new_select);
+      }
+    }
+  }
+#endif
+
   group_announce_route(bgp, afi, safi, rn, new_select);
 
   /* FIB update. */
@@ -1862,7 +2001,10 @@ bgp_process_main (struct work_queue *wq, void *data)
            bgp_zebra_withdraw (p, old_select, safi);
        }
     }
-    
+
+  /* Clear any route change flags. */
+  bgp_zebra_clear_route_change_flags (rn);
+
   /* Reap old select bgp_info, if it has been removed */
   if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
     bgp_info_reap (rn, old_select);
@@ -1919,21 +2061,8 @@ bgp_process (struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
   if (CHECK_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED))
     return;
 
-  if (rn->info == NULL)
-    {
-      /* XXX: Perhaps remove before next release, after we've flushed out
-       * any obvious cases
-       */
-      assert (rn->info != NULL);
-      char buf[PREFIX2STR_BUFFER];
-      zlog_warn ("%s: Called for route_node %s with no routing entries!",
-                 __func__,
-                 prefix2str (&(bgp_node_to_rnode (rn)->p), buf, sizeof(buf)));
-      return;
-    }
-  
   if (bm->process_main_queue == NULL)
-    bgp_process_queue_init ();
+    return;
 
   pqnode = XCALLOC (MTYPE_BGP_PROCESS_QUEUE, 
                     sizeof (struct bgp_process_queue));
@@ -1958,7 +2087,7 @@ bgp_add_eoiu_mark (struct bgp *bgp)
   struct bgp_process_queue *pqnode;
 
   if (bm->process_main_queue == NULL)
-    bgp_process_queue_init ();
+    return;
 
   pqnode = XCALLOC (MTYPE_BGP_PROCESS_QUEUE,
                     sizeof (struct bgp_process_queue));
@@ -2083,7 +2212,7 @@ bgp_rib_remove (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
 
 static void
 bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
-                 afi_t afi, safi_t safi)
+                 afi_t afi, safi_t safi, struct prefix_rd *prd)
 {
   int status = BGP_DAMP_NONE;
 
@@ -2098,7 +2227,33 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
         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);
 }
 
@@ -2126,6 +2281,8 @@ bgp_info_addpath_rx_str(u_int32_t addpath_id, char *buf)
 {
   if (addpath_id)
     sprintf(buf, " with addpath ID %d", addpath_id);
+  else
+    buf[0] = '\0';
 }
 
 
@@ -2167,6 +2324,7 @@ bgp_update_martian_nexthop (struct bgp *bgp, afi_t afi, safi_t safi, struct attr
 #ifdef HAVE_IPV6
         case BGP_ATTR_NHLEN_IPV6_GLOBAL:
         case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
+        case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
           ret = (IN6_IS_ADDR_UNSPECIFIED(&attre->mp_nexthop_global) ||
                  IN6_IS_ADDR_LOOPBACK(&attre->mp_nexthop_global)    ||
                  IN6_IS_ADDR_MULTICAST(&attre->mp_nexthop_global));
@@ -2201,6 +2359,13 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
   char buf[SU_ADDRSTRLEN];
   char buf2[30];
   int connected = 0;
+  int do_loop_check = 1;
+#if ENABLE_BGP_VNC
+  int vnc_implicit_withdraw = 0;
+#endif
+
+  memset (&new_attr, 0, sizeof(struct attr));
+  memset (&new_extra, 0, sizeof(struct attr_extra));
 
   bgp = peer->bgp;
   rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
@@ -2230,14 +2395,23 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
        }
     }
 
+  /* If the peer is configured for "allowas-in origin" and the last ASN in the
+   * as-path is our ASN then we do not need to call aspath_loop_check
+   */
+  if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
+      if (aspath_get_last_as(attr->aspath) == bgp->as)
+        do_loop_check = 0;
+
   /* AS path loop check. */
-  if (aspath_loop_check (attr->aspath, bgp->as) > peer->allowas_in[afi][safi]
-      || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
-         && aspath_loop_check(attr->aspath, bgp->confed_id)
-         > peer->allowas_in[afi][safi]))
+  if (do_loop_check)
     {
-      reason = "as-path contains our own AS;";
-      goto filtered;
+      if (aspath_loop_check (attr->aspath, bgp->as) > peer->allowas_in[afi][safi]
+          || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
+              && aspath_loop_check(attr->aspath, bgp->confed_id) > peer->allowas_in[afi][safi]))
+        {
+          reason = "as-path contains our own AS;";
+          goto filtered;
+        }
     }
 
   /* Route reflector originator ID check.  */
@@ -2390,6 +2564,35 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
          if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
            bgp_damp_withdraw (ri, rn, afi, safi, 1);  
        }
+#if ENABLE_BGP_VNC
+    if (safi == SAFI_MPLS_VPN) {
+       struct bgp_node         *prn = NULL;
+       struct bgp_table        *table = NULL;
+
+       prn = bgp_node_get(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(
+               bgp,
+               prd,
+               table,
+               p,
+               ri);
+       }
+       bgp_unlock_node(prn);
+    }
+    if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
+        if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) {
+           /*
+            * Implicit withdraw case.
+            */
+           ++vnc_implicit_withdraw;
+           vnc_import_bgp_del_route(bgp, p, ri);
+           vnc_import_bgp_exterior_del_route(bgp, p, ri);
+       }
+    }
+#endif
        
       /* Update to new attribute.  */
       bgp_attr_unintern (&ri->attr);
@@ -2399,6 +2602,25 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
       if (safi == SAFI_MPLS_VPN)
         memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
 
+#if ENABLE_BGP_VNC
+      if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) 
+        {
+          if (vnc_implicit_withdraw) 
+            {
+              /*
+               * Add back the route with its new attributes (e.g., nexthop).
+               * The route is still selected, until the route selection
+               * queued by bgp_process actually runs. We have to make this
+               * update to the VNC side immediately to avoid racing against
+               * configuration changes (e.g., route-map changes) which
+               * trigger re-importation of the entire RIB.
+               */
+              vnc_import_bgp_add_route(bgp, p, ri);
+              vnc_import_bgp_exterior_add_route(bgp, p, ri);
+            }
+        }
+#endif
+
       /* Update bgp route dampening information.  */
       if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
          && peer->sort == BGP_PEER_EBGP)
@@ -2438,12 +2660,49 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
       else
        bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
 
+#if ENABLE_BGP_VNC
+      if (safi == SAFI_MPLS_VPN) 
+        {
+          struct bgp_node              *prn = NULL;
+          struct bgp_table     *table = NULL;
+
+          prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *) prd);
+          if (prn->info) 
+            {
+              table = (struct bgp_table *)(prn->info);
+
+              vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
+               bgp,
+                    prd,
+                    table,
+                    p,
+                    ri);
+            }
+          bgp_unlock_node(prn);
+        }
+#endif
+
       /* Process change. */
       bgp_aggregate_increment (bgp, p, ri, afi, safi);
 
       bgp_process (bgp, rn, afi, safi);
       bgp_unlock_node (rn);
 
+#if ENABLE_BGP_VNC
+  if (SAFI_MPLS_VPN == safi)
+    {
+      uint32_t    label = decode_label(tag);
+
+      rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
+        &label);
+    }
+  if (SAFI_ENCAP == safi)
+    {
+      rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
+        NULL);
+    }
+#endif
+
       return 0;
     } // End of implicit withdraw
 
@@ -2508,6 +2767,28 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
   /* route_node_get lock */
   bgp_unlock_node (rn);
 
+#if ENABLE_BGP_VNC
+  if (safi == SAFI_MPLS_VPN) 
+    {
+      struct bgp_node          *prn = NULL;
+      struct bgp_table *table = NULL;
+    
+      prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *) prd);
+      if (prn->info) 
+        {
+          table = (struct bgp_table *)(prn->info);
+      
+          vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
+                             bgp,
+                             prd,
+                             table,
+                             p,
+                             new);
+        }
+      bgp_unlock_node(prn);
+    }
+#endif
+
   /* If maximum prefix count is configured and current prefix
      count exeed it. */
   if (bgp_maximum_prefix_overflow (peer, afi, safi, 0))
@@ -2516,6 +2797,21 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
   /* Process change. */
   bgp_process (bgp, rn, afi, safi);
 
+#if ENABLE_BGP_VNC
+  if (SAFI_MPLS_VPN == safi)
+    {
+      uint32_t    label = decode_label(tag);
+
+      rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
+        &label);
+    }
+  if (SAFI_ENCAP == safi)
+    {
+      rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
+        NULL);
+    }
+#endif
+
   return 0;
 
   /* This BGP update is filtered.  Log the reason then update BGP
@@ -2541,6 +2837,17 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
 
   bgp_unlock_node (rn);
 
+#if ENABLE_BGP_VNC
+  /*
+   * Filtered update is treated as an implicit withdrawal (see bgp_rib_remove()
+   * a few lines above)
+   */
+  if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi))
+    {
+      rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type, 0);
+    }
+#endif
+
   return 0;
 }
 
@@ -2555,16 +2862,39 @@ bgp_withdraw (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
   struct bgp_node *rn;
   struct bgp_info *ri;
 
+#if ENABLE_BGP_VNC
+  if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi))
+    {
+      rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type, 0);
+    }
+#endif
+
   bgp = peer->bgp;
 
   /* Lookup node. */
   rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
 
   /* If peer is soft reconfiguration enabled.  Record input packet for
-     further calculation. */
+   * further calculation.
+   *
+   * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
+   * routes that are filtered.  This tanks out Quagga RS pretty badly due to
+   * the iteration over all RS clients.
+   * Since we need to remove the entry from adj_in anyway, do that first and
+   * if there was no entry, we don't need to do anything more.
+   */
   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
       && peer != bgp->peer_self)
-    bgp_adj_in_unset (rn, peer, addpath_id);
+    if (!bgp_adj_in_unset (rn, peer, addpath_id))
+      {
+        if (bgp_debug_update (peer, p, NULL, 1))
+          zlog_debug ("%s withdrawing route %s/%d "
+                     "not in adj-in", peer->host,
+                     inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+                     p->prefixlen);
+        bgp_unlock_node (rn);
+        return 0;
+      }
 
   /* Lookup withdrawn route. */
   for (ri = rn->info; ri; ri = ri->next)
@@ -2584,7 +2914,7 @@ bgp_withdraw (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
 
   /* Withdraw specified route from routing table. */
   if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
-    bgp_rib_withdraw (rn, ri, peer, afi, safi);
+    bgp_rib_withdraw (rn, ri, peer, afi, safi, prd);
   else if (bgp_debug_update(peer, p, NULL, 1))
     zlog_debug ("%s Can't find the route %s/%d", peer->host,
                inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
@@ -2629,7 +2959,6 @@ bgp_announce_route_timer_expired (struct thread *t)
   struct peer_af *paf;
   struct peer *peer;
 
-
   paf = THREAD_ARG (t);
   peer = paf->peer;
 
@@ -2743,7 +3072,7 @@ bgp_soft_reconfig_in (struct peer *peer, afi_t afi, safi_t safi)
   if (peer->status != Established)
     return;
 
-  if (safi != SAFI_MPLS_VPN)
+  if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP))
     bgp_soft_reconfig_table (peer, afi, safi, NULL, NULL);
   else
     for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
@@ -2846,7 +3175,7 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
                        struct bgp_table *table)
 {
   struct bgp_node *rn;
-  
+  int force = bm->process_main_queue ? 0 : 1;
   
   if (! table)
     table = peer->bgp->rib[afi][safi];
@@ -2857,7 +3186,7 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
   
   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
     {
-      struct bgp_info *ri;
+      struct bgp_info *ri, *next;
       struct bgp_adj_in *ain;
       struct bgp_adj_in *ain_next;
 
@@ -2909,20 +3238,28 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
           ain = ain_next;
         }
 
-      for (ri = rn->info; ri; ri = ri->next)
-        if (ri->peer == peer)
-          {
-            struct bgp_clear_node_queue *cnq;
-
-            /* both unlocked in bgp_clear_node_queue_del */
-            bgp_table_lock (bgp_node_table (rn));
-            bgp_lock_node (rn);
-            cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE,
-                           sizeof (struct bgp_clear_node_queue));
-            cnq->rn = rn;
-            work_queue_add (peer->clear_node_queue, cnq);
-            break;
-          }
+      for (ri = rn->info; ri; ri = next)
+       {
+         next = ri->next;
+         if (ri->peer != peer)
+           continue;
+
+         if (force)
+           bgp_info_reap (rn, ri);
+         else
+           {
+             struct bgp_clear_node_queue *cnq;
+
+             /* both unlocked in bgp_clear_node_queue_del */
+             bgp_table_lock (bgp_node_table (rn));
+             bgp_lock_node (rn);
+             cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE,
+                            sizeof (struct bgp_clear_node_queue));
+             cnq->rn = rn;
+             work_queue_add (peer->clear_node_queue, cnq);
+             break;
+           }
+       }
     }
   return;
 }
@@ -2956,7 +3293,7 @@ bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi)
   if (!peer->clear_node_queue->thread)
     peer_lock (peer);
 
-  if (safi != SAFI_MPLS_VPN)
+  if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP)
     bgp_clear_route_table (peer, afi, safi, NULL);
   else
     for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
@@ -2979,6 +3316,10 @@ bgp_clear_route_all (struct peer *peer)
   for (afi = AFI_IP; afi < AFI_MAX; afi++)
     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
       bgp_clear_route (peer, afi, safi);
+
+#if ENABLE_BGP_VNC
+  rfapiProcessPeerDown(peer);
+#endif
 }
 
 void
@@ -3034,37 +3375,70 @@ bgp_clear_stale_route (struct peer *peer, afi_t afi, safi_t safi)
     }
 }
 
-/* Delete all kernel routes. */
-void
-bgp_cleanup_routes (void)
+static void
+bgp_cleanup_table(struct bgp_table *table, safi_t safi)
 {
-  struct bgp *bgp;
-  struct listnode *node, *nnode;
   struct bgp_node *rn;
-  struct bgp_table *table;
   struct bgp_info *ri;
+  struct bgp_info *next;
 
-  for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
+  for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+    for (ri = rn->info; ri; ri = next)
+      {
+        next = ri->next;
+        if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
+            && ri->type == ZEBRA_ROUTE_BGP
+            && (ri->sub_type == BGP_ROUTE_NORMAL ||
+                ri->sub_type == BGP_ROUTE_AGGREGATE))
+          {
+#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);
+           bgp_info_reap (rn, ri);
+          }
+      }
+}
+
+/* Delete all kernel routes. */
+void
+bgp_cleanup_routes (struct bgp *bgp)
+{
+  afi_t afi;
+
+  for (afi = AFI_IP; afi < AFI_MAX; ++afi)
     {
-      table = bgp->rib[AFI_IP][SAFI_UNICAST];
+      struct bgp_node *rn;
 
-      for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
-       for (ri = rn->info; ri; ri = ri->next)
-         if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
-             && ri->type == ZEBRA_ROUTE_BGP 
-             && (ri->sub_type == BGP_ROUTE_NORMAL ||
-                 ri->sub_type == BGP_ROUTE_AGGREGATE))
-           bgp_zebra_withdraw (&rn->p, ri,SAFI_UNICAST);
+      bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST);
 
-      table = bgp->rib[AFI_IP6][SAFI_UNICAST];
+      /*
+       * VPN and ENCAP tables are two-level (RD is top level)
+       */
+      for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn;
+          rn = bgp_route_next (rn))
+       {
+         if (rn->info)
+           {
+             bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_MPLS_VPN);
+             bgp_table_finish ((struct bgp_table **)&(rn->info));
+             rn->info = NULL;
+             bgp_unlock_node(rn);
+           }
+       }
 
-      for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
-       for (ri = rn->info; ri; ri = ri->next)
-         if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
-             && ri->type == ZEBRA_ROUTE_BGP 
-             && (ri->sub_type == BGP_ROUTE_NORMAL ||
-                 ri->sub_type == BGP_ROUTE_AGGREGATE))
-           bgp_zebra_withdraw (&rn->p, ri,SAFI_UNICAST);
+      for (rn = bgp_table_top(bgp->rib[afi][SAFI_ENCAP]); rn;
+          rn = bgp_route_next (rn))
+       {
+         if (rn->info)
+           {
+             bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_ENCAP);
+             bgp_table_finish ((struct bgp_table **)&(rn->info));
+             rn->info = NULL;
+             bgp_unlock_node(rn);
+           }
+       }
     }
 }
 
@@ -3087,7 +3461,8 @@ bgp_addpath_encode_rx (struct peer *peer, afi_t afi, safi_t safi)
 /* Parse NLRI stream.  Withdraw NLRI is recognized by NULL attr
    value. */
 int
-bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
+bgp_nlri_parse_ip (struct peer *peer, struct attr *attr,
+                   struct bgp_nlri *packet)
 {
   u_char *pnt;
   u_char *lim;
@@ -3110,6 +3485,9 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
   addpath_id = 0;
   addpath_encoded = bgp_addpath_encode_rx (peer, afi, safi);
 
+  /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
+     syntactic validity.  If the field is syntactically incorrect,
+     then the Error Subcode is set to Invalid Network Field. */
   for (; pnt < lim; pnt += psize)
     {
       /* Clear prefix structure. */
@@ -3128,20 +3506,35 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
 
       /* Fetch prefix length. */
       p.prefixlen = *pnt++;
+      /* afi/safi validity already verified by caller, bgp_update_receive */
       p.family = afi2family (afi);
-      
-      /* Already checked in nlri_sanity_check().  We do double check
-         here. */
-      if ((afi == AFI_IP && p.prefixlen > 32)
-         || (afi == AFI_IP6 && p.prefixlen > 128))
-       return -1;
+
+      /* Prefix length check. */
+      if (p.prefixlen > prefix_blen (&p) * 8)
+        {
+          zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
+                   peer->host, p.prefixlen, packet->afi);
+          return -1;
+        }
 
       /* Packet size overflow check. */
       psize = PSIZE (p.prefixlen);
 
       /* When packet overflow occur return immediately. */
       if (pnt + psize > lim)
-       return -1;
+        {
+          zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
+                   peer->host, p.prefixlen);
+          return -1;
+        }
+
+      /* Defensive coding, double-check the psize fits in a struct prefix */
+      if (psize > (ssize_t) sizeof(p.u))
+        {
+          zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
+                   peer->host, p.prefixlen, sizeof(p.u));
+          return -1;
+        }
 
       /* Fetch prefix from NLRI packet. */
       memcpy (&p.u.prefix, pnt, psize);
@@ -3151,17 +3544,15 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
        {
          if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))
            {
-            /* 
-             * From draft-ietf-idr-bgp4-22, Section 6.3: 
-             * If a BGP router receives an UPDATE message with a
-             * semantically incorrect NLRI field, in which a prefix is
-             * semantically incorrect (eg. an unexpected multicast IP
-             * address), it should ignore the prefix.
-             */
-             zlog_err ("IPv4 unicast NLRI is multicast address %s",
-                       inet_ntoa (p.u.prefix4));
-
-             return -1;
+             /* From RFC4271 Section 6.3:
+              *
+              * If a prefix in the NLRI field is semantically incorrect
+              * (e.g., an unexpected multicast IP address), an error SHOULD
+              * be logged locally, and the prefix SHOULD be ignored.
+               */
+             zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
+                       peer->host, inet_ntoa (p.u.prefix4));
+             continue;
            }
        }
 
@@ -3173,112 +3564,45 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
            {
              char buf[BUFSIZ];
 
-             zlog_warn ("IPv6 link-local NLRI received %s ignore this NLRI",
-                        inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
+             zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
+                       peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
 
              continue;
            }
-       }
-#endif /* HAVE_IPV6 */
-
-      /* Normal process. */
-      if (attr)
-       ret = bgp_update (peer, &p, addpath_id, attr, afi, safi,
-                         ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0);
-      else
-       ret = bgp_withdraw (peer, &p, addpath_id, attr, afi, safi,
-                           ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);
-
-      /* Address family configuration mismatch or maximum-prefix count
-         overflow. */
-      if (ret < 0)
-       return -1;
-    }
-
-  /* Packet length consistency check. */
-  if (pnt != lim)
-    return -1;
-
-  return 0;
-}
-
-/* NLRI encode syntax check routine. */
-int
-bgp_nlri_sanity_check (struct peer *peer, int afi, safi_t safi, u_char *pnt,
-                      bgp_size_t length, int *numpfx)
-{
-  u_char *end;
-  u_char prefixlen;
-  int psize;
-  int addpath_encoded;
-
-  *numpfx = 0;
-  end = pnt + length;
-  addpath_encoded = bgp_addpath_encode_rx (peer, afi, safi);
-
-  /* RFC1771 6.3 The NLRI field in the UPDATE message is checked for
-     syntactic validity.  If the field is syntactically incorrect,
-     then the Error Subcode is set to Invalid Network Field. */
-
-  while (pnt < end)
-    {
-
-      /* If the NLRI is encoded using addpath then the first 4 bytes are
-       * the addpath ID. */
-      if (addpath_encoded)
-        {
-          if (pnt + BGP_ADDPATH_ID_LEN > end)
+         if (IN6_IS_ADDR_MULTICAST (&p.u.prefix6))
            {
-              zlog_err ("%s [Error] Update packet error"
-                        " (prefix data addpath overflow)",
-                        peer->host);
-              bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
-                               BGP_NOTIFY_UPDATE_INVAL_NETWORK);
-              return -1;
-            }
-          pnt += BGP_ADDPATH_ID_LEN;
-        }
-
-      prefixlen = *pnt++;
-      
-      /* Prefix length check. */
-      if ((afi == AFI_IP && prefixlen > 32)
-         || (afi == AFI_IP6 && prefixlen > 128))
-       {
-         zlog_err ("%s [Error] Update packet error (wrong prefix length %d)",
-                   peer->host, prefixlen);
-         bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 
-                          BGP_NOTIFY_UPDATE_INVAL_NETWORK);
-         return -1;
-       }
+             char buf[BUFSIZ];
 
-      /* Packet size overflow check. */
-      psize = PSIZE (prefixlen);
+             zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
+                       peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
 
-      if (pnt + psize > end)
-       {
-         zlog_err ("%s [Error] Update packet error"
-                   " (prefix data overflow prefix size is %d)",
-                   peer->host, psize);
-         bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 
-                          BGP_NOTIFY_UPDATE_INVAL_NETWORK);
-         return -1;
+             continue;
+           }
        }
+#endif /* HAVE_IPV6 */
+
+      /* Normal process. */
+      if (attr)
+       ret = bgp_update (peer, &p, addpath_id, attr, afi, safi,
+                         ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0);
+      else
+       ret = bgp_withdraw (peer, &p, addpath_id, attr, afi, safi,
+                           ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);
 
-      pnt += psize;
-      (*numpfx)++;
+      /* Address family configuration mismatch or maximum-prefix count
+         overflow. */
+      if (ret < 0)
+       return -1;
     }
 
   /* Packet length consistency check. */
-  if (pnt != end)
+  if (pnt != lim)
     {
-      zlog_err ("%s [Error] Update packet error"
-               " (prefix length mismatch with total length)",
-               peer->host);
-      bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 
-                      BGP_NOTIFY_UPDATE_INVAL_NETWORK);
+      zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
+                peer->host);
       return -1;
     }
+
   return 0;
 }
 
@@ -3307,6 +3631,9 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
   struct attr attr;
   struct attr *attr_new;
   int ret;
+#if ENABLE_BGP_VNC
+  int vnc_implicit_withdraw = 0;
+#endif
 
   assert (bgp_static);
   if (!bgp_static)
@@ -3379,9 +3706,34 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
            bgp_info_restore(rn, ri);
          else
            bgp_aggregate_decrement (bgp, p, ri, afi, safi);
+#if ENABLE_BGP_VNC
+          if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) 
+            {
+              if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) 
+                {
+                  /*
+                   * Implicit withdraw case.
+                   * We have to do this before ri is changed
+                   */
+                  ++vnc_implicit_withdraw;
+                  vnc_import_bgp_del_route(bgp, p, ri);
+                  vnc_import_bgp_exterior_del_route(bgp, p, ri);
+                }
+            }
+#endif
          bgp_attr_unintern (&ri->attr);
          ri->attr = attr_new;
          ri->uptime = bgp_clock ();
+#if ENABLE_BGP_VNC
+          if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) 
+            {
+              if (vnc_implicit_withdraw) 
+                {
+                  vnc_import_bgp_add_route(bgp, p, ri);
+                  vnc_import_bgp_exterior_add_route(bgp, p, ri);
+                }
+            }
+#endif
 
          /* Nexthop reachability check. */
          if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
@@ -3527,6 +3879,18 @@ bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi,
   /* Withdraw static BGP route from routing table. */
   if (ri)
     {
+#if ENABLE_BGP_VNC
+       rfapiProcessWithdraw(
+           ri->peer,
+           NULL,
+           p,
+           prd,
+           ri->attr,
+           afi,
+           safi,
+           ri->type,
+           1);         /* Kill, since it is an administrative change */
+#endif
       bgp_aggregate_decrement (bgp, p, ri, afi, safi);
       bgp_info_delete (rn, ri);
       bgp_process (bgp, rn, afi, safi);
@@ -3545,6 +3909,9 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
   struct attr *attr_new;
   struct attr attr = { 0 };
   struct bgp_info *ri;
+#if ENABLE_BGP_VNC
+  u_int32_t        label = 0;
+#endif
 
   assert (bgp_static);
 
@@ -3621,10 +3988,19 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
           bgp_attr_unintern (&ri->attr);
           ri->attr = attr_new;
           ri->uptime = bgp_clock ();
+#if ENABLE_BGP_VNC
+          if (ri->extra)
+              label = decode_label (ri->extra->tag);
+#endif
 
           /* Process change. */
           bgp_aggregate_increment (bgp, p, ri, afi, safi);
           bgp_process (bgp, rn, afi, safi);
+#if ENABLE_BGP_VNC
+          rfapiProcessUpdate(ri->peer, NULL, p, &bgp_static->prd,
+                             ri->attr, afi, safi, 
+                             ri->type, ri->sub_type, &label);
+#endif
           bgp_unlock_node (rn);
           aspath_unintern (&attr.aspath);
           bgp_attr_extra_free (&attr);
@@ -3639,6 +4015,9 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
   SET_FLAG (new->flags, BGP_INFO_VALID);
   new->extra = bgp_info_extra_new();
   memcpy (new->extra->tag, bgp_static->tag, 3);
+#if ENABLE_BGP_VNC
+  label = decode_label (bgp_static->tag);
+#endif
 
   /* Aggregate address increment. */
   bgp_aggregate_increment (bgp, p, new, afi, safi);
@@ -3652,6 +4031,12 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
   /* Process change. */
   bgp_process (bgp, rn, afi, safi);
 
+#if ENABLE_BGP_VNC
+  rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd,
+                     new->attr, afi, safi, 
+                     new->type, new->sub_type, &label);
+#endif
+
   /* Unintern original. */
   aspath_unintern (&attr.aspath);
   bgp_attr_extra_free (&attr);
@@ -3847,7 +4232,7 @@ bgp_static_delete (struct bgp *bgp)
       for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
        if (rn->info != NULL)
          {      
-           if (safi == SAFI_MPLS_VPN)
+           if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
              {
                table = rn->info;
 
@@ -4147,7 +4532,6 @@ bgp_config_write_table_map (struct vty *vty, struct bgp *bgp, afi_t afi,
   return 0;
 }
 
-
 DEFUN (bgp_table_map,
        bgp_table_map_cmd,
        "table-map WORD",
@@ -4743,7 +5127,7 @@ bgp_aggregate_increment (struct bgp *bgp, struct prefix *p,
   struct bgp_table *table;
 
   /* MPLS-VPN aggregation is not yet supported. */
-  if (safi == SAFI_MPLS_VPN)
+  if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
     return;
 
   table = bgp->aggregate[afi][safi];
@@ -4780,7 +5164,7 @@ bgp_aggregate_decrement (struct bgp *bgp, struct prefix *p,
   struct bgp_table *table;
 
   /* MPLS-VPN aggregation is not yet supported. */
-  if (safi == SAFI_MPLS_VPN)
+  if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
     return;
 
   table = bgp->aggregate[afi][safi];
@@ -5443,7 +5827,7 @@ ALIAS (no_ipv6_aggregate_address_summary_only,
 void
 bgp_redistribute_add (struct bgp *bgp, struct prefix *p, const struct in_addr *nexthop,
                      const struct in6_addr *nexthop6, unsigned int ifindex,
-                     u_int32_t metric, u_char type, u_short instance, u_short tag)
+                     u_int32_t metric, u_char type, u_short instance, route_tag_t tag)
 {
   struct bgp_info *new;
   struct bgp_info *bi;
@@ -5779,10 +6163,40 @@ route_vty_out (struct vty *vty, struct prefix *p,
   attr = binfo->attr;
   if (attr) 
     {
+      /*
+       * For ENCAP routes, nexthop address family is not
+       * neccessarily the same as the prefix address family.
+       * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
+       */
+      if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN))
+        {
+         if (attr->extra)
+            {
+             char buf[BUFSIZ];
+              int af = NEXTHOP_FAMILY(attr->extra->mp_nexthop_len);
 
+              switch (af)
+                {
+                  case AF_INET:
+                    vty_out (vty, "%s", inet_ntop(af,
+                             &attr->extra->mp_nexthop_global_in, buf, BUFSIZ));
+                  break;
+#if HAVE_IPV6
+                  case AF_INET6:
+                    vty_out (vty, "%s", inet_ntop(af,
+                             &attr->extra->mp_nexthop_global, buf, BUFSIZ));
+                  break;
+#endif
+                  default:
+                    vty_out(vty, "?");
+                  break;
+                }
+            }
+          else
+            vty_out(vty, "?");
+        }
       /* IPv4 Next Hop */
-      if (p->family == AF_INET
-          && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
+      else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
        {
           if (json_paths)
             {
@@ -5806,7 +6220,6 @@ route_vty_out (struct vty *vty, struct prefix *p,
             }
        }
 
-#ifdef HAVE_IPV6
       /* IPv6 Next Hop */
       else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
        {
@@ -5834,8 +6247,9 @@ route_vty_out (struct vty *vty, struct prefix *p,
                   json_object_string_add(json_nexthop_ll, "afi", "ipv6");
                   json_object_string_add(json_nexthop_ll, "scope", "link-local");
 
-                  if (IPV6_ADDR_CMP (&attr->extra->mp_nexthop_global,
-                                     &attr->extra->mp_nexthop_local) != 0)
+                  if ((IPV6_ADDR_CMP (&attr->extra->mp_nexthop_global,
+                                      &attr->extra->mp_nexthop_local) != 0) &&
+                                      !attr->extra->mp_nexthop_prefer_global)
                     json_object_boolean_true_add(json_nexthop_ll, "used");
                   else
                     json_object_boolean_true_add(json_nexthop_global, "used");
@@ -5845,7 +6259,10 @@ route_vty_out (struct vty *vty, struct prefix *p,
             }
           else
             {
-             if ((attr->extra->mp_nexthop_len == 32) || (binfo->peer->conf_if))
+              /* Display LL if LL/Global both in table unless prefer-global is set */
+             if (((attr->extra->mp_nexthop_len == 32) &&
+                   !attr->extra->mp_nexthop_prefer_global) ||
+                   (binfo->peer->conf_if))
                {
                  if (binfo->peer->conf_if)
                    {
@@ -5887,7 +6304,6 @@ route_vty_out (struct vty *vty, struct prefix *p,
                }
             }
        }
-#endif /* HAVE_IPV6 */
 
       /* MED/Metric */
       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
@@ -5919,6 +6335,11 @@ route_vty_out (struct vty *vty, struct prefix *p,
       else
         vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
 
+      if (json_paths) {
+       char buf[BUFSIZ];
+       json_object_string_add(json_path, "peerId", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
+      }
+
       /* Print aspath */
       if (attr->aspath)
         {
@@ -5960,7 +6381,14 @@ route_vty_out (struct vty *vty, struct prefix *p,
       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))
+        rfapi_vty_out_vncinfo(vty, p, binfo, safi);
+#endif
+    }
 }  
 
 /* called from terminal list command */
@@ -5995,9 +6423,12 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p, struct attr *attr, safi_t
     {
       if (use_json)
         {
-          if (p->family == AF_INET && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
+          if (p->family == AF_INET &&
+              (safi == SAFI_MPLS_VPN ||
+               safi == SAFI_ENCAP ||
+               !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
             {
-              if (safi == SAFI_MPLS_VPN)
+              if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
                 json_object_string_add(json_net, "nextHop", inet_ntoa (attr->extra->mp_nexthop_global_in));
               else
                 json_object_string_add(json_net, "nextHop", inet_ntoa (attr->nexthop));
@@ -6032,9 +6463,13 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p, struct attr *attr, safi_t
         }
       else
         {
-          if (p->family == AF_INET && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
+          if (p->family == AF_INET &&
+              (safi == SAFI_MPLS_VPN ||
+               safi == SAFI_ENCAP ||
+               !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
             {
-              if (safi == SAFI_MPLS_VPN)
+              if (attr->extra && 
+                  (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))
                 vty_out (vty, "%-16s",
                          inet_ntoa (attr->extra->mp_nexthop_global_in));
               else
@@ -6045,13 +6480,15 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p, struct attr *attr, safi_t
             {
               int len;
               char buf[BUFSIZ];
-
-              assert (attr->extra);
-
-              len = vty_out (vty, "%s",
-                             inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
-                             buf, BUFSIZ));
-              len = 16 - len;
+              if (attr->extra)
+                {
+                  len = vty_out (vty, "%s",
+                                 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
+                                            buf, BUFSIZ));
+                  len = 16 - len;
+                }
+              else
+                len = 0;
               if (len < 1)
                 vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
               else
@@ -6123,7 +6560,7 @@ route_vty_out_tag (struct vty *vty, struct prefix *p,
       if (p->family == AF_INET
           && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
        {
-         if (safi == SAFI_MPLS_VPN)
+         if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
             {
               if (json)
                 json_object_string_add(json_out, "mpNexthopGlobalIn", inet_ntoa (attr->extra->mp_nexthop_global_in));
@@ -6437,7 +6874,7 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
   struct peer *peer;
   int addpath_capable;
   int has_adj;
-  int first_as;
+  unsigned int first_as;
 
   if (json_paths)
     {
@@ -6534,10 +6971,12 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
          
       /* Line2 display Next-hop, Neighbor, Router-id */
       /* Display the nexthop */
-      if (p->family == AF_INET
-          && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
+      if (p->family == AF_INET &&
+          (safi == SAFI_MPLS_VPN ||
+           safi == SAFI_ENCAP ||
+           !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
        {
-          if (safi == SAFI_MPLS_VPN)
+          if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
             {
               if (json_paths)
                 json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->extra->mp_nexthop_global_in));
@@ -6555,7 +6994,6 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
           if (json_paths)
             json_object_string_add(json_nexthop_global, "afi", "ipv4");
        }
-#ifdef HAVE_IPV6
       else
        {
          assert (attr->extra);
@@ -6574,8 +7012,6 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
                                  buf, INET6_ADDRSTRLEN));
             }
        }
-#endif /* HAVE_IPV6 */
-
 
       /* Display the IGP cost or 'inaccessible' */
       if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
@@ -6681,7 +7117,6 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
       if (!json_paths)
         vty_out (vty, "%s", VTY_NEWLINE);
 
-#ifdef HAVE_IPV6
       /* display the link-local nexthop */
       if (attr->extra && attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
        {
@@ -6695,13 +7130,19 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
               json_object_string_add(json_nexthop_ll, "scope", "link-local");
 
               json_object_boolean_true_add(json_nexthop_ll, "accessible");
-              json_object_boolean_true_add(json_nexthop_ll, "used");
+
+              if (!attr->extra->mp_nexthop_prefer_global)
+                json_object_boolean_true_add(json_nexthop_ll, "used");
+              else
+                json_object_boolean_true_add(json_nexthop_global, "used");
             }
           else
             {
-             vty_out (vty, "    (%s) (used)%s",
-                      inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
+             vty_out (vty, "    (%s) %s%s",
+                       inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
                                  buf, INET6_ADDRSTRLEN),
+                       attr->extra->mp_nexthop_prefer_global ?
+                                   "(prefer-global)" : "(used)",
                       VTY_NEWLINE);
             }
        }
@@ -6711,7 +7152,6 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
           if (json_paths)
             json_object_boolean_true_add(json_nexthop_global, "used");
         }
-#endif /* HAVE_IPV6 */
 
       /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
       if (json_paths)
@@ -6755,7 +7195,7 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
           if (json_paths)
             json_object_int_add(json_path, "tag", attr->extra->tag);
           else
-            vty_out (vty, ", tag %d", attr->extra->tag);
+            vty_out (vty, ", tag %"ROUTE_TAG_PRI, attr->extra->tag);
         }
        
       if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
@@ -6863,7 +7303,7 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
       // Mark the bestpath(s)
       if (CHECK_FLAG (binfo->flags, BGP_INFO_DMED_SELECTED))
         {
-          first_as = aspath_get_firstas(attr->aspath);
+          first_as = aspath_get_first_as(attr->aspath);
 
           if (json_paths)
             {
@@ -7145,40 +7585,43 @@ bgp_show_prefix_longer (struct vty *vty, const char *name,
                         safi_t safi, enum bgp_show_type type);
 
 static int
-bgp_show_table (struct vty *vty, struct bgp_table *table,
-                struct in_addr *router_id, enum bgp_show_type type,
-                void *output_arg, u_char use_json, json_object *json)
+bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table,
+                enum bgp_show_type type, void *output_arg, u_char use_json)
 {
   struct bgp_info *ri;
   struct bgp_node *rn;
   int header = 1;
   int display;
   unsigned long output_count;
+  unsigned long total_count;
   struct prefix *p;
   char buf[BUFSIZ];
   char buf2[BUFSIZ];
   json_object *json_paths = NULL;
-  json_object *json_routes = NULL;
+  int first = 1;
 
   if (use_json)
     {
-      if (json == NULL)
-        json = json_object_new_object();
-
-      json_object_int_add(json, "tableVersion", table->version);
-      json_object_string_add(json, "routerId", inet_ntoa (*router_id));
-      json_routes = json_object_new_object();
+      vty_out (vty, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64 ", \"routerId\": \"%s\", \"routes\": { ",
+              bgp->vrf_id == VRF_UNKNOWN ? -1 : bgp->vrf_id,
+              bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default" : bgp->name,
+              table->version, inet_ntoa (bgp->router_id));
+      json_paths = json_object_new_object();
     }
 
   /* This is first entry point, so reset total line. */
   output_count = 0;
+  total_count  = 0;
 
   /* Start processing of routes. */
   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) 
     if (rn->info != NULL)
       {
         display = 0;
-
+       if (!first && use_json)
+         {
+           vty_out (vty, ",");
+         }
         if (use_json)
           json_paths = json_object_new_array();
         else
@@ -7186,6 +7629,7 @@ bgp_show_table (struct vty *vty, struct bgp_table *table,
 
         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
@@ -7332,7 +7776,7 @@ bgp_show_table (struct vty *vty, struct bgp_table *table,
 
             if (!use_json && header)
               {
-                vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (*router_id), VTY_NEWLINE);
+                vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (bgp->router_id), VTY_NEWLINE);
                 vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
                 vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
                 if (type == bgp_show_type_dampend_paths
@@ -7380,16 +7824,19 @@ bgp_show_table (struct vty *vty, struct bgp_table *table,
               {
                 p = &rn->p;
                 sprintf(buf2, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen);
-                json_object_object_add(json_routes, buf2, json_paths);
+               vty_out (vty, "\"%s\": ", buf2);
+               vty_out (vty, "%s", json_object_to_json_string (json_paths));
+               json_object_free (json_paths);
+               first = 0;
+
               }
           }
         }
 
   if (use_json)
     {
-      json_object_object_add(json, "routes", json_routes);
-      vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
-      json_object_free(json);
+      json_object_free (json_paths);
+      vty_out (vty, " } }%s", VTY_NEWLINE);
     }
   else
     {
@@ -7397,11 +7844,11 @@ bgp_show_table (struct vty *vty, struct bgp_table *table,
       if (output_count == 0)
         {
           if (type == bgp_show_type_normal)
-            vty_out (vty, "No BGP network exists%s", VTY_NEWLINE);
+            vty_out (vty, "No BGP prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
         }
       else
-        vty_out (vty, "%sTotal number of prefixes %ld%s",
-                 VTY_NEWLINE, output_count, VTY_NEWLINE);
+        vty_out (vty, "%sDisplayed  %ld routes and %ld total paths%s",
+                 VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
     }
 
   return CMD_SUCCESS;
@@ -7427,8 +7874,8 @@ bgp_show (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
 
   table = bgp->rib[afi][safi];
 
-  return bgp_show_table (vty, table, &bgp->router_id, type, output_arg,
-                         use_json, NULL);
+  return bgp_show_table (vty, bgp, table, type, output_arg,
+                         use_json);
 }
 
 static void
@@ -7438,7 +7885,6 @@ bgp_show_all_instances_routes_vty (struct vty *vty, afi_t afi, safi_t safi,
   struct listnode *node, *nnode;
   struct bgp *bgp;
   struct bgp_table *table;
-  json_object *json = NULL;
   int is_first = 1;
 
   if (use_json)
@@ -7448,20 +7894,6 @@ bgp_show_all_instances_routes_vty (struct vty *vty, afi_t afi, safi_t safi,
     {
       if (use_json)
         {
-          if (!(json = json_object_new_object()))
-            {
-              zlog_err("Unable to allocate memory for JSON object");
-              vty_out (vty,
-                       "{\"error\": {\"message:\": \"Unable to allocate memory for JSON object\"}}}%s",
-                       VTY_NEWLINE);
-              return;
-            }
-          json_object_int_add(json, "vrfId",
-                              (bgp->vrf_id == VRF_UNKNOWN)
-                              ? -1 : bgp->vrf_id);
-          json_object_string_add(json, "vrfName",
-                                 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
-                                 ? "Default" : bgp->name);
           if (! is_first)
             vty_out (vty, ",%s", VTY_NEWLINE);
           else
@@ -7479,8 +7911,8 @@ bgp_show_all_instances_routes_vty (struct vty *vty, afi_t afi, safi_t safi,
                    VTY_NEWLINE);
         }
       table = bgp->rib[afi][safi];
-      bgp_show_table (vty, table, &bgp->router_id,
-                      bgp_show_type_normal, NULL, use_json, json);
+      bgp_show_table (vty, bgp, table,
+                      bgp_show_type_normal, NULL, use_json);
 
     }
 
@@ -7520,7 +7952,7 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
   else
     {
       vty_out (vty, "BGP routing table entry for %s%s%s/%d%s",
-              (safi == SAFI_MPLS_VPN ?
+              ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) ?
               prefix_rd2str (prd, buf1, RD_ADDRSTRLEN) : ""),
               safi == SAFI_MPLS_VPN ? ":" : "",
               inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN),
@@ -7554,7 +7986,9 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
         {
           vty_out (vty, ", best #%d", best);
           if (safi == SAFI_UNICAST)
-           vty_out (vty, ", table Default-IP-Routing-Table");
+            vty_out (vty, ", table %s",
+                     (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+                     ? "Default-IP-Routing-Table" : bgp->name);
         }
       else
         vty_out (vty, ", no best path");
@@ -7640,7 +8074,7 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
       json_paths = json_object_new_array();
     }
 
-  if (safi == SAFI_MPLS_VPN)
+  if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
     {
       for (rn = bgp_table_top (rib); rn; rn = bgp_route_next (rn))
         {
@@ -7664,8 +8098,7 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
                       if (header)
                         {
                           route_vty_out_detail_header (vty, bgp, rm, (struct prefix_rd *)&rn->p,
-                                                       AFI_IP, SAFI_MPLS_VPN, json);
-
+                                                       AFI_IP, safi, json);
                           header = 0;
                         }
                       display++;
@@ -7674,7 +8107,7 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
                           (pathtype == BGP_PATH_BESTPATH && CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) ||
                           (pathtype == BGP_PATH_MULTIPATH &&
                            (CHECK_FLAG (ri->flags, BGP_INFO_MULTIPATH) || CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))))
-                        route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, SAFI_MPLS_VPN, json_paths);
+                        route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, safi, json_paths);
                     }
 
                   bgp_unlock_node (rm);
@@ -7716,7 +8149,7 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
       if (display)
         json_object_object_add(json, "paths", json_paths);
 
-      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
@@ -7777,6 +8210,15 @@ DEFUN (show_ip_bgp,
   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL, use_json(argc, argv));
 }
 
+ALIAS (show_ip_bgp,
+       show_bgp_ipv4_cmd,
+       "show bgp ipv4 {json}",
+       SHOW_STR
+       IP_STR
+       BGP_STR
+       "Address family\n"
+       "JavaScript Object Notation\n")
+
 DEFUN (show_ip_bgp_ipv4,
        show_ip_bgp_ipv4_cmd,
        "show ip bgp ipv4 (unicast|multicast) {json}",
@@ -7789,12 +8231,10 @@ DEFUN (show_ip_bgp_ipv4,
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
-
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST, bgp_show_type_normal,
-                     NULL, uj);
  
-  return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL, uj);
+  return bgp_show (vty, NULL, AFI_IP, 
+                   bgp_vty_safi_from_arg(argv[0]), 
+                   bgp_show_type_normal, NULL, uj);
 }
 
 ALIAS (show_ip_bgp_ipv4,
@@ -7840,12 +8280,10 @@ DEFUN (show_ip_bgp_route_pathtype,
 
 DEFUN (show_bgp_ipv4_safi_route_pathtype,
        show_bgp_ipv4_safi_route_pathtype_cmd,
-       "show bgp ipv4 (unicast|multicast) A.B.C.D (bestpath|multipath) {json}",
+       "show bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D (bestpath|multipath) {json}",
        SHOW_STR
        BGP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
        "Display only the bestpath\n"
        "Display only multipaths\n"
@@ -7853,87 +8291,195 @@ DEFUN (show_bgp_ipv4_safi_route_pathtype,
 {
   u_char uj = use_json(argc, argv);
 
-  if (strncmp (argv[0], "m", 1) == 0)
-    if (strncmp (argv[2], "b", 1) == 0)
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 0, BGP_PATH_BESTPATH, uj);
-    else
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 0, BGP_PATH_MULTIPATH, uj);
+  if (strncmp (argv[2], "b", 1) == 0)
+    return bgp_show_route (vty, NULL, argv[1], AFI_IP, 
+                           bgp_vty_safi_from_arg(argv[0]), 
+                           NULL, 0, BGP_PATH_BESTPATH, uj);
   else
-    if (strncmp (argv[2], "b", 1) == 0)
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_BESTPATH, uj);
-    else
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_MULTIPATH, uj);
+    return bgp_show_route (vty, NULL, argv[1], AFI_IP, 
+                           bgp_vty_safi_from_arg(argv[0]), 
+                           NULL, 0, BGP_PATH_MULTIPATH, uj);
+}
+
+DEFUN (show_bgp_ipv4_prefix,
+       show_bgp_ipv4_prefix_cmd,
+       "show bgp ipv4 A.B.C.D/M {json}",
+       SHOW_STR
+       BGP_STR
+       IP_STR
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+       JSON_STR)
+{
+  return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json (argc, argv));
+}
+
+DEFUN (show_bgp_ipv6_route,
+       show_bgp_ipv6_route_cmd,
+       "show bgp ipv6 X:X::X:X {json}",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Network in the BGP routing table to display\n"
+       JSON_STR)
+{
+  return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, use_json (argc, argv));
+}
+
+DEFUN (show_bgp_ipv6_prefix,
+       show_bgp_ipv6_prefix_cmd,
+       "show bgp ipv6 X:X::X:X/M {json}",
+       SHOW_STR
+       BGP_STR
+       IP_STR
+       "IPv6 prefix <network>/<length>\n"
+       JSON_STR)
+{
+  return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json (argc,argv));
 }
 
 DEFUN (show_ip_bgp_ipv4_route,
        show_ip_bgp_ipv4_route_cmd,
-       "show ip bgp ipv4 (unicast|multicast) A.B.C.D {json}",
+       "show ip bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D {json}",
        SHOW_STR
        IP_STR
        BGP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "Network in the BGP routing table to display\n"
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
 
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 0, BGP_PATH_ALL, uj);
-
-  return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, uj);
+  return bgp_show_route (vty, NULL, argv[1], AFI_IP, 
+                         bgp_vty_safi_from_arg(argv[0]), 
+                         NULL, 0, BGP_PATH_ALL, uj);
 }
 
 ALIAS (show_ip_bgp_ipv4_route,
        show_bgp_ipv4_safi_route_cmd,
-       "show bgp ipv4 (unicast|multicast) A.B.C.D {json}",
+       "show bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D {json}",
        SHOW_STR
        BGP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "Network in the BGP routing table to display\n"
        "JavaScript Object Notation\n")
 
-DEFUN (show_ip_bgp_vpnv4_all_route,
-       show_ip_bgp_vpnv4_all_route_cmd,
-       "show ip bgp vpnv4 all A.B.C.D {json}",
+DEFUN (show_bgp_ipv4_safi_rd_route,
+       show_bgp_ipv4_safi_rd_route_cmd,
+       "show bgp ipv4 (encap|vpn) rd ASN:nn_or_IP-address:nn A.B.C.D {json}",
        SHOW_STR
-       IP_STR
        BGP_STR
-       "Display VPNv4 NLRI specific information\n"
-       "Display information about all VPNv4 NLRIs\n"
-       "Network in the BGP routing table to display\n"
-       "JavaScript Object Notation\n")
+       "Address Family\n"
+       "Address Family Modifier\n"
+       "Address Family Modifier\n"
+       "Display information for a route distinguisher\n"
+       "ENCAP Route Distinguisher\n"
+       "Network in the BGP routing table to display\n")
+{
+  int ret;
+  struct prefix_rd prd;
+  safi_t       safi;
+
+  if (bgp_parse_safi(argv[0], &safi)) {
+    vty_out (vty, "Error: Bad SAFI: %s%s", argv[0], VTY_NEWLINE);
+    return CMD_WARNING;
+  }
+  ret = str2prefix_rd (argv[1], &prd);
+  if (! ret)
+    {
+      vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  return bgp_show_route (vty, NULL, argv[2], AFI_IP, safi, &prd, 0, BGP_PATH_ALL, use_json (argc, argv));
+}
+
+DEFUN (show_bgp_ipv6_safi_rd_route,
+       show_bgp_ipv6_safi_rd_route_cmd,
+       "show bgp ipv6 (encap|vpn) rd ASN:nn_or_IP-address:nn X:X::X:X {json}",
+       SHOW_STR
+       BGP_STR
+       "Address Family\n"
+       "Address Family Modifier\n"
+       "Address Family Modifier\n"
+       "Display information for a route distinguisher\n"
+       "ENCAP Route Distinguisher\n"
+       "Network in the BGP routing table to display\n")
 {
-  return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
+  int ret;
+  struct prefix_rd prd;
+  safi_t       safi;
+
+  if (bgp_parse_safi(argv[0], &safi)) {
+    vty_out (vty, "Error: Bad SAFI: %s%s", argv[0], VTY_NEWLINE);
+    return CMD_WARNING;
+  }
+  ret = str2prefix_rd (argv[1], &prd);
+  if (! ret)
+    {
+      vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  return bgp_show_route (vty, NULL, argv[2], AFI_IP6, SAFI_ENCAP, &prd, 0, BGP_PATH_ALL, use_json (argc, argv));
 }
 
 
-DEFUN (show_ip_bgp_vpnv4_rd_route,
-       show_ip_bgp_vpnv4_rd_route_cmd,
-       "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn A.B.C.D {json}",
+DEFUN (show_bgp_ipv4_safi_rd_prefix,
+       show_bgp_ipv4_safi_rd_prefix_cmd,
+       "show bgp ipv4 (encap|vpn) rd ASN:nn_or_IP-address:nn A.B.C.D/M {json}",
        SHOW_STR
-       IP_STR
        BGP_STR
-       "Display VPNv4 NLRI specific information\n"
+       "Address Family\n"
+       "Address Family Modifier\n"
+       "Address Family Modifier\n"
        "Display information for a route distinguisher\n"
-       "VPN Route Distinguisher\n"
-       "Network in the BGP routing table to display\n"
-       "JavaScript Object Notation\n")
+       "ENCAP Route Distinguisher\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+  int ret;
+  struct prefix_rd prd;
+  safi_t       safi;
+
+  if (bgp_parse_safi(argv[0], &safi)) {
+    vty_out (vty, "Error: Bad SAFI: %s%s", argv[0], VTY_NEWLINE);
+    return CMD_WARNING;
+  }
+
+  ret = str2prefix_rd (argv[1], &prd);
+  if (! ret)
+    {
+      vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  return bgp_show_route (vty, NULL, argv[2], AFI_IP, safi, &prd, 1, BGP_PATH_ALL, use_json (argc, argv));
+}
+
+DEFUN (show_bgp_ipv6_safi_rd_prefix,
+       show_bgp_ipv6_safi_rd_prefix_cmd,
+       "show bgp ipv6 (encap|vpn) rd ASN:nn_or_IP-address:nn X:X::X:X/M {json}",
+       SHOW_STR
+       BGP_STR
+       "Address Family\n"
+       "Address Family Modifier\n"
+       "Address Family Modifier\n"
+       "Display information for a route distinguisher\n"
+       "ENCAP Route Distinguisher\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
 {
   int ret;
   struct prefix_rd prd;
-  u_char uj= use_json(argc, argv);
+  safi_t       safi;
+
+  if (bgp_parse_safi(argv[0], &safi)) {
+    vty_out (vty, "Error: Bad SAFI: %s%s", argv[0], VTY_NEWLINE);
+    return CMD_WARNING;
+  }
 
-  ret = str2prefix_rd (argv[0], &prd);
+  ret = str2prefix_rd (argv[1], &prd);
   if (! ret)
     {
       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
-  return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MPLS_VPN, &prd, 0, BGP_PATH_ALL, uj);
+  return bgp_show_route (vty, NULL, argv[2], AFI_IP6, safi, &prd, 1, BGP_PATH_ALL, use_json (argc, argv));
 }
 
 DEFUN (show_ip_bgp_prefix,
@@ -7968,44 +8514,37 @@ DEFUN (show_ip_bgp_prefix_pathtype,
 
 DEFUN (show_ip_bgp_ipv4_prefix,
        show_ip_bgp_ipv4_prefix_cmd,
-       "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M {json}",
+       "show ip bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D/M {json}",
        SHOW_STR
        IP_STR
        BGP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
 
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 1, BGP_PATH_ALL, uj);
-
-  return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, uj);
+  return bgp_show_route (vty, NULL, argv[1], AFI_IP, 
+                         bgp_vty_safi_from_arg(argv[0]), 
+                         NULL, 1, BGP_PATH_ALL, uj);
 }
 
 ALIAS (show_ip_bgp_ipv4_prefix,
        show_bgp_ipv4_safi_prefix_cmd,
-       "show bgp ipv4 (unicast|multicast) A.B.C.D/M {json}",
+       "show bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D/M {json}",
        SHOW_STR
        BGP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
        "JavaScript Object Notation\n")
 
 DEFUN (show_ip_bgp_ipv4_prefix_pathtype,
        show_ip_bgp_ipv4_prefix_pathtype_cmd,
-       "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M (bestpath|multipath) {json}",
+       "show ip bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D/M (bestpath|multipath) {json}",
        SHOW_STR
        IP_STR
        BGP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
        "Display only the bestpath\n"
        "Display only multipaths\n"
@@ -8013,68 +8552,27 @@ DEFUN (show_ip_bgp_ipv4_prefix_pathtype,
 {
   u_char uj = use_json(argc, argv);
 
-  if (strncmp (argv[0], "m", 1) == 0)
-    if (strncmp (argv[2], "b", 1) == 0)
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 1, BGP_PATH_BESTPATH, uj);
-    else
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 1, BGP_PATH_MULTIPATH, uj);
+  if (strncmp (argv[2], "b", 1) == 0)
+    return bgp_show_route (vty, NULL, argv[1], AFI_IP, 
+                           bgp_vty_safi_from_arg(argv[0]), 
+                           NULL, 1, BGP_PATH_BESTPATH, uj);
   else
-    if (strncmp (argv[2], "b", 1) == 0)
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_BESTPATH, uj);
-    else
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_MULTIPATH, uj);
+    return bgp_show_route (vty, NULL, argv[1], AFI_IP, 
+                           bgp_vty_safi_from_arg(argv[0]), 
+                           NULL, 1, BGP_PATH_MULTIPATH, uj);
 }
 
 ALIAS (show_ip_bgp_ipv4_prefix_pathtype,
        show_bgp_ipv4_safi_prefix_pathtype_cmd,
-       "show bgp ipv4 (unicast|multicast) A.B.C.D/M (bestpath|multipath) {json}",
+       "show bgp ipv4 "BGP_SAFI_CMD_STR" A.B.C.D/M (bestpath|multipath) {json}",
        SHOW_STR
        BGP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
        "Display only the bestpath\n"
        "Display only multipaths\n"
        "JavaScript Object Notation\n")
 
-DEFUN (show_ip_bgp_vpnv4_all_prefix,
-       show_ip_bgp_vpnv4_all_prefix_cmd,
-       "show ip bgp vpnv4 all A.B.C.D/M {json}",
-       SHOW_STR
-       IP_STR
-       BGP_STR
-       "Display VPNv4 NLRI specific information\n"
-       "Display information about all VPNv4 NLRIs\n"
-       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
-       "JavaScript Object Notation\n")
-{
-  return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 1, BGP_PATH_ALL, use_json(argc, argv));
-}
-
-DEFUN (show_ip_bgp_vpnv4_rd_prefix,
-       show_ip_bgp_vpnv4_rd_prefix_cmd,
-       "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn A.B.C.D/M {json}",
-       SHOW_STR
-       IP_STR
-       BGP_STR
-       "Display VPNv4 NLRI specific information\n"
-       "Display information for a route distinguisher\n"
-       "VPN Route Distinguisher\n"
-       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
-       "JavaScript Object Notation\n")
-{
-  int ret;
-  struct prefix_rd prd;
-
-  ret = str2prefix_rd (argv[0], &prd);
-  if (! ret)
-    {
-      vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-  return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MPLS_VPN, &prd, 0, BGP_PATH_ALL, use_json(argc, argv));
-}
 
 DEFUN (show_ip_bgp_view,
        show_ip_bgp_instance_cmd,
@@ -8209,11 +8707,10 @@ DEFUN (show_bgp_ipv6_safi,
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST, bgp_show_type_normal,
-                     NULL, uj);
 
-  return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal, NULL, uj);
+  return bgp_show (vty, NULL, AFI_IP6, 
+                   bgp_vty_safi_from_arg(argv[0]), 
+                   bgp_show_type_normal, NULL, uj);
 }
 
 static void
@@ -8249,31 +8746,20 @@ DEFUN (show_bgp_route,
   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
 }
 
-ALIAS (show_bgp_route,
-       show_bgp_ipv6_route_cmd,
-       "show bgp ipv6 X:X::X:X {json}",
-       SHOW_STR
-       BGP_STR
-       "Address family\n"
-       "Network in the BGP routing table to display\n"
-       "JavaScript Object Notation\n")
-
 DEFUN (show_bgp_ipv6_safi_route,
        show_bgp_ipv6_safi_route_cmd,
-       "show bgp ipv6 (unicast|multicast) X:X::X:X {json}",
+       "show bgp ipv6 "BGP_SAFI_CMD_STR" X:X::X:X {json}",
        SHOW_STR
        BGP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "Network in the BGP routing table to display\n"
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 0, BGP_PATH_ALL, uj);
 
-  return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, uj);
+  return bgp_show_route (vty, NULL, argv[1], AFI_IP6, 
+                   bgp_vty_safi_from_arg(argv[0]), 
+                         NULL, 0, BGP_PATH_ALL, uj);
 }
 
 DEFUN (show_bgp_route_pathtype,
@@ -8306,28 +8792,24 @@ ALIAS (show_bgp_route_pathtype,
 
 DEFUN (show_bgp_ipv6_safi_route_pathtype,
        show_bgp_ipv6_safi_route_pathtype_cmd,
-       "show bgp ipv6 (unicast|multicast) X:X::X:X (bestpath|multipath) {json}",
+       "show bgp ipv6 "BGP_SAFI_CMD_STR" X:X::X:X (bestpath|multipath) {json}",
        SHOW_STR
        BGP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "Network in the BGP routing table to display\n"
        "Display only the bestpath\n"
        "Display only multipaths\n"
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
-  if (strncmp (argv[0], "m", 1) == 0)
-    if (strncmp (argv[2], "b", 1) == 0)
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 0, BGP_PATH_BESTPATH, uj);
-    else
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 0, BGP_PATH_MULTIPATH, uj);
+  if (strncmp (argv[2], "b", 1) == 0)
+    return bgp_show_route (vty, NULL, argv[1], AFI_IP6, 
+                           bgp_vty_safi_from_arg(argv[0]), 
+                           NULL, 0, BGP_PATH_BESTPATH, uj);
   else
-    if (strncmp (argv[2], "b", 1) == 0)
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_BESTPATH, uj);
-    else
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_MULTIPATH, uj);
+    return bgp_show_route (vty, NULL, argv[1], AFI_IP6,
+                           bgp_vty_safi_from_arg(argv[0]), 
+                           NULL, 0, BGP_PATH_MULTIPATH, uj);
 }
 
 /* old command */
@@ -8344,42 +8826,31 @@ DEFUN (show_ipv6_bgp_route,
   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
 }
 
-DEFUN (show_bgp_prefix,
-       show_bgp_prefix_cmd,
-       "show bgp X:X::X:X/M {json}",
-       SHOW_STR
-       BGP_STR
-       "IPv6 prefix <network>/<length>\n"
-       "JavaScript Object Notation\n")
-{
-  return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json(argc, argv));
-}
-
-ALIAS (show_bgp_prefix,
-       show_bgp_ipv6_prefix_cmd,
-       "show bgp ipv6 X:X::X:X/M {json}",
+DEFUN (show_bgp_prefix,
+       show_bgp_prefix_cmd,
+       "show bgp X:X::X:X/M {json}",
        SHOW_STR
        BGP_STR
-       "Address family\n"
        "IPv6 prefix <network>/<length>\n"
        "JavaScript Object Notation\n")
+{
+  return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json(argc, argv));
+}
 
 DEFUN (show_bgp_ipv6_safi_prefix,
        show_bgp_ipv6_safi_prefix_cmd,
-       "show bgp ipv6 (unicast|multicast) X:X::X:X/M {json}",
+       "show bgp ipv6 "BGP_SAFI_CMD_STR" X:X::X:X/M {json}",
        SHOW_STR
        BGP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 1, BGP_PATH_ALL, uj);
 
-  return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, uj);
+  return bgp_show_route (vty, NULL, argv[1], AFI_IP6, 
+                   bgp_vty_safi_from_arg(argv[0]), 
+                         NULL, 1, BGP_PATH_ALL, uj);
 }
 
 DEFUN (show_bgp_prefix_pathtype,
@@ -8412,28 +8883,23 @@ ALIAS (show_bgp_prefix_pathtype,
 
 DEFUN (show_bgp_ipv6_safi_prefix_pathtype,
        show_bgp_ipv6_safi_prefix_pathtype_cmd,
-       "show bgp ipv6 (unicast|multicast) X:X::X:X/M (bestpath|multipath) {json}",
+       "show bgp ipv6 "BGP_SAFI_CMD_STR" X:X::X:X/M (bestpath|multipath) {json}",
        SHOW_STR
        BGP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
        "Display only the bestpath\n"
        "Display only multipaths\n"
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
-  if (strncmp (argv[0], "m", 1) == 0)
-    if (strncmp (argv[2], "b", 1) == 0)
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 1, BGP_PATH_BESTPATH, uj);
-    else
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 1, BGP_PATH_MULTIPATH, uj);
+  if (strncmp (argv[2], "b", 1) == 0)
+    return bgp_show_route (vty, NULL, argv[1], AFI_IP6,
+                           bgp_vty_safi_from_arg(argv[0]), 
+                           NULL, 1, BGP_PATH_BESTPATH, uj);
   else
-    if (strncmp (argv[2], "b", 1) == 0)
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_BESTPATH, uj);
-    else
-      return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_MULTIPATH, uj);
+    return bgp_show_route (vty, NULL, argv[1], AFI_IP6, 
+                           bgp_vty_safi_from_arg(argv[0]), NULL, 1, BGP_PATH_MULTIPATH, uj);
 }
 
 /* old command */
@@ -8853,12 +9319,10 @@ DEFUN (show_ip_bgp_ipv4_regexp,
        "Display routes matching the AS path regular expression\n"
        "A regular-expression to match the BGP AS paths\n")
 {
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_MULTICAST,
-                           bgp_show_type_regexp);
-
-  return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
-                         bgp_show_type_regexp);
+  safi_t safi;
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_show_regexp (vty, argc, argv, AFI_IP, safi,
+                          bgp_show_type_regexp);
 }
 
 #ifdef HAVE_IPV6
@@ -9003,12 +9467,10 @@ DEFUN (show_ip_bgp_ipv4_prefix_list,
        "Display routes conforming to the prefix-list\n"
        "IP prefix-list name\n")
 {
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_prefix_list (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST,
-                                bgp_show_type_prefix_list);
-
-  return bgp_show_prefix_list (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST,
-                              bgp_show_type_prefix_list);
+  safi_t safi;
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_show_prefix_list (vty, NULL, argv[1], AFI_IP, safi,
+                               bgp_show_type_prefix_list);
 }
 
 #ifdef HAVE_IPV6
@@ -9152,12 +9614,10 @@ DEFUN (show_ip_bgp_ipv4_filter_list,
        "Display routes conforming to the filter-list\n"
        "Regular expression access list name\n")
 {
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_filter_list (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST,
-                                bgp_show_type_filter_list);
-  
-  return bgp_show_filter_list (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST,
-                              bgp_show_type_filter_list);
+  safi_t safi;
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_show_filter_list (vty, NULL, argv[1], AFI_IP, safi,
+                               bgp_show_type_filter_list);
 }
 
 #ifdef HAVE_IPV6
@@ -9225,6 +9685,61 @@ DEFUN (show_ip_bgp_dampening_info,
     return bgp_show_dampening_parameters (vty, AFI_IP, SAFI_UNICAST);
 }
 
+
+DEFUN (show_ip_bgp_ipv4_dampening_parameters,
+       show_ip_bgp_ipv4_dampening_parameters_cmd,
+       "show ip bgp ipv4 (unicast|multicast) dampening parameters",
+       SHOW_STR
+       IP_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Display detailed information about dampening\n"
+       "Display detail of configured dampening parameters\n")
+{
+    safi_t safi;
+    safi = bgp_vty_safi_from_arg(argv[0]);
+    return bgp_show_dampening_parameters (vty, AFI_IP, safi);
+}
+
+
+DEFUN (show_ip_bgp_ipv4_dampening_flap_stats,
+       show_ip_bgp_ipv4_dampening_flap_stats_cmd,
+       "show ip bgp ipv4 (unicast|multicast) dampening flap-statistics",
+       SHOW_STR
+       IP_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Display detailed information about dampening\n"
+       "Display flap statistics of routes\n")
+{
+    safi_t safi;
+    safi = bgp_vty_safi_from_arg(argv[0]);
+    return bgp_show (vty, NULL, AFI_IP, safi,
+                     bgp_show_type_flap_statistics, NULL, 0);
+}
+
+DEFUN (show_ip_bgp_ipv4_dampening_dampd_paths,
+       show_ip_bgp_ipv4_dampening_dampd_paths_cmd,
+       "show ip bgp ipv4 (unicast|multicast) dampening dampened-paths",
+       SHOW_STR
+       IP_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Display detailed information about dampening\n"
+       "Display paths suppressed due to dampening\n")
+{
+    safi_t safi;
+    safi = bgp_vty_safi_from_arg(argv[0]);
+    return bgp_show (vty, NULL, AFI_IP, safi,
+                     bgp_show_type_dampend_paths, NULL, 0);
+}
+
 static int
 bgp_show_route_map (struct vty *vty, const char *name,
                     const char *rmap_str, afi_t afi,
@@ -9314,12 +9829,10 @@ DEFUN (show_ip_bgp_ipv4_route_map,
        "Display routes matching the route-map\n"
        "A route-map to match on\n")
 {
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_route_map (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST,
-                              bgp_show_type_route_map);
-
-  return bgp_show_route_map (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST,
-                            bgp_show_type_route_map);
+  safi_t safi;
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_show_route_map (vty, NULL, argv[1], AFI_IP, safi,
+                             bgp_show_type_route_map);
 }
 
 DEFUN (show_bgp_route_map, 
@@ -9389,12 +9902,10 @@ DEFUN (show_ip_bgp_ipv4_cidr_only,
        "Address Family modifier\n"
        "Display only routes with non-natural netmasks\n")
 {
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
-                    bgp_show_type_cidr_only, NULL, 0);
-
-  return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
-                  bgp_show_type_cidr_only, NULL, 0);
+  safi_t safi;
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_show (vty, NULL, AFI_IP, safi,
+                   bgp_show_type_cidr_only, NULL, 0);
 }
 
 DEFUN (show_ip_bgp_community_all,
@@ -9420,12 +9931,10 @@ DEFUN (show_ip_bgp_ipv4_community_all,
        "Address Family modifier\n"
        "Display routes matching the communities\n")
 {
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
-                    bgp_show_type_community_all, NULL, 0);
-  return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
-                  bgp_show_type_community_all, NULL, 0);
+  safi_t safi;
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_show (vty, NULL, AFI_IP, safi,
+                   bgp_show_type_community_all, NULL, 0);
 }
 
 #ifdef HAVE_IPV6
@@ -9630,10 +10139,9 @@ DEFUN (show_ip_bgp_ipv4_community,
        "Do not advertise to any peer (well-known community)\n"
        "Do not export to next AS (well-known community)\n")
 {
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_MULTICAST);
-  return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_UNICAST);
+  safi_t safi;
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, safi);
 }
 
 ALIAS (show_ip_bgp_ipv4_community,
@@ -9729,8 +10237,8 @@ DEFUN (show_bgp_instance_afi_safi_community_all,
       return CMD_WARNING;
     }
 
-  afi = (strncmp (argv[2], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
-  safi = (strncmp (argv[3], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  afi = bgp_vty_safi_from_arg(argv[2]);
+  safi = bgp_vty_safi_from_arg(argv[3]);
   return bgp_show (vty, bgp, afi, safi, bgp_show_type_community_all, NULL, 0);
 }
 
@@ -9753,8 +10261,8 @@ DEFUN (show_bgp_instance_afi_safi_community,
   int afi;
   int safi;
 
-  afi = (strncmp (argv[2], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
-  safi = (strncmp (argv[3], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  afi = bgp_vty_safi_from_arg(argv[2]);
+  safi = bgp_vty_safi_from_arg(argv[3]);
   return bgp_show_community (vty, argv[1], argc-4, &argv[4], 0, afi, safi);
 }
 
@@ -9925,10 +10433,9 @@ DEFUN (show_ip_bgp_ipv4_community_exact,
        "Do not export to next AS (well-known community)\n"
        "Exact match of the communities")
 {
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_MULTICAST);
-  return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_UNICAST);
+  safi_t safi;
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, safi);
 }
 
 ALIAS (show_ip_bgp_ipv4_community_exact,
@@ -10694,10 +11201,9 @@ DEFUN (show_ip_bgp_ipv4_community_list,
        "community-list number\n"
        "community-list name\n")
 {
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_community_list (vty, NULL, argv[1], 0, AFI_IP, SAFI_MULTICAST);
-  
-  return bgp_show_community_list (vty, NULL, argv[1], 0, AFI_IP, SAFI_UNICAST);
+  safi_t safi;
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_show_community_list (vty, NULL, argv[1], 0, AFI_IP, safi);
 }
 
 DEFUN (show_ip_bgp_community_list_exact,
@@ -10728,10 +11234,9 @@ DEFUN (show_ip_bgp_ipv4_community_list_exact,
        "community-list name\n"
        "Exact match of the communities\n")
 {
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_community_list (vty, NULL, argv[1], 1, AFI_IP, SAFI_MULTICAST);
-  return bgp_show_community_list (vty, NULL, argv[1], 1, AFI_IP, SAFI_UNICAST);
+  safi_t safi;
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_show_community_list (vty, NULL, argv[1], 1, AFI_IP, safi);
 }
 
 #ifdef HAVE_IPV6
@@ -10933,12 +11438,10 @@ DEFUN (show_ip_bgp_ipv4_prefix_longer,
        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
        "Display route and more specific routes\n")
 {
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_prefix_longer (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST,
-                                  bgp_show_type_prefix_longer);
-
-  return bgp_show_prefix_longer (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST,
-                                bgp_show_type_prefix_longer);
+  safi_t safi;
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_show_prefix_longer (vty, NULL, argv[1], AFI_IP, safi,
+                                 bgp_show_type_prefix_longer);
 }
 
 DEFUN (show_ip_bgp_flap_address,
@@ -11305,7 +11808,7 @@ bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
   
   if (!bgp->rib[afi][safi])
     {
-      vty_out (vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
+      vty_out (vty, "%% No RIB exists for the AFI(%d)/SAFI(%d)%s",
               afi, safi, VTY_NEWLINE);
       return CMD_WARNING;
     }
@@ -11397,38 +11900,21 @@ bgp_table_stats_vty (struct vty *vty, const char *name,
 
   if (!bgp)
     {
-      vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE);
+      vty_out (vty, "%% No such BGP instance exists%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
-  if (strncmp (afi_str, "ipv", 3) == 0)
+  afi  = bgp_vty_afi_from_arg(afi_str);
+  if (afi == AFI_MAX)
     {
-      if (strncmp (afi_str, "ipv4", 4) == 0)
-        afi = AFI_IP;
-      else if (strncmp (afi_str, "ipv6", 4) == 0)
-        afi = AFI_IP6;
-      else
-        {
-          vty_out (vty, "%% Invalid address family %s%s",
-                   afi_str, VTY_NEWLINE);
-          return CMD_WARNING;
-        }
-      if (strncmp (safi_str, "m", 1) == 0)
-        safi = SAFI_MULTICAST;
-      else if (strncmp (safi_str, "u", 1) == 0)
-        safi = SAFI_UNICAST;
-      else if (strncmp (safi_str, "vpnv4", 5) == 0 || strncmp (safi_str, "vpnv6", 5) == 0)
-        safi = SAFI_MPLS_VPN;
-      else
-        {
-          vty_out (vty, "%% Invalid subsequent address family %s%s",
-                   safi_str, VTY_NEWLINE);
-          return CMD_WARNING;
-        }
+      vty_out (vty, "%% Invalid address family \"%s\"%s",
+               afi_str, VTY_NEWLINE);
+      return CMD_WARNING;
     }
-  else
+  safi = bgp_vty_safi_from_arg(safi_str);
+  if (safi == SAFI_MAX)
     {
-      vty_out (vty, "%% Invalid address family %s%s",
-               afi_str, VTY_NEWLINE);
+      vty_out (vty, "%% Invalid subsequent address family %s%s",
+               safi_str, VTY_NEWLINE);
       return CMD_WARNING;
     }
 
@@ -11437,52 +11923,27 @@ bgp_table_stats_vty (struct vty *vty, const char *name,
 
 DEFUN (show_bgp_statistics,
        show_bgp_statistics_cmd,
-       "show bgp (ipv4|ipv6) (unicast|multicast) statistics",
+       "show bgp "BGP_AFI_SAFI_CMD_STR" statistics",
        SHOW_STR
        BGP_STR
-       "Address family\n"
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "BGP RIB advertisement statistics\n")
 {
   return bgp_table_stats_vty (vty, NULL, argv[0], argv[1]);
 }
 
-ALIAS (show_bgp_statistics,
-       show_bgp_statistics_vpnv4_cmd,
-       "show bgp (ipv4) (vpnv4) statistics",
-       SHOW_STR
-       BGP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "BGP RIB advertisement statistics\n")
-
 DEFUN (show_bgp_statistics_view,
        show_bgp_statistics_view_cmd,
-       "show bgp " BGP_INSTANCE_CMD " (ipv4|ipv6) (unicast|multicast) statistics",
+       "show bgp " BGP_INSTANCE_CMD " "BGP_AFI_SAFI_CMD_STR" statistics",
        SHOW_STR
        BGP_STR
        BGP_INSTANCE_HELP_STR
-       "Address family\n"
-       "Address family\n"
-       "Address Family modifier\n"
-       "Address Family modifier\n"
+       BGP_AFI_SAFI_HELP_STR
        "BGP RIB advertisement statistics\n")
 {
   return bgp_table_stats_vty (vty, NULL, argv[1], argv[2]);
 }
 
-ALIAS (show_bgp_statistics_view,
-       show_bgp_statistics_view_vpnv4_cmd,
-       "show bgp " BGP_INSTANCE_CMD " (ipv4) (vpnv4) statistics",
-       SHOW_STR
-       BGP_STR
-       BGP_INSTANCE_HELP_STR
-       "Address family\n"
-       "Address Family modifier\n"
-       "BGP RIB advertisement statistics\n")
-
 enum bgp_pcounts
 {
   PCOUNT_ADJ_IN = 0,
@@ -11602,7 +12063,7 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_c
       if (use_json)
         {
           json_object_string_add(json, "warning", "No such neighbor or address family");
-          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
@@ -11637,7 +12098,7 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_c
           json_object_string_add(json, "pfxctDriftFor", peer->host);
           json_object_string_add(json, "recommended", "Please report this bug, with the above command output");
         }
-      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
@@ -11791,36 +12252,9 @@ DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts,
   if (! peer)
     return CMD_WARNING;
 
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MULTICAST, uj);
-
-  return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST, uj);
-}
-
-DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts,
-       show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd,
-       "show ip bgp vpnv4 all neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts {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"
-       "Neighbor to display information about\n"
-       "Neighbor to display information about\n"
-       "Neighbor on bgp configured interface\n"
-       "Display detailed prefix count information\n"
-       "JavaScript Object Notation\n")
-{
-  struct peer *peer;
-  u_char uj = use_json(argc, argv);
-
-  peer = peer_lookup_in_view (vty, NULL, argv[0], uj);
-  if (! peer)
-    return CMD_WARNING;
-  
-  return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
+  safi_t safi;
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_peer_counts (vty, peer, AFI_IP, safi, uj);
 }
 
 static void
@@ -11874,7 +12308,7 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
       if (use_json)
         {
           json_object_string_add(json, "alert", "no BGP");
-          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
@@ -12015,7 +12449,7 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
     }
   if (use_json)
     {
-      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);
     }
 
@@ -12035,7 +12469,7 @@ peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
       if (use_json)
         {
           json_object_string_add(json, "warning", "No such neighbor or address family");
-          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
@@ -12049,7 +12483,7 @@ peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
       if (use_json)
         {
           json_object_string_add(json, "warning", "Inbound soft reconfiguration not enabled");
-          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
@@ -12164,6 +12598,8 @@ DEFUN (show_ip_bgp_ipv4_neighbor_advertised_route,
 {
   struct peer *peer;
   const char *rmap_name = NULL;
+  safi_t safi;
+
   u_char uj = use_json(argc, argv); 
 
   peer = peer_lookup_in_view (vty, NULL, argv[1], uj);
@@ -12173,10 +12609,8 @@ DEFUN (show_ip_bgp_ipv4_neighbor_advertised_route,
   if ((argc == 4) || (argc == 3 && argv[2] && strcmp(argv[2], "json") != 0))
     rmap_name = argv[2];
 
-  if (strncmp (argv[0], "m", 1) == 0)
-    return peer_adj_routes (vty, peer, AFI_IP, SAFI_MULTICAST, 0, rmap_name, uj);
-  else
-    return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0, rmap_name, uj);
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return peer_adj_routes (vty, peer, AFI_IP, safi, 0, rmap_name, uj);
 }
 
 ALIAS (show_ip_bgp_ipv4_neighbor_advertised_route,
@@ -12455,6 +12889,7 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_routes,
 {
   struct peer *peer;
   const char *rmap_name = NULL;
+  safi_t safi;
   u_char uj = use_json(argc, argv);
 
   peer = peer_lookup_in_view (vty, NULL, argv[1], uj);
@@ -12464,10 +12899,8 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_routes,
   if (argc == 4 || (argc == 3 && argv[2] && strcmp(argv[2], "json") != 0))
     rmap_name = argv[2];
 
-  if (strncmp (argv[0], "m", 1) == 0)
-    return peer_adj_routes (vty, peer, AFI_IP, SAFI_MULTICAST, 1, rmap_name, uj);
-  else
-    return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1, rmap_name, uj);
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return peer_adj_routes (vty, peer, AFI_IP, safi, 1, rmap_name, uj);
 }
 
 ALIAS (show_ip_bgp_ipv4_neighbor_received_routes,
@@ -12515,8 +12948,8 @@ DEFUN (show_bgp_instance_afi_safi_neighbor_adv_recd_routes,
   if (! peer)
     return CMD_WARNING;
 
-  afi = (strncmp (argv[2], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
-  safi = (strncmp (argv[3], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  afi = bgp_vty_safi_from_arg(argv[2]);
+  safi = bgp_vty_safi_from_arg(argv[3]);
   in = (strncmp (argv[5], "r", 1) == 0) ? 1 : 0;
 
   return peer_adj_routes (vty, peer, afi, safi, in, NULL, uj);
@@ -12674,38 +13107,16 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter,
         }
     }
 
-  if (strncmp (argv[0], "m", 1) == 0)
-    {
-      sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_MULTICAST);
-      count =  prefix_bgp_show_prefix_list (NULL, AFI_IP, name, uj);
-      if (count)
-        {
-          if (!uj)
-            vty_out (vty, "Address family: IPv4 Multicast%s", VTY_NEWLINE);
-          prefix_bgp_show_prefix_list (vty, AFI_IP, name, uj);
-        }
-      else
-        {
-          if (uj)
-            {
-              json_object *json_no = NULL;
-              json_no = json_object_new_object();
-              json_object_boolean_true_add(json_no, "noFuntionalOutput");
-              vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
-              json_object_free(json_no);
-            }
-          else
-            vty_out (vty, "No functional output%s", VTY_NEWLINE);
-        }
-    }
-  else 
     {
-      sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_UNICAST);
+      safi_t safi;
+      safi = bgp_vty_safi_from_arg(argv[0]);
+      sprintf (name, "%s.%d.%d", peer->host, AFI_IP, safi);
       count =  prefix_bgp_show_prefix_list (NULL, AFI_IP, name, uj);
       if (count)
         {
           if (!uj)
-            vty_out (vty, "Address family: IPv4 Unicast%s", VTY_NEWLINE);
+            vty_out (vty, "Address family: %s%s", 
+                     afi_safi_print (AFI_IP, safi), VTY_NEWLINE);
           prefix_bgp_show_prefix_list (vty, AFI_IP, name, uj);
         }
       else
@@ -13149,18 +13560,16 @@ DEFUN (show_ip_bgp_ipv4_neighbor_routes,
        "JavaScript Object Notation\n")
 {
   struct peer *peer;
+  safi_t safi;
   u_char uj = use_json(argc, argv);
 
   peer = peer_lookup_in_view (vty, NULL, argv[1], uj);
   if (! peer)
     return CMD_WARNING;
  
-  if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_MULTICAST,
-                                   bgp_show_type_neighbor, uj);
-
-  return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
-                                 bgp_show_type_neighbor, uj);
+  safi = bgp_vty_safi_from_arg(argv[0]);
+  return bgp_show_neighbor_route (vty, peer, AFI_IP, safi,
+                                  bgp_show_type_neighbor, uj);
 }
 
 #ifdef HAVE_IPV6
@@ -13417,7 +13826,7 @@ ALIAS (show_bgp_instance_neighbor_damp,
 
 #endif /* HAVE_IPV6 */
 
-struct bgp_table *bgp_distance_table;
+struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
 
 struct bgp_distance
 {
@@ -13445,12 +13854,17 @@ bgp_distance_set (struct vty *vty, const char *distance_str,
                   const char *ip_str, const char *access_list_str)
 {
   int ret;
-  struct prefix_ipv4 p;
+  afi_t afi;
+  safi_t safi;
+  struct prefix p;
   u_char distance;
   struct bgp_node *rn;
   struct bgp_distance *bdistance;
 
-  ret = str2prefix_ipv4 (ip_str, &p);
+  afi = bgp_node_afi (vty);
+  safi = bgp_node_safi (vty);
+
+  ret = str2prefix (ip_str, &p);
   if (ret == 0)
     {
       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
@@ -13460,7 +13874,7 @@ bgp_distance_set (struct vty *vty, const char *distance_str,
   distance = atoi (distance_str);
 
   /* Get BGP distance node. */
-  rn = bgp_node_get (bgp_distance_table, (struct prefix *) &p);
+  rn = bgp_node_get (bgp_distance_table[afi][safi], (struct prefix *) &p);
   if (rn->info)
     {
       bdistance = rn->info;
@@ -13492,19 +13906,24 @@ bgp_distance_unset (struct vty *vty, const char *distance_str,
                     const char *ip_str, const char *access_list_str)
 {
   int ret;
+  afi_t afi;
+  safi_t safi;
+  struct prefix p;
   int distance;
-  struct prefix_ipv4 p;
   struct bgp_node *rn;
   struct bgp_distance *bdistance;
 
-  ret = str2prefix_ipv4 (ip_str, &p);
+  afi = bgp_node_afi (vty);
+  safi = bgp_node_safi (vty);
+
+  ret = str2prefix (ip_str, &p);
   if (ret == 0)
     {
       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
 
-  rn = bgp_node_lookup (bgp_distance_table, (struct prefix *)&p);
+  rn = bgp_node_lookup (bgp_distance_table[afi][safi], (struct prefix *)&p);
   if (! rn)
     {
       vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
@@ -13533,10 +13952,11 @@ bgp_distance_unset (struct vty *vty, const char *distance_str,
 
 /* Apply BGP information to distance method. */
 u_char
-bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
+bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, afi_t afi,
+                   safi_t safi, struct bgp *bgp)
 {
   struct bgp_node *rn;
-  struct prefix_ipv4 q;
+  struct prefix q;
   struct peer *peer;
   struct bgp_distance *bdistance;
   struct access_list *alist;
@@ -13545,21 +13965,11 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
   if (! bgp)
     return 0;
 
-  if (p->family != AF_INET)
-    return 0;
-
   peer = rinfo->peer;
 
-  if (peer->su.sa.sa_family != AF_INET)
-    return 0;
-
-  memset (&q, 0, sizeof (struct prefix_ipv4));
-  q.family = AF_INET;
-  q.prefix = peer->su.sin.sin_addr;
-  q.prefixlen = IPV4_MAX_BITLEN;
-
   /* Check source address. */
-  rn = bgp_node_match (bgp_distance_table, (struct prefix *) &q);
+  sockunion2hostprefix (&peer->su, &q);
+  rn = bgp_node_match (bgp_distance_table[afi][safi], &q);
   if (rn)
     {
       bdistance = rn->info;
@@ -13567,7 +13977,7 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
 
       if (bdistance->access_list)
        {
-         alist = access_list_lookup (AFI_IP, bdistance->access_list);
+         alist = access_list_lookup (afi, bdistance->access_list);
          if (alist && access_list_apply (alist, p) == FILTER_PERMIT)
            return bdistance->distance;
        }
@@ -13576,7 +13986,7 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
     }
 
   /* Backdoor check. */
-  rn = bgp_node_lookup (bgp->route[AFI_IP][SAFI_UNICAST], p);
+  rn = bgp_node_lookup (bgp->route[afi][safi], p);
   if (rn)
     {
       bgp_static = rn->info;
@@ -13584,8 +13994,8 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
 
       if (bgp_static->backdoor)
        {
-         if (bgp->distance_local)
-           return bgp->distance_local;
+         if (bgp->distance_local[afi][safi])
+           return bgp->distance_local[afi][safi];
          else
            return ZEBRA_IBGP_DISTANCE_DEFAULT;
        }
@@ -13593,14 +14003,14 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp)
 
   if (peer->sort == BGP_PEER_EBGP)
     {
-      if (bgp->distance_ebgp)
-       return bgp->distance_ebgp;
+      if (bgp->distance_ebgp[afi][safi])
+       return bgp->distance_ebgp[afi][safi];
       return ZEBRA_EBGP_DISTANCE_DEFAULT;
     }
   else
     {
-      if (bgp->distance_ibgp)
-       return bgp->distance_ibgp;
+      if (bgp->distance_ibgp[afi][safi])
+       return bgp->distance_ibgp[afi][safi];
       return ZEBRA_IBGP_DISTANCE_DEFAULT;
     }
 }
@@ -13615,12 +14025,16 @@ DEFUN (bgp_distance,
        "Distance for local routes\n")
 {
   struct bgp *bgp;
+  afi_t afi;
+  safi_t safi;
 
   bgp = vty->index;
+  afi = bgp_node_afi (vty);
+  safi = bgp_node_safi (vty);
 
-  bgp->distance_ebgp = atoi (argv[0]);
-  bgp->distance_ibgp = atoi (argv[1]);
-  bgp->distance_local = atoi (argv[2]);
+  bgp->distance_ebgp[afi][safi] = atoi (argv[0]);
+  bgp->distance_ibgp[afi][safi] = atoi (argv[1]);
+  bgp->distance_local[afi][safi] = atoi (argv[2]);
   return CMD_SUCCESS;
 }
 
@@ -13635,12 +14049,16 @@ DEFUN (no_bgp_distance,
        "Distance for local routes\n")
 {
   struct bgp *bgp;
+  afi_t afi;
+  safi_t safi;
 
   bgp = vty->index;
+  afi = bgp_node_afi (vty);
+  safi = bgp_node_safi (vty);
 
-  bgp->distance_ebgp= 0;
-  bgp->distance_ibgp = 0;
-  bgp->distance_local = 0;
+  bgp->distance_ebgp[afi][safi] = 0;
+  bgp->distance_ibgp[afi][safi] = 0;
+  bgp->distance_local[afi][safi] = 0;
   return CMD_SUCCESS;
 }
 
@@ -13699,6 +14117,54 @@ DEFUN (no_bgp_distance_source_access_list,
   return CMD_SUCCESS;
 }
 
+DEFUN (ipv6_bgp_distance_source,
+       ipv6_bgp_distance_source_cmd,
+       "distance <1-255> X:X::X:X/M",
+       "Define an administrative distance\n"
+       "Administrative distance\n"
+       "IP source prefix\n")
+{
+  bgp_distance_set (vty, argv[0], argv[1], NULL);
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_ipv6_bgp_distance_source,
+       no_ipv6_bgp_distance_source_cmd,
+       "no distance <1-255> X:X::X:X/M",
+       NO_STR
+       "Define an administrative distance\n"
+       "Administrative distance\n"
+       "IP source prefix\n")
+{
+  bgp_distance_unset (vty, argv[0], argv[1], NULL);
+  return CMD_SUCCESS;
+}
+
+DEFUN (ipv6_bgp_distance_source_access_list,
+       ipv6_bgp_distance_source_access_list_cmd,
+       "distance <1-255> X:X::X:X/M WORD",
+       "Define an administrative distance\n"
+       "Administrative distance\n"
+       "IP source prefix\n"
+       "Access list name\n")
+{
+  bgp_distance_set (vty, argv[0], argv[1], argv[2]);
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_ipv6_bgp_distance_source_access_list,
+       no_ipv6_bgp_distance_source_access_list_cmd,
+       "no distance <1-255> X:X::X:X/M WORD",
+       NO_STR
+       "Define an administrative distance\n"
+       "Administrative distance\n"
+       "IP source prefix\n"
+       "Access list name\n")
+{
+  bgp_distance_unset (vty, argv[0], argv[1], argv[2]);
+  return CMD_SUCCESS;
+}
+
 DEFUN (bgp_damp_set,
        bgp_damp_set_cmd,
        "bgp dampening <1-45> <1-20000> <1-20000> <1-255>",
@@ -13873,9 +14339,9 @@ bgp_clear_damp_route (struct vty *vty, const char *view_name,
 
   match.family = afi2family (afi);
 
-  if (safi == SAFI_MPLS_VPN)
+  if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
     {
-      for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
+      for (rn = bgp_table_top (bgp->rib[AFI_IP][safi]); rn; rn = bgp_route_next (rn))
         {
           if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
             continue;
@@ -13992,6 +14458,7 @@ DEFUN (clear_ip_bgp_dampening_address_mask,
                               SAFI_UNICAST, NULL, 0);
 }
 
+/* also used for encap safi */
 static int
 bgp_config_write_network_vpnv4 (struct vty *vty, struct bgp *bgp,
                                afi_t afi, safi_t safi, int *write)
@@ -14043,7 +14510,7 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,
   struct bgp_aggregate *bgp_aggregate;
   char buf[SU_ADDRSTRLEN];
   
-  if (afi == AFI_IP && safi == SAFI_MPLS_VPN)
+  if (afi == AFI_IP && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)))
     return bgp_config_write_network_vpnv4 (vty, bgp, afi, safi, write);
 
   /* Network configuration. */
@@ -14132,40 +14599,53 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,
 }
 
 int
-bgp_config_write_distance (struct vty *vty, struct bgp *bgp)
+bgp_config_write_distance (struct vty *vty, struct bgp *bgp, afi_t afi,
+                          safi_t safi, int *write)
 {
   struct bgp_node *rn;
   struct bgp_distance *bdistance;
 
   /* Distance configuration. */
-  if (bgp->distance_ebgp
-      && bgp->distance_ibgp
-      && bgp->distance_local
-      && (bgp->distance_ebgp != ZEBRA_EBGP_DISTANCE_DEFAULT
-         || bgp->distance_ibgp != ZEBRA_IBGP_DISTANCE_DEFAULT
-         || bgp->distance_local != ZEBRA_IBGP_DISTANCE_DEFAULT))
-    vty_out (vty, " distance bgp %d %d %d%s",
-            bgp->distance_ebgp, bgp->distance_ibgp, bgp->distance_local,
-            VTY_NEWLINE);
-  
-  for (rn = bgp_table_top (bgp_distance_table); rn; rn = bgp_route_next (rn))
+  if (bgp->distance_ebgp[afi][safi]
+      && bgp->distance_ibgp[afi][safi]
+      && bgp->distance_local[afi][safi]
+      && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
+         || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
+         || bgp->distance_local[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT))
+    {
+      bgp_config_write_family_header (vty, afi, safi, write);
+      vty_out (vty, "  distance bgp %d %d %d%s",
+              bgp->distance_ebgp[afi][safi], bgp->distance_ibgp[afi][safi],
+              bgp->distance_local[afi][safi], VTY_NEWLINE);
+    }
+
+  for (rn = bgp_table_top (bgp_distance_table[afi][safi]); rn;
+       rn = bgp_route_next (rn))
     if ((bdistance = rn->info) != NULL)
       {
-       vty_out (vty, " distance %d %s/%d %s%s", bdistance->distance,
-                inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
+       char buf[PREFIX_STRLEN];
+
+       bgp_config_write_family_header (vty, afi, safi, write);
+       vty_out (vty, "  distance %d %s %s%s", bdistance->distance,
+                prefix2str (&rn->p, buf, sizeof (buf)),
                 bdistance->access_list ? bdistance->access_list : "",
                 VTY_NEWLINE);
       }
 
-  return 0;
+  return *write;
 }
 
 /* Allocate routing table structure and install commands. */
 void
 bgp_route_init (void)
 {
+  afi_t afi;
+  safi_t safi;
+
   /* Init BGP distance table. */
-  bgp_distance_table = bgp_table_init (AFI_IP, SAFI_UNICAST);
+  for (afi = AFI_IP; afi < AFI_MAX; afi++)
+    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+      bgp_distance_table[afi][safi] = bgp_table_init (afi, safi);
 
   /* IPv4 BGP commands. */
   install_element (BGP_NODE, &bgp_table_map_cmd);
@@ -14284,6 +14764,7 @@ bgp_route_init (void)
   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_bgp_ipv4_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);
@@ -14295,8 +14776,6 @@ bgp_route_init (void)
   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);
@@ -14305,8 +14784,6 @@ bgp_route_init (void)
   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);
@@ -14371,7 +14848,10 @@ bgp_route_init (void)
   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);
@@ -14391,160 +14871,12 @@ bgp_route_init (void)
   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);
-  
-  /* Restricted node: VIEW_NODE - (set of dangerous commands) */
-  install_element (RESTRICTED_NODE, &show_ip_bgp_route_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_instance_route_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_route_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_instance_route_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_route_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_route_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_route_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_route_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_prefix_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_instance_prefix_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_prefix_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_prefix_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_prefix_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_prefix_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_prefix_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_instance_prefix_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_instance_route_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_instance_prefix_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_community_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_community2_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_community3_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_community4_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community2_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community3_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community4_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_afi_safi_community_all_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_afi_safi_community_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_afi_safi_community2_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_afi_safi_community3_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_afi_safi_community4_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_community_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_community2_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_community3_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_community4_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community2_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community3_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community4_exact_cmd);
-
-  install_element (ENABLE_NODE, &show_ip_bgp_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_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_bgp_ipv4_safi_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_route_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_route_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_route_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_route_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv4_safi_route_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_route_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv4_safi_route_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_route_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_route_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_prefix_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_prefix_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_prefix_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_prefix_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv4_safi_prefix_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv4_safi_prefix_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_prefix_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_prefix_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd);
-
-  install_element (ENABLE_NODE, &show_ip_bgp_regexp_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_regexp_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_prefix_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_prefix_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_prefix_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_filter_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_filter_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_filter_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_route_map_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_route_map_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_route_map_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_cidr_only_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_cidr_only_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_community_all_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community_all_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_community_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_community2_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_community3_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_community4_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community2_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community3_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community4_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_afi_safi_community_all_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_afi_safi_community_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_afi_safi_community2_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_afi_safi_community3_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_afi_safi_community4_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_community_exact_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_community2_exact_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_community3_exact_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_community4_exact_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community_exact_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community2_exact_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community3_exact_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community4_exact_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_community_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_community_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_community_list_exact_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community_list_exact_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_prefix_longer_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_prefix_longer_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_prefix_longer_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_neighbor_advertised_route_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_neighbor_advertised_route_rmap_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_advertised_route_rmap_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_rmap_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_routes_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_received_routes_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_routes_rmap_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_received_routes_rmap_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_rmap_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_afi_safi_neighbor_adv_recd_routes_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_neighbor_routes_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_routes_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_routes_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_dampening_params_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_dampened_paths_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_damp_dampened_paths_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_flap_statistics_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_damp_flap_statistics_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_flap_address_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_damp_flap_address_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_flap_prefix_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_flap_cidr_only_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_damp_flap_cidr_only_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_flap_regexp_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_damp_flap_regexp_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_flap_filter_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_damp_flap_filter_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_flap_prefix_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_damp_flap_prefix_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_damp_flap_prefix_list_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_flap_prefix_longer_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_damp_flap_prefix_longer_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_flap_route_map_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_damp_flap_route_map_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_neighbor_flap_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_neighbor_damp_cmd);
+
+  install_element (VIEW_NODE, &show_bgp_ipv4_prefix_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv4_safi_rd_route_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv6_safi_rd_route_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv4_safi_rd_prefix_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv6_safi_rd_prefix_cmd);
 
  /* BGP dampening clear commands */
   install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
@@ -14556,7 +14888,6 @@ bgp_route_init (void)
   install_element (ENABLE_NODE, &show_ip_bgp_neighbor_prefix_counts_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_prefix_counts_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd);
 #ifdef HAVE_IPV6
   install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_prefix_counts_cmd);
   install_element (ENABLE_NODE, &show_bgp_instance_ipv6_neighbor_prefix_counts_cmd);
@@ -14678,145 +15009,12 @@ bgp_route_init (void)
   install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbor_flap_cmd);
   install_element (VIEW_NODE, &show_bgp_instance_neighbor_damp_cmd);
   install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbor_damp_cmd);
-  
-  /* Restricted:
-   * VIEW_NODE - (set of dangerous commands) - (commands dependent on prev) 
-   */
-  install_element (RESTRICTED_NODE, &show_bgp_route_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_route_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_route_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_route_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_route_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_route_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_prefix_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_prefix_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_prefix_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_prefix_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_prefix_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_prefix_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_community_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_community2_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community2_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_community3_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community3_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_community4_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community4_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_community_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_community2_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community2_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_community3_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community3_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_community4_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community4_exact_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_route_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_route_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_route_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_route_pathtype_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_prefix_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_prefix_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_neighbor_received_prefix_filter_cmd);
-  install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_neighbor_received_prefix_filter_cmd);
-
-  install_element (ENABLE_NODE, &show_bgp_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_cmd);
-  install_element (ENABLE_NODE, &show_bgp_route_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_route_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_route_cmd);
-  install_element (ENABLE_NODE, &show_bgp_route_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_route_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_route_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_prefix_cmd);
-  install_element (ENABLE_NODE, &show_bgp_prefix_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_prefix_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_prefix_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_prefix_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_prefix_cmd);
-  install_element (ENABLE_NODE, &show_bgp_regexp_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_regexp_cmd);
-  install_element (ENABLE_NODE, &show_bgp_prefix_list_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_prefix_list_cmd);
-  install_element (ENABLE_NODE, &show_bgp_filter_list_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_filter_list_cmd);
-  install_element (ENABLE_NODE, &show_bgp_route_map_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_route_map_cmd);
-  install_element (ENABLE_NODE, &show_bgp_community_all_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_community_all_cmd);
-  install_element (ENABLE_NODE, &show_bgp_community_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_community_cmd);
-  install_element (ENABLE_NODE, &show_bgp_community2_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_community2_cmd);
-  install_element (ENABLE_NODE, &show_bgp_community3_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_community3_cmd);
-  install_element (ENABLE_NODE, &show_bgp_community4_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_community4_cmd);
-  install_element (ENABLE_NODE, &show_bgp_community_exact_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_community_exact_cmd);
-  install_element (ENABLE_NODE, &show_bgp_community2_exact_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_community2_exact_cmd);
-  install_element (ENABLE_NODE, &show_bgp_community3_exact_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_community3_exact_cmd);
-  install_element (ENABLE_NODE, &show_bgp_community4_exact_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_community4_exact_cmd);
-  install_element (ENABLE_NODE, &show_bgp_community_list_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_community_list_cmd);
-  install_element (ENABLE_NODE, &show_bgp_community_list_exact_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_community_list_exact_cmd);
-  install_element (ENABLE_NODE, &show_bgp_prefix_longer_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_prefix_longer_cmd);
-  install_element (ENABLE_NODE, &show_bgp_neighbor_advertised_route_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_advertised_route_cmd);
-  install_element (ENABLE_NODE, &show_bgp_neighbor_received_routes_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_received_routes_cmd);
-  install_element (ENABLE_NODE, &show_bgp_neighbor_routes_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_routes_cmd);
-  install_element (ENABLE_NODE, &show_bgp_neighbor_received_prefix_filter_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_received_prefix_filter_cmd);
-  install_element (ENABLE_NODE, &show_bgp_neighbor_flap_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_flap_cmd);
-  install_element (ENABLE_NODE, &show_bgp_neighbor_damp_cmd);
-  install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_damp_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_all_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_route_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_route_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_route_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_route_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_prefix_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_prefix_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_prefix_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_prefix_pathtype_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_prefix_list_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_prefix_list_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_filter_list_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_filter_list_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_route_map_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_route_map_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_community_list_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_community_list_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_prefix_longer_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_prefix_longer_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_neighbor_advertised_route_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_neighbor_advertised_route_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_neighbor_received_routes_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_neighbor_received_routes_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_neighbor_routes_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_neighbor_routes_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_neighbor_received_prefix_filter_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_neighbor_received_prefix_filter_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_neighbor_flap_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_neighbor_flap_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_neighbor_damp_cmd);
-  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_neighbor_damp_cmd);
 
   /* Statistics */
   install_element (ENABLE_NODE, &show_bgp_statistics_cmd);
-  install_element (ENABLE_NODE, &show_bgp_statistics_vpnv4_cmd);
+  //install_element (ENABLE_NODE, &show_bgp_statistics_vpnv4_cmd);
   install_element (ENABLE_NODE, &show_bgp_statistics_view_cmd);
-  install_element (ENABLE_NODE, &show_bgp_statistics_view_vpnv4_cmd);
+  //install_element (ENABLE_NODE, &show_bgp_statistics_view_vpnv4_cmd);
   
   /* old command */
   install_element (VIEW_NODE, &show_ipv6_bgp_cmd);
@@ -14856,61 +15054,17 @@ bgp_route_init (void)
   install_element (VIEW_NODE, &show_ipv6_mbgp_community_list_exact_cmd);
   install_element (VIEW_NODE, &show_ipv6_mbgp_prefix_longer_cmd);
   
-  /* old command */
-  install_element (ENABLE_NODE, &show_ipv6_bgp_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_route_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_prefix_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_regexp_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_prefix_list_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_filter_list_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_community_all_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_community_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_community2_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_community3_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_community4_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_community_exact_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_community2_exact_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_community3_exact_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_community4_exact_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_community_list_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_community_list_exact_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_bgp_prefix_longer_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_route_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_prefix_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_regexp_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_prefix_list_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_filter_list_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_community_all_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_community_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_community2_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_community3_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_community4_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_community_exact_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_community2_exact_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_community3_exact_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_community4_exact_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_community_list_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_community_list_exact_cmd);
-  install_element (ENABLE_NODE, &show_ipv6_mbgp_prefix_longer_cmd);
-
   /* old command */
   install_element (VIEW_NODE, &ipv6_bgp_neighbor_advertised_route_cmd);
-  install_element (ENABLE_NODE, &ipv6_bgp_neighbor_advertised_route_cmd);
   install_element (VIEW_NODE, &ipv6_mbgp_neighbor_advertised_route_cmd);
-  install_element (ENABLE_NODE, &ipv6_mbgp_neighbor_advertised_route_cmd);
 
   /* old command */
   install_element (VIEW_NODE, &ipv6_bgp_neighbor_received_routes_cmd);
-  install_element (ENABLE_NODE, &ipv6_bgp_neighbor_received_routes_cmd);
   install_element (VIEW_NODE, &ipv6_mbgp_neighbor_received_routes_cmd);
-  install_element (ENABLE_NODE, &ipv6_mbgp_neighbor_received_routes_cmd);
 
   /* old command */
   install_element (VIEW_NODE, &ipv6_bgp_neighbor_routes_cmd);
-  install_element (ENABLE_NODE, &ipv6_bgp_neighbor_routes_cmd);
   install_element (VIEW_NODE, &ipv6_mbgp_neighbor_routes_cmd);
-  install_element (ENABLE_NODE, &ipv6_mbgp_neighbor_routes_cmd);
 #endif /* HAVE_IPV6 */
 
   install_element (BGP_NODE, &bgp_distance_cmd);
@@ -14920,6 +15074,34 @@ bgp_route_init (void)
   install_element (BGP_NODE, &no_bgp_distance_source_cmd);
   install_element (BGP_NODE, &bgp_distance_source_access_list_cmd);
   install_element (BGP_NODE, &no_bgp_distance_source_access_list_cmd);
+  install_element (BGP_IPV4_NODE, &bgp_distance_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_distance_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_distance2_cmd);
+  install_element (BGP_IPV4_NODE, &bgp_distance_source_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
+  install_element (BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
+  install_element (BGP_IPV4M_NODE, &bgp_distance_cmd);
+  install_element (BGP_IPV4M_NODE, &no_bgp_distance_cmd);
+  install_element (BGP_IPV4M_NODE, &no_bgp_distance2_cmd);
+  install_element (BGP_IPV4M_NODE, &bgp_distance_source_cmd);
+  install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
+  install_element (BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
+  install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_access_list_cmd);
+  install_element (BGP_IPV6_NODE, &bgp_distance_cmd);
+  install_element (BGP_IPV6_NODE, &no_bgp_distance_cmd);
+  install_element (BGP_IPV6_NODE, &no_bgp_distance2_cmd);
+  install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
+  install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
+  install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_access_list_cmd);
+  install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_access_list_cmd);
+  install_element (BGP_IPV6M_NODE, &bgp_distance_cmd);
+  install_element (BGP_IPV6M_NODE, &no_bgp_distance_cmd);
+  install_element (BGP_IPV6M_NODE, &no_bgp_distance2_cmd);
+  install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
+  install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
+  install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_access_list_cmd);
+  install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_access_list_cmd);
 
   install_element (BGP_NODE, &bgp_damp_set_cmd);
   install_element (BGP_NODE, &bgp_damp_set2_cmd);
@@ -14933,11 +15115,25 @@ bgp_route_init (void)
   install_element (BGP_IPV4_NODE, &bgp_damp_unset_cmd);
   install_element (BGP_IPV4_NODE, &bgp_damp_unset2_cmd);
   install_element (BGP_IPV4_NODE, &bgp_damp_unset3_cmd);
+
+  /* IPv4 Multicast Mode */
+  install_element (BGP_IPV4M_NODE, &bgp_damp_set_cmd);
+  install_element (BGP_IPV4M_NODE, &bgp_damp_set2_cmd);
+  install_element (BGP_IPV4M_NODE, &bgp_damp_set3_cmd);
+  install_element (BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
+  install_element (BGP_IPV4M_NODE, &bgp_damp_unset2_cmd);
 }
 
 void
 bgp_route_finish (void)
 {
-  bgp_table_unlock (bgp_distance_table);
-  bgp_distance_table = NULL;
+  afi_t afi;
+  safi_t safi;
+
+  for (afi = AFI_IP; afi < AFI_MAX; afi++)
+    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+      {
+       bgp_table_unlock (bgp_distance_table[afi][safi]);
+       bgp_distance_table[afi][safi] = NULL;
+      }
 }