]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_route.c
bgpd: use loops to reduce code duplication
[mirror_frr.git] / bgpd / bgp_route.c
index adc6407bb9a7d1d05744b5093a7f9420de1d7be7..57e38ce10c3f4470a6ee4d2e02167364a29700cb 100644 (file)
@@ -62,6 +62,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 +83,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 +96,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 +138,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 +241,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 +345,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 +389,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;
@@ -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,31 @@ 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;
+  struct bgp_maxpaths_cfg mpath_cfg;
+  int ret;
+  ret = bgp_info_cmp (bgp, new, exist, &paths_eq, &mpath_cfg, 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 +1018,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 +1075,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 +1197,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 +1214,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 +1366,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 +1435,18 @@ 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 && \
+     (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
+    (safi == SAFI_ENCAP && attr->extra->mp_nexthop_len == 16))
+
   /* 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;
             }
 
@@ -1755,6 +1822,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 +1923,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 +1963,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 +2000,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,19 +2060,6 @@ 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 ();
 
@@ -2083,7 +2211,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 +2226,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);
 }
 
@@ -2201,6 +2355,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 +2391,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 +2560,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 +2598,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,6 +2656,28 @@ 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);
 
@@ -2508,6 +2748,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))
@@ -2561,10 +2823,26 @@ bgp_withdraw (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
   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 +2862,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 +2907,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 +3020,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;
@@ -2956,7 +3233,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 +3256,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 +3315,74 @@ bgp_clear_stale_route (struct peer *peer, afi_t afi, safi_t safi)
     }
 }
 
+static void
+bgp_cleanup_table(struct bgp_table *table, safi_t safi)
+{
+  struct bgp_node *rn;
+  struct bgp_info *ri;
+  struct bgp_info *next;
+
+  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);
+          }
+      }
+}
+
 /* Delete all kernel routes. */
 void
 bgp_cleanup_routes (void)
 {
   struct bgp *bgp;
   struct listnode *node, *nnode;
-  struct bgp_node *rn;
-  struct bgp_table *table;
-  struct bgp_info *ri;
+  afi_t afi;
 
   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
     {
-      table = bgp->rib[AFI_IP][SAFI_UNICAST];
+      for (afi = AFI_IP; afi < AFI_MAX; ++afi)
+       {
+         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 +3405,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 +3429,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 +3450,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 +3488,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,8 +3508,17 @@ 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;
+           }
+         if (IN6_IS_ADDR_MULTICAST (&p.u.prefix6))
+           {
+             char buf[BUFSIZ];
+
+             zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
+                       peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
 
              continue;
            }
@@ -3197,88 +3541,12 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
 
   /* 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)
-           {
-              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;
-       }
-
-      /* Packet size overflow check. */
-      psize = PSIZE (prefixlen);
-
-      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;
-       }
-
-      pnt += psize;
-      (*numpfx)++;
-    }
-
-  /* Packet length consistency check. */
-  if (pnt != end)
-    {
-      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 +3575,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 +3650,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))
@@ -3476,36 +3772,6 @@ bgp_static_update (struct bgp *bgp, struct prefix *p,
   bgp_static_update_main (bgp, p, bgp_static, afi, safi);
 }
 
-static void
-bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
-                        safi_t safi, struct prefix_rd *prd, u_char *tag)
-{
-  struct bgp_node *rn;
-  struct bgp_info *new;
-  
-  rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
-
-  /* Make new BGP info. */
-  new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
-                 bgp_attr_default_intern(BGP_ORIGIN_IGP), rn);
-
-  SET_FLAG (new->flags, BGP_INFO_VALID);
-  new->extra = bgp_info_extra_new();
-  memcpy (new->extra->tag, tag, 3);
-
-  /* Aggregate address increment. */
-  bgp_aggregate_increment (bgp, p, new, afi, safi);
-  
-  /* Register new BGP information. */
-  bgp_info_add (rn, new);
-
-  /* route_node_get lock */
-  bgp_unlock_node (rn);
-  
-  /* Process change. */
-  bgp_process (bgp, rn, afi, safi);
-}
-
 void
 bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
                     safi_t safi)
@@ -3535,9 +3801,12 @@ bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
   bgp_unlock_node (rn);
 }
 
+/*
+ * Used for SAFI_MPLS_VPN and SAFI_ENCAP
+ */
 static void
-bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
-                          safi_t safi, struct prefix_rd *prd, u_char *tag)
+bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi,
+                          safi_t safi, struct prefix_rd *prd, u_char *tag)
 {
   struct bgp_node *rn;
   struct bgp_info *ri;
@@ -3554,6 +3823,18 @@ bgp_static_withdraw_vpnv4 (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);
@@ -3563,6 +3844,148 @@ bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
   bgp_unlock_node (rn);
 }
 
+static void
+bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
+                        struct bgp_static *bgp_static, afi_t afi, safi_t safi)
+{
+  struct bgp_node *rn;
+  struct bgp_info *new;
+  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);
+
+  rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, &bgp_static->prd);
+
+  bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
+
+  attr.nexthop = bgp_static->igpnexthop;
+  attr.med = bgp_static->igpmetric;
+  attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
+
+  /* Apply route-map. */
+  if (bgp_static->rmap.name)
+    {
+      struct attr attr_tmp = attr;
+      struct bgp_info info;
+      int ret;
+
+      info.peer = bgp->peer_self;
+      info.attr = &attr_tmp;
+
+      SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
+
+      ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
+
+      bgp->peer_self->rmap_type = 0;
+
+      if (ret == RMAP_DENYMATCH)
+        {
+          /* Free uninterned attribute. */
+          bgp_attr_flush (&attr_tmp);
+
+          /* Unintern original. */
+          aspath_unintern (&attr.aspath);
+          bgp_attr_extra_free (&attr);
+          bgp_static_withdraw_safi (bgp, p, afi, safi, &bgp_static->prd,
+                                    bgp_static->tag);
+          return;
+        }
+
+      attr_new = bgp_attr_intern (&attr_tmp);
+    }
+  else
+    {
+      attr_new = bgp_attr_intern (&attr);
+    }
+
+  for (ri = rn->info; ri; ri = ri->next)
+    if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
+        && ri->sub_type == BGP_ROUTE_STATIC)
+      break;
+
+  if (ri)
+    {
+      if (attrhash_cmp (ri->attr, attr_new) &&
+          !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
+        {
+          bgp_unlock_node (rn);
+          bgp_attr_unintern (&attr_new);
+          aspath_unintern (&attr.aspath);
+          bgp_attr_extra_free (&attr);
+          return;
+        }
+      else
+        {
+          /* The attribute is changed. */
+          bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
+
+          /* Rewrite BGP route information. */
+          if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
+            bgp_info_restore(rn, ri);
+          else
+            bgp_aggregate_decrement (bgp, p, ri, afi, safi);
+          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);
+          return;
+        }
+    }
+
+
+  /* Make new BGP info. */
+  new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self, attr_new,
+                 rn);
+  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);
+
+  /* Register new BGP information. */
+  bgp_info_add (rn, new);
+
+  /* route_node_get lock */
+  bgp_unlock_node (rn);
+
+  /* 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);
+}
+
 /* Configure static BGP network.  When user don't run zebra, static
    route should be installed as valid.  */
 static int
@@ -3726,10 +4149,7 @@ bgp_static_add (struct bgp *bgp)
                for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
                  {
                    bgp_static = rn->info;
-                   bgp_static_update_vpnv4 (bgp, &rm->p,
-                                             AFI_IP, SAFI_MPLS_VPN,
-                                            (struct prefix_rd *)&rn->p,
-                                            bgp_static->tag);
+                    bgp_static_update_safi (bgp, &rm->p, bgp_static, afi, safi);
                  }
              }
            else
@@ -3756,15 +4176,15 @@ 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;
 
                for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
                  {
                    bgp_static = rn->info;
-                   bgp_static_withdraw_vpnv4 (bgp, &rm->p,
-                                              AFI_IP, SAFI_MPLS_VPN,
+                   bgp_static_withdraw_safi (bgp, &rm->p,
+                                              AFI_IP, safi,
                                               (struct prefix_rd *)&rn->p,
                                               bgp_static->tag);
                    bgp_static_free (bgp_static);
@@ -3846,9 +4266,15 @@ bgp_purge_static_redist_routes (struct bgp *bgp)
       bgp_purge_af_static_redist_routes (bgp, afi, safi);
 }
 
+/*
+ * gpz 110624
+ * Currently this is used to set static routes for VPN and ENCAP.
+ * I think it can probably be factored with bgp_static_set.
+ */
 int
-bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
-                     const char *tag_str)
+bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,
+                     const char *rd_str, const char *tag_str,
+                     const char *rmap_str)
 {
   int ret;
   struct prefix p;
@@ -3884,10 +4310,10 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
       return CMD_WARNING;
     }
 
-  prn = bgp_node_get (bgp->route[AFI_IP][SAFI_MPLS_VPN],
+  prn = bgp_node_get (bgp->route[AFI_IP][safi],
                        (struct prefix *)&prd);
   if (prn->info == NULL)
-    prn->info = bgp_table_init (AFI_IP, SAFI_MPLS_VPN);
+    prn->info = bgp_table_init (AFI_IP, safi);
   else
     bgp_unlock_node (prn);
   table = prn->info;
@@ -3903,11 +4329,24 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
     {
       /* New configuration. */
       bgp_static = bgp_static_new ();
-      bgp_static->valid = 1;
-      memcpy (bgp_static->tag, tag, 3);
+      bgp_static->backdoor = 0;
+      bgp_static->valid = 0;
+      bgp_static->igpmetric = 0;
+      bgp_static->igpnexthop.s_addr = 0;
+      memcpy(bgp_static->tag, tag, 3);
+      bgp_static->prd = prd;
+
+      if (rmap_str)
+       {
+         if (bgp_static->rmap.name)
+           free (bgp_static->rmap.name);
+         bgp_static->rmap.name = strdup (rmap_str);
+         bgp_static->rmap.map = route_map_lookup_by_name (rmap_str);
+       }
       rn->info = bgp_static;
 
-      bgp_static_update_vpnv4 (bgp, &p, AFI_IP, SAFI_MPLS_VPN, &prd, tag);
+      bgp_static->valid = 1;
+      bgp_static_update_safi (bgp, &p, bgp_static, AFI_IP, safi);
     }
 
   return CMD_SUCCESS;
@@ -3915,8 +4354,8 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
 
 /* Configure static BGP network. */
 int
-bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str, 
-                        const char *rd_str, const char *tag_str)
+bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str,
+                      const char *rd_str, const char *tag_str)
 {
   int ret;
   struct bgp *bgp;
@@ -3953,10 +4392,10 @@ bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str,
       return CMD_WARNING;
     }
 
-  prn = bgp_node_get (bgp->route[AFI_IP][SAFI_MPLS_VPN],
+  prn = bgp_node_get (bgp->route[AFI_IP][safi],
                        (struct prefix *)&prd);
   if (prn->info == NULL)
-    prn->info = bgp_table_init (AFI_IP, SAFI_MPLS_VPN);
+    prn->info = bgp_table_init (AFI_IP, safi);
   else
     bgp_unlock_node (prn);
   table = prn->info;
@@ -3965,7 +4404,7 @@ bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str,
 
   if (rn)
     {
-      bgp_static_withdraw_vpnv4 (bgp, &p, AFI_IP, SAFI_MPLS_VPN, &prd, tag);
+      bgp_static_withdraw_safi (bgp, &p, AFI_IP, safi, &prd, tag);
 
       bgp_static = rn->info;
       bgp_static_free (bgp_static);
@@ -4633,7 +5072,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];
@@ -4670,7 +5109,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];
@@ -5333,7 +5772,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;
@@ -5669,10 +6108,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)
             {
@@ -5696,7 +6165,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))
        {
@@ -5724,8 +6192,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");
@@ -5735,7 +6204,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)
                    {
@@ -5777,14 +6249,13 @@ 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))
         if (json_paths)
           json_object_int_add(json_path, "med", attr->med);
         else
-         vty_out (vty, "%10u", attr->med);
+         vty_out (vty, "%10u ", attr->med);
       else
         if (!json_paths)
          vty_out (vty, "          ");
@@ -5794,7 +6265,7 @@ route_vty_out (struct vty *vty, struct prefix *p,
         if (json_paths)
           json_object_int_add(json_path, "localpref", attr->local_pref);
         else
-         vty_out (vty, "%7u", attr->local_pref);
+         vty_out (vty, "%7u ", attr->local_pref);
       else
         if (!json_paths)
          vty_out (vty, "       ");
@@ -5809,6 +6280,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)
         {
@@ -5850,7 +6326,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) || (safi == SAFI_UNICAST))
+        rfapi_vty_out_vncinfo(vty, p, binfo, safi);
+#endif
+    }
 }  
 
 /* called from terminal list command */
@@ -5885,9 +6368,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));
@@ -5922,9 +6408,12 @@ 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 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
                 vty_out (vty, "%-16s",
                          inet_ntoa (attr->extra->mp_nexthop_global_in));
               else
@@ -5949,12 +6438,12 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p, struct attr *attr, safi_t
             }
 #endif /* HAVE_IPV6 */
           if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
-            vty_out (vty, "%10u", attr->med);
+            vty_out (vty, "%10u ", attr->med);
           else
             vty_out (vty, "          ");
 
           if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
-            vty_out (vty, "%7u", attr->local_pref);
+            vty_out (vty, "%7u ", attr->local_pref);
           else
             vty_out (vty, "       ");
 
@@ -6013,7 +6502,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));
@@ -6327,7 +6816,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)
     {
@@ -6424,10 +6913,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));
@@ -6445,7 +6936,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);
@@ -6464,8 +6954,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))
@@ -6571,7 +7059,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)
        {
@@ -6585,13 +7072,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);
             }
        }
@@ -6601,7 +7094,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)
@@ -6645,7 +7137,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))
@@ -6753,7 +7245,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)
             {
@@ -7035,40 +7527,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
@@ -7076,6 +7571,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
@@ -7222,7 +7718,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
@@ -7270,16 +7766,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
     {
@@ -7287,11 +7786,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 out of %ld total prefixes%s",
+                 VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
     }
 
   return CMD_SUCCESS;
@@ -7317,8 +7816,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
@@ -7328,7 +7827,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)
@@ -7338,20 +7836,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
@@ -7369,8 +7853,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);
 
     }
 
@@ -7410,7 +7894,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),
@@ -7444,7 +7928,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");
@@ -7530,7 +8016,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))
         {
@@ -7554,8 +8040,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++;
@@ -7564,7 +8049,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);
@@ -7606,7 +8091,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
@@ -7755,6 +8240,42 @@ DEFUN (show_bgp_ipv4_safi_route_pathtype,
       return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, 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}",
@@ -7800,6 +8321,79 @@ DEFUN (show_ip_bgp_vpnv4_all_route,
   return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
 }
 
+DEFUN (show_bgp_ipv4_vpn_route,
+       show_bgp_ipv4_vpn_route_cmd,
+       "show bgp ipv4 vpn A.B.C.D {json}",
+       SHOW_STR
+       BGP_STR
+       "Address Family\n"
+       "Display VPN NLRI specific information\n"
+       "Network in the BGP routing table to display\n"
+       JSON_STR)
+{
+  return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 0, BGP_PATH_ALL, use_json (argc, argv));
+}
+
+DEFUN (show_bgp_ipv6_vpn_route,
+       show_bgp_ipv6_vpn_route_cmd,
+       "show bgp ipv6 vpn X:X::X:X {json}",
+       SHOW_STR
+       BGP_STR
+       "Address Family\n"
+       "Display VPN NLRI specific information\n"
+       "Network in the BGP routing table to display\n"
+       JSON_STR)
+{
+  return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MPLS_VPN, NULL, 0, BGP_PATH_ALL, use_json (argc, argv));
+}
+
+DEFUN (show_bgp_ipv4_vpn_rd_route,
+       show_bgp_ipv4_vpn_rd_route_cmd,
+       "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn A.B.C.D {json}",
+       SHOW_STR
+       BGP_STR
+       IP_STR
+       "Display VPN NLRI specific information\n"
+       "Display information for a route distinguisher\n"
+       "VPN Route Distinguisher\n"
+       "Network in the BGP routing table to display\n"
+       JSON_STR)
+{
+  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_bgp_ipv6_vpn_rd_route,
+       show_bgp_ipv6_vpn_rd_route_cmd,
+       "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn X:X::X:X {json}",
+       SHOW_STR
+       BGP_STR
+       "Address Family\n"
+       "Display VPN NLRI specific information\n"
+       "Display information for a route distinguisher\n"
+       "VPN Route Distinguisher\n"
+       "Network in the BGP routing table to display\n"
+       JSON_STR)
+{
+  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_IP6, SAFI_MPLS_VPN, &prd, 0, BGP_PATH_ALL, use_json (argc, argv));
+}
 
 DEFUN (show_ip_bgp_vpnv4_rd_route,
        show_ip_bgp_vpnv4_rd_route_cmd,
@@ -8139,15 +8733,6 @@ 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}",
@@ -8245,15 +8830,6 @@ DEFUN (show_bgp_prefix,
   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}",
-       SHOW_STR
-       BGP_STR
-       "Address family\n"
-       "IPv6 prefix <network>/<length>\n"
-       "JavaScript Object Notation\n")
-
 DEFUN (show_bgp_ipv6_safi_prefix,
        show_bgp_ipv6_safi_prefix_cmd,
        "show bgp ipv6 (unicast|multicast) X:X::X:X/M {json}",
@@ -9115,6 +9691,66 @@ 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")
+{
+    if (strncmp(argv[0], "m", 1) == 0)
+      return bgp_show_dampening_parameters (vty, AFI_IP, SAFI_MULTICAST);
+
+    return bgp_show_dampening_parameters (vty, AFI_IP, SAFI_UNICAST);
+}
+
+
+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")
+{
+    if (strncmp(argv[0], "m", 1) == 0)
+      return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
+                     bgp_show_type_flap_statistics, NULL, 0);
+
+    return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
+                 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")
+{
+    if (strncmp(argv[0], "m", 1) == 0)
+      return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
+                     bgp_show_type_dampend_paths, NULL, 0);
+
+    return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
+                 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,
@@ -11195,7 +11831,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;
     }
@@ -11287,7 +11923,7 @@ 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)
@@ -11306,18 +11942,20 @@ bgp_table_stats_vty (struct vty *vty, const char *name,
         safi = SAFI_MULTICAST;
       else if (strncmp (safi_str, "u", 1) == 0)
         safi = SAFI_UNICAST;
+      else if (strncmp (safi_str, "e", 1) == 0)
+        safi = SAFI_ENCAP;
       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;
-        }
+            return CMD_WARNING;
+      }
     }
   else
     {
-      vty_out (vty, "%% Invalid address family %s%s",
+      vty_out (vty, "%% Invalid address family \"%s\"%s",
                afi_str, VTY_NEWLINE);
       return CMD_WARNING;
     }
@@ -11327,30 +11965,23 @@ 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 (ipv4|ipv6) (encap|multicast|unicast|vpn) statistics",
        SHOW_STR
        BGP_STR
        "Address family\n"
        "Address family\n"
        "Address Family modifier\n"
        "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
        "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 " (ipv4|ipv6) (unicast|multicast|vpn|encap) statistics",
        SHOW_STR
        BGP_STR
        BGP_INSTANCE_HELP_STR
@@ -11358,21 +11989,13 @@ DEFUN (show_bgp_statistics_view,
        "Address family\n"
        "Address Family modifier\n"
        "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
        "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,
@@ -11492,7 +12115,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
@@ -11527,7 +12150,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
@@ -11764,7 +12387,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
@@ -11905,7 +12528,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);
     }
 
@@ -11925,7 +12548,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
@@ -11939,7 +12562,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
@@ -13307,7 +13930,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
 {
@@ -13335,12 +13958,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);
@@ -13350,7 +13978,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;
@@ -13382,19 +14010,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);
@@ -13423,10 +14056,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;
@@ -13435,21 +14069,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;
@@ -13457,7 +14081,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;
        }
@@ -13466,7 +14090,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;
@@ -13474,8 +14098,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;
        }
@@ -13483,14 +14107,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;
     }
 }
@@ -13505,12 +14129,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;
 }
 
@@ -13525,12 +14153,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;
 }
 
@@ -13589,6 +14221,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>",
@@ -13763,9 +14443,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;
@@ -13882,6 +14562,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)
@@ -13933,7 +14614,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. */
@@ -14022,40 +14703,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);
@@ -14261,7 +14955,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);
@@ -14281,160 +14978,13 @@ 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_vpn_rd_route_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv4_vpn_route_cmd);
+
+  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_route_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_route_cmd);
 
  /* BGP dampening clear commands */
   install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
@@ -14568,145 +15118,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);
@@ -14746,61 +15163,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);
@@ -14810,6 +15183,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);
@@ -14823,11 +15224,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;
+      }
 }