]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_route.c
Merge pull request #624 "Babel"
[mirror_frr.git] / bgpd / bgp_route.c
index 3cfb118828d0d0da5036c7e9eeb28a26998051e1..31c1dd8c101d0fa82574bc2061d94eeac7e9e465 100644 (file)
@@ -1,23 +1,23 @@
 /* BGP routing information
  Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
  Copyright (C) 2016 Job Snijders <job@instituut.net>
-
-This file is part of GNU Zebra.
-
-GNU Zebra is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-GNU Zebra is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Zebra; see the file COPYING.  If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
* Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
* Copyright (C) 2016 Job Snijders <job@instituut.net>
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
 
 #include <zebra.h>
 
@@ -35,6 +35,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "thread.h"
 #include "workqueue.h"
 #include "queue.h"
+#include "mpls.h"
 #include "memory.h"
 #include "lib/json.h"
 
@@ -53,7 +54,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "bgpd/bgp_filter.h"
 #include "bgpd/bgp_fsm.h"
 #include "bgpd/bgp_mplsvpn.h"
-#include "bgpd/bgp_encap.h"
 #include "bgpd/bgp_nexthop.h"
 #include "bgpd/bgp_damp.h"
 #include "bgpd/bgp_advertise.h"
@@ -62,6 +62,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "bgpd/bgp_mpath.h"
 #include "bgpd/bgp_nht.h"
 #include "bgpd/bgp_updgrp.h"
+#include "bgpd/bgp_label.h"
 
 #if ENABLE_BGP_VNC
 #include "bgpd/rfapi/rfapi_backend.h"
@@ -296,6 +297,11 @@ bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri)
     }
 }
 
+static int
+bgp_label_index_differs (struct bgp_info *ri1, struct bgp_info *ri2)
+{
+  return (!(ri1->attr->extra->label_index == ri2->attr->extra->label_index));
+}
 
 /* Set/unset bgp_info flags, adjusting any other state as needed.
  * This is here primarily to keep prefix-count in check.
@@ -1187,7 +1193,8 @@ subgroup_announce_reset_nhop (u_char family, struct attr *attr)
 }
 
 int
-subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
+subgroup_announce_check (struct bgp_node *rn, struct bgp_info *ri,
+                         struct update_subgroup *subgrp,
                         struct prefix *p, struct attr *attr)
 {
   struct bgp_filter *filter;
@@ -1261,6 +1268,21 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
        return 0;
       }
 
+  /* If it's labeled safi, make sure the route has a valid label. */
+  if (safi == SAFI_LABELED_UNICAST)
+    {
+      u_char *tag = bgp_adv_label(rn, ri, peer, afi, safi);
+      if (!bgp_is_valid_label(tag))
+        {
+          if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
+           zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s/%d is filtered - no label (%p)",
+                  subgrp->update_group->id, subgrp->id,
+                 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+                 p->prefixlen, tag);
+          return 0;
+        }
+    }
+
   /* Do not send back route to sender. */
   if (onlypeer && from == onlypeer)
     {
@@ -1433,7 +1455,7 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
 
 #define NEXTHOP_IS_V6 (\
     (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
-     (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
+     (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) || \
     ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
      attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
 
@@ -1535,7 +1557,7 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
           if (!reflect ||
               CHECK_FLAG (peer->af_flags[afi][safi],
                           PEER_FLAG_FORCE_NEXTHOP_SELF))
-            subgroup_announce_reset_nhop ((peer_cap_enhe(peer) ?
+            subgroup_announce_reset_nhop ((peer_cap_enhe(peer, afi, safi) ?
                           AF_INET6 : p->family), attr);
         }
       else if (peer->sort == BGP_PEER_EBGP)
@@ -1550,14 +1572,14 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
                 break;
             }
           if (!paf)
-            subgroup_announce_reset_nhop ((peer_cap_enhe(peer) ? AF_INET6 : p->family), attr);
+            subgroup_announce_reset_nhop ((peer_cap_enhe(peer, afi, safi) ? AF_INET6 : p->family), attr);
         }
       /* If IPv6/MP and nexthop does not have any override and happens to
        * be a link-local address, reset it so that we don't pass along the
        * source's link-local IPv6 address to recipients who may not be on
        * the same interface.
        */
-      if (p->family == AF_INET6 || peer_cap_enhe(peer))
+      if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))
         {
           if (IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
             subgroup_announce_reset_nhop (AF_INET6, attr);
@@ -1804,7 +1826,7 @@ subgroup_process_announce_selected (struct update_subgroup *subgrp,
   /* Announcement to the subgroup.  If the route is filtered withdraw it. */
   if (selected)
     {
-      if (subgroup_announce_check(selected, subgrp, p, &attr))
+      if (subgroup_announce_check(rn, selected, subgrp, p, &attr))
         bgp_adj_out_set_subgroup(rn, subgrp, &attr, selected);
       else
         bgp_adj_out_unset_subgroup(rn, subgrp, 1, selected->addpath_tx_id);
@@ -1914,7 +1936,40 @@ bgp_process_main (struct work_queue *wq, void *data)
   old_select = old_and_new.old;
   new_select = old_and_new.new;
 
-  /* Nothing to do. */
+  /* Do we need to allocate or free labels?
+   * Right now, since we only deal with per-prefix labels, it is not necessary
+   * to do this upon changes to best path except of the label index changes.
+   */
+  if (safi == SAFI_LABELED_UNICAST)
+    {
+      bgp_table_lock (bgp_node_table (rn));
+      if (new_select)
+        {
+          if (!old_select ||
+              bgp_label_index_differs (new_select, old_select) ||
+              new_select->sub_type != old_select->sub_type)
+            {
+              if (new_select->sub_type == BGP_ROUTE_STATIC &&
+                  new_select->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID) &&
+                  new_select->attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
+                {
+                  if (CHECK_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
+                    bgp_unregister_for_label (rn);
+                  label_ntop (MPLS_IMP_NULL_LABEL, 1, rn->local_label);
+                  bgp_set_valid_label(rn->local_label);
+                }
+              else
+                bgp_register_for_label (rn, new_select);
+            }
+        }
+      else if (CHECK_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
+        bgp_unregister_for_label (rn);
+    }
+
+  /* If best route remains the same and this is not due to user-initiated
+   * clear, see exactly what needs to be done.
+   */
+
   if (old_select && old_select == new_select &&
       !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR) &&
       !CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED) &&
@@ -1926,10 +1981,26 @@ bgp_process_main (struct work_queue *wq, void *data)
               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);
+          if (bgp_fibupd_safi(safi) &&
+              !bgp->name &&
+              !bgp_option_check (BGP_OPT_NO_FIB) &&
+              new_select->type == ZEBRA_ROUTE_BGP &&
+              new_select->sub_type == BGP_ROUTE_NORMAL)
+            bgp_zebra_announce (rn, p, old_select, bgp, afi, safi);
         }
       UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
       bgp_zebra_clear_route_change_flags (rn);
+
+      /* If there is a change of interest to peers, reannounce the route. */
+      if (CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED) ||
+          CHECK_FLAG (rn->flags, BGP_NODE_LABEL_CHANGED))
+        {
+          group_announce_route(bgp, afi, safi, rn, new_select);
+
+          UNSET_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED);
+          UNSET_FLAG (rn->flags, BGP_NODE_LABEL_CHANGED);
+         }
+
       UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
       return WQ_SUCCESS;
     }
@@ -1945,9 +2016,10 @@ bgp_process_main (struct work_queue *wq, void *data)
       if (!bgp->t_rmap_def_originate_eval)
         {
           bgp_lock (bgp);
-          THREAD_TIMER_ON(bm->master, bgp->t_rmap_def_originate_eval,
-                          update_group_refresh_default_originate_route_map,
-                          bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER);
+          thread_add_timer(bm->master,
+                           update_group_refresh_default_originate_route_map,
+                           bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
+                           &bgp->t_rmap_def_originate_eval);
         }
     }
 
@@ -1978,7 +2050,7 @@ bgp_process_main (struct work_queue *wq, void *data)
   group_announce_route(bgp, afi, safi, rn, new_select);
 
   /* FIB update. */
-  if ((safi == SAFI_UNICAST || safi == SAFI_MULTICAST) &&
+  if (bgp_fibupd_safi(safi) &&
       (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW) &&
       !bgp_option_check (BGP_OPT_NO_FIB))
     {
@@ -1986,7 +2058,7 @@ bgp_process_main (struct work_queue *wq, void *data)
          && new_select->type == ZEBRA_ROUTE_BGP 
          && (new_select->sub_type == BGP_ROUTE_NORMAL ||
               new_select->sub_type == BGP_ROUTE_AGGREGATE))
-       bgp_zebra_announce (p, new_select, bgp, afi, safi);
+       bgp_zebra_announce (rn, p, new_select, bgp, afi, safi);
       else
        {
          /* Withdraw the route from the kernel. */
@@ -2406,6 +2478,7 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
   struct bgp_info *new;
   const char *reason;
   char pfx_buf[BGP_PRD_PATH_STRLEN];
+  char label_buf[20];
   int connected = 0;
   int do_loop_check = 1;
 #if ENABLE_BGP_VNC
@@ -2417,6 +2490,9 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
 
   bgp = peer->bgp;
   rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
+  label_buf[0] = '\0';
+  if (bgp_labeled_safi(safi))
+    sprintf (label_buf, "label %u", label_pton(tag));
   
   /* When peer's soft reconfiguration enabled.  Record input packet in
      Adj-RIBs-In.  */
@@ -2516,6 +2592,8 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
       /* Same attribute comes in. */
       if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED) 
           && attrhash_cmp (ri->attr, attr_new)
+          && (!bgp_labeled_safi(safi) ||
+              memcmp ((bgp_info_extra_get (ri))->tag, tag, 3) == 0)
           && (overlay_index_equal(afi, ri, evpn==NULL?NULL:&evpn->eth_s_id,
                                   evpn==NULL?NULL:&evpn->gw_ip)))
        {
@@ -2524,9 +2602,9 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
              && CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
            {
              if (bgp_debug_update(peer, p, NULL, 1))
-                zlog_debug ("%s rcvd %s", peer->host,
+                zlog_debug ("%s rcvd %s %s", peer->host,
                             bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
-                                      addpath_id, pfx_buf, sizeof (pfx_buf)));
+                                      addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
 
              if (bgp_damp_update (ri, rn, afi, safi) != BGP_DAMP_SUPPRESSED)
                {
@@ -2544,10 +2622,10 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
                     peer->rcvd_attr_printed = 1;
                   }
 
-                 zlog_debug ("%s rcvd %s...duplicate ignored",
+                 zlog_debug ("%s rcvd %s %s...duplicate ignored",
                              peer->host,
                               bgp_debug_rdpfxpath2str (prd, p, addpath_id ?
-                                1 : 0, addpath_id, pfx_buf, sizeof (pfx_buf)));
+                                1 : 0, addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
                 }
 
              /* graceful restart STALE flag unset. */
@@ -2568,18 +2646,18 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
       if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
         {
           if (bgp_debug_update(peer, p, NULL, 1))
-            zlog_debug ("%s rcvd %s, flapped quicker than processing",
+            zlog_debug ("%s rcvd %s %s, flapped quicker than processing",
                         peer->host,
                         bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
-                                  addpath_id, pfx_buf, sizeof (pfx_buf)));
+                                  addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
           bgp_info_restore (rn, ri);
         }
 
       /* Received Logging. */
       if (bgp_debug_update(peer, p, NULL, 1))
-         zlog_debug ("%s rcvd %s", peer->host,
+         zlog_debug ("%s rcvd %s %s", peer->host,
                       bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
-                                        addpath_id, pfx_buf, sizeof (pfx_buf)));
+                                        addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
 
       /* graceful restart STALE flag unset. */
       if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
@@ -2637,7 +2715,7 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
       ri->attr = attr_new;
 
       /* Update MPLS tag.  */
-      if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN)
+      if (bgp_labeled_safi(safi))
         memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
 
 #if ENABLE_BGP_VNC
@@ -2678,8 +2756,9 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
            }
        }
 
-      /* Nexthop reachability check. */
-      if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
+      /* Nexthop reachability check - for unicast and labeled-unicast.. */
+      if ((afi == AFI_IP || afi == AFI_IP6) &&
+          (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
        {
          if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
              ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
@@ -2759,16 +2838,16 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
           peer->rcvd_attr_printed = 1;
         }
 
-      zlog_debug ("%s rcvd %s", peer->host,
+      zlog_debug ("%s rcvd %s %s ", peer->host,
                   bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
-                                 addpath_id, pfx_buf, sizeof (pfx_buf)));
+                                 addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
     }
 
   /* Make new BGP info. */
   new = info_make(type, sub_type, 0, peer, attr_new, rn);
 
   /* Update MPLS tag. */
-  if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN)
+  if (bgp_labeled_safi(safi))
     memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
 
   /* Update Overlay Index */
@@ -2778,7 +2857,8 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
                            evpn==NULL?NULL:&evpn->gw_ip);
     }
   /* Nexthop reachability check. */
-  if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
+  if ((afi == AFI_IP || afi == AFI_IP6) &&
+       (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
     {
       if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
          ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
@@ -2873,10 +2953,10 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
           peer->rcvd_attr_printed = 1;
         }
 
-      zlog_debug ("%s rcvd UPDATE about %s -- DENIED due to: %s",
+      zlog_debug ("%s rcvd UPDATE about %s %s -- DENIED due to: %s",
                   peer->host,
                   bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
-                             addpath_id, pfx_buf, sizeof (pfx_buf)), reason);
+                             addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf, reason);
     }
 
   if (ri)
@@ -3008,9 +3088,6 @@ bgp_announce_route_timer_expired (struct thread *t)
   paf = THREAD_ARG (t);
   peer = paf->peer;
 
-  assert (paf->t_announce_route);
-  paf->t_announce_route = NULL;
-
   if (peer->status != Established)
     return 0;
 
@@ -3050,11 +3127,9 @@ bgp_announce_route (struct peer *peer, afi_t afi, safi_t safi)
    * multiple peers and the announcement doesn't happen in the
    * vty context.
    */
-  THREAD_TIMER_MSEC_ON (bm->master, paf->t_announce_route,
-                       bgp_announce_route_timer_expired, paf,
-                        (subgrp->peer_count == 1) ?
-                       BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS :
-                       BGP_ANNOUNCE_ROUTE_DELAY_MS);
+  thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
+                        (subgrp->peer_count == 1) ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS : BGP_ANNOUNCE_ROUTE_DELAY_MS,
+                        &paf->t_announce_route);
 }
 
 /*
@@ -3702,9 +3777,9 @@ bgp_static_free (struct bgp_static *bgp_static)
   XFREE (MTYPE_BGP_STATIC, bgp_static);
 }
 
-static void
-bgp_static_update_main (struct bgp *bgp, struct prefix *p,
-                       struct bgp_static *bgp_static, afi_t afi, safi_t safi)
+void
+bgp_static_update (struct bgp *bgp, struct prefix *p,
+                   struct bgp_static *bgp_static, afi_t afi, safi_t safi)
 {
   struct bgp_node *rn;
   struct bgp_info *ri;
@@ -3732,6 +3807,13 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
   if (bgp_static->atomic)
     attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
 
+  /* Store label index, if required. */
+  if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
+    {
+      (bgp_attr_extra_get (&attr))->label_index = bgp_static->label_index;
+      attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID);
+    }
+
   /* Apply route-map. */
   if (bgp_static->rmap.name)
     {
@@ -3818,7 +3900,8 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
 #endif
 
          /* Nexthop reachability check. */
-         if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
+         if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK) &&
+             (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
            {
              if (bgp_find_or_add_nexthop (bgp, afi, ri, NULL, 0))
                bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
@@ -3858,7 +3941,8 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
   new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self, attr_new,
                  rn);
   /* Nexthop reachability check. */
-  if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
+  if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK) &&
+      (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
     {
       if (bgp_find_or_add_nexthop (bgp, afi, new, NULL, 0))
        bgp_info_set_flag (rn, new, BGP_INFO_VALID);
@@ -3903,13 +3987,6 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
   bgp_attr_extra_free (&attr);
 }
 
-void
-bgp_static_update (struct bgp *bgp, struct prefix *p,
-                  struct bgp_static *bgp_static, afi_t afi, safi_t safi)
-{
-  bgp_static_update_main (bgp, p, bgp_static, afi, safi);
-}
-
 void
 bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
                     safi_t safi)
@@ -4008,7 +4085,7 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
 
   if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
     {
-      if (bgp_static->igpnexthop.s_addr)
+      if (afi == AFI_IP)
         {
           bgp_attr_extra_get (&attr)->mp_nexthop_global_in = bgp_static->igpnexthop;
           bgp_attr_extra_get (&attr)->mp_nexthop_len = IPV4_MAX_BYTELEN;
@@ -4158,7 +4235,8 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
    route should be installed as valid.  */
 static int
 bgp_static_set (struct vty *vty, const char *ip_str, 
-                afi_t afi, safi_t safi, const char *rmap, int backdoor)
+                afi_t afi, safi_t safi, const char *rmap, int backdoor,
+                u_int32_t label_index)
 {
   VTY_DECLVAR_CONTEXT(bgp, bgp);
   int ret;
@@ -4191,6 +4269,13 @@ bgp_static_set (struct vty *vty, const char *ip_str,
       /* Configuration change. */
       bgp_static = rn->info;
 
+      /* Label index cannot be changed. */
+      if (bgp_static->label_index != label_index)
+        {
+          vty_out (vty, "%% Label index cannot be changed%s", VTY_NEWLINE);
+          return CMD_WARNING;
+        }
+
       /* Check previous routes are installed into BGP.  */
       if (bgp_static->valid && bgp_static->backdoor != backdoor)
         need_update = 1;
@@ -4222,6 +4307,7 @@ bgp_static_set (struct vty *vty, const char *ip_str,
       bgp_static->valid = 0;
       bgp_static->igpmetric = 0;
       bgp_static->igpnexthop.s_addr = 0;
+      bgp_static->label_index = label_index;
       
       if (rmap)
        {
@@ -4752,7 +4838,8 @@ DEFUN (bgp_network,
 {
   int idx_ipv4_prefixlen = 1;
   return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
-                        AFI_IP, bgp_node_safi (vty), NULL, 0);
+                        AFI_IP, bgp_node_safi (vty), NULL, 0,
+                         BGP_INVALID_LABEL_INDEX);
 }
 
 DEFUN (bgp_network_route_map,
@@ -4766,7 +4853,8 @@ DEFUN (bgp_network_route_map,
   int idx_ipv4_prefixlen = 1;
   int idx_word = 3;
   return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
-                        AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
+                        AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0,
+                         BGP_INVALID_LABEL_INDEX);
 }
 
 DEFUN (bgp_network_backdoor,
@@ -4778,7 +4866,7 @@ DEFUN (bgp_network_backdoor,
 {
   int idx_ipv4_prefixlen = 1;
   return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP, SAFI_UNICAST,
-                         NULL, 1);
+                         NULL, 1, BGP_INVALID_LABEL_INDEX);
 }
 
 DEFUN (bgp_network_mask,
@@ -4802,7 +4890,7 @@ DEFUN (bgp_network_mask,
     }
 
   return bgp_static_set (vty, prefix_str,
-                        AFI_IP, bgp_node_safi (vty), NULL, 0);
+                        AFI_IP, bgp_node_safi (vty), NULL, 0, BGP_INVALID_LABEL_INDEX);
 }
 
 DEFUN (bgp_network_mask_route_map,
@@ -4829,7 +4917,7 @@ DEFUN (bgp_network_mask_route_map,
     }
 
   return bgp_static_set (vty, prefix_str,
-                        AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
+                        AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0, BGP_INVALID_LABEL_INDEX);
 }
 
 DEFUN (bgp_network_mask_backdoor,
@@ -4854,7 +4942,8 @@ DEFUN (bgp_network_mask_backdoor,
     }
 
   return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
-                         NULL, 1);
+                         NULL, 1,
+                         BGP_INVALID_LABEL_INDEX);
 }
 
 DEFUN (bgp_network_mask_natural,
@@ -4875,7 +4964,8 @@ DEFUN (bgp_network_mask_natural,
     }
 
   return bgp_static_set (vty, prefix_str,
-                        AFI_IP, bgp_node_safi (vty), NULL, 0);
+                        AFI_IP, bgp_node_safi (vty), NULL, 0,
+                         BGP_INVALID_LABEL_INDEX);
 }
 
 DEFUN (bgp_network_mask_natural_route_map,
@@ -4899,7 +4989,8 @@ DEFUN (bgp_network_mask_natural_route_map,
     }
 
   return bgp_static_set (vty, prefix_str,
-                        AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
+                        AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0,
+                         BGP_INVALID_LABEL_INDEX);
 }
 
 DEFUN (bgp_network_mask_natural_backdoor,
@@ -4921,7 +5012,39 @@ DEFUN (bgp_network_mask_natural_backdoor,
     }
 
   return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
-                         NULL, 1);
+                         NULL, 1, BGP_INVALID_LABEL_INDEX);
+}
+
+DEFUN (bgp_network_label_index,
+       bgp_network_label_index_cmd,
+       "network A.B.C.D/M label-index (0-1048560)",
+       "Specify a network to announce via BGP\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+       "Label index to associate with the prefix\n"
+       "Label index value\n")
+{
+  u_int32_t label_index;
+
+  VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
+  return bgp_static_set (vty, argv[1]->arg,
+                         AFI_IP, bgp_node_safi (vty), NULL, 0, label_index);
+}
+
+DEFUN (bgp_network_label_index_route_map,
+       bgp_network_label_index_route_map_cmd,
+       "network A.B.C.D/M label-index (0-1048560) route-map WORD",
+       "Specify a network to announce via BGP\n"
+       "IP prefix\n"
+       "Label index to associate with the prefix\n"
+       "Label index value\n"
+       "Route-map to modify the attributes\n"
+       "Name of the route map\n")
+{
+  u_int32_t label_index;
+
+  VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
+  return bgp_static_set (vty, argv[1]->arg,
+                         AFI_IP, bgp_node_safi (vty), argv[5]->arg, 0, label_index);
 }
 
 DEFUN (no_bgp_network,
@@ -4992,6 +5115,26 @@ DEFUN (no_bgp_network_mask_natural,
                           bgp_node_safi (vty));
 }
 
+ALIAS (no_bgp_network,
+       no_bgp_network_label_index_cmd,
+       "no network A.B.C.D/M label-index (0-1048560)",
+       NO_STR
+       "Specify a network to announce via BGP\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+       "Label index to associate with the prefix\n"
+       "Label index value\n")
+
+ALIAS (no_bgp_network,
+       no_bgp_network_label_index_route_map_cmd,
+       "no network A.B.C.D/M label-index (0-1048560) route-map WORD",
+       NO_STR
+       "Specify a network to announce via BGP\n"
+       "IP prefix\n"
+       "Label index to associate with the prefix\n"
+       "Label index value\n"
+       "Route-map to modify the attributes\n"
+       "Name of the route map\n")
+
 DEFUN (ipv6_bgp_network,
        ipv6_bgp_network_cmd,
        "network X:X::X:X/M",
@@ -5000,7 +5143,8 @@ DEFUN (ipv6_bgp_network,
 {
   int idx_ipv6_prefixlen = 1;
   return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty),
-                         NULL, 0);
+                         NULL, 0,
+                         BGP_INVALID_LABEL_INDEX);
 }
 
 DEFUN (ipv6_bgp_network_route_map,
@@ -5014,7 +5158,40 @@ DEFUN (ipv6_bgp_network_route_map,
   int idx_ipv6_prefixlen = 1;
   int idx_word = 3;
   return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
-                        bgp_node_safi (vty), argv[idx_word]->arg, 0);
+                        bgp_node_safi (vty), argv[idx_word]->arg, 0,
+                         BGP_INVALID_LABEL_INDEX);
+}
+
+DEFUN (ipv6_bgp_network_label_index,
+       ipv6_bgp_network_label_index_cmd,
+       "network X:X::X:X/M label-index (0-1048560)",
+       "Specify a network to announce via BGP\n"
+       "IPv6 prefix <network>/<length>\n"
+       "Label index to associate with the prefix\n"
+       "Label index value\n")
+{
+  u_int32_t label_index;
+
+  VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
+  return bgp_static_set (vty, argv[1]->arg,
+                         AFI_IP6, bgp_node_safi (vty), NULL, 0, label_index);
+}
+
+DEFUN (ipv6_bgp_network_label_index_route_map,
+       ipv6_bgp_network_label_index_route_map_cmd,
+       "network X:X::X:X/M label-index (0-1048560) route-map WORD",
+       "Specify a network to announce via BGP\n"
+       "IPv6 prefix\n"
+       "Label index to associate with the prefix\n"
+       "Label index value\n"
+       "Route-map to modify the attributes\n"
+       "Name of the route map\n")
+{
+  u_int32_t label_index;
+
+  VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
+  return bgp_static_set (vty, argv[1]->arg,
+                         AFI_IP6, bgp_node_safi (vty), argv[5]->arg, 0, label_index);
 }
 
 DEFUN (no_ipv6_bgp_network,
@@ -5030,6 +5207,26 @@ DEFUN (no_ipv6_bgp_network,
   return bgp_static_unset (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty));
 }
 
+ALIAS (no_ipv6_bgp_network,
+       no_ipv6_bgp_network_label_index_cmd,
+       "no network X:X::X:X/M label-index (0-1048560)",
+       NO_STR
+       "Specify a network to announce via BGP\n"
+       "IPv6 prefix <network>/<length>\n"
+       "Label index to associate with the prefix\n"
+       "Label index value\n")
+
+ALIAS (no_ipv6_bgp_network,
+       no_ipv6_bgp_network_label_index_route_map_cmd,
+       "no network X:X::X:X/M label-index (0-1048560) route-map WORD",
+       NO_STR
+       "Specify a network to announce via BGP\n"
+       "IPv6 prefix\n"
+       "Label index to associate with the prefix\n"
+       "Label index value\n"
+       "Route-map to modify the attributes\n"
+       "Name of the route map\n")
+
 /* Aggreagete address:
 
   advertise-map  Set condition to advertise attribute
@@ -5559,9 +5756,11 @@ bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
     }
 
   aggregate = rn->info;
-  if (aggregate->safi & SAFI_UNICAST)
+  if (aggregate->safi == SAFI_UNICAST)
     bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
-  if (aggregate->safi & SAFI_MULTICAST)
+  if (aggregate->safi == SAFI_LABELED_UNICAST)
+    bgp_aggregate_delete (bgp, &p, afi, SAFI_LABELED_UNICAST, aggregate);
+  if (aggregate->safi == SAFI_MULTICAST)
     bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
 
   /* Unlock aggregate address configuration. */
@@ -5617,9 +5816,11 @@ bgp_aggregate_set (struct vty *vty, const char *prefix_str,
   rn->info = aggregate;
 
   /* Aggregate address insert into BGP routing table. */
-  if (safi & SAFI_UNICAST)
+  if (safi == SAFI_UNICAST)
     bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate);
-  if (safi & SAFI_MULTICAST)
+  if (safi == SAFI_LABELED_UNICAST)
+    bgp_aggregate_add (bgp, &p, afi, SAFI_LABELED_UNICAST, aggregate);
+  if (safi == SAFI_MULTICAST)
     bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate);
 
   return CMD_SUCCESS;
@@ -5658,9 +5859,8 @@ DEFUN (aggregate_address_mask,
 {
   int idx = 0;
   argv_find (argv, argc, "A.B.C.D", &idx);
-  char *prefix = argv[idx++]->arg;
-  argv_find (argv, argc, "A.B.C.D", &idx);
-  char *mask = argv[idx]->arg;
+  char *prefix = argv[idx]->arg;
+  char *mask = argv[idx+1]->arg;
   int as_set = argv_find (argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
   idx = 0;
   int summary_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
@@ -5708,9 +5908,8 @@ DEFUN (no_aggregate_address_mask,
 {
   int idx = 0;
   argv_find (argv, argc, "A.B.C.D", &idx);
-  char *prefix = argv[idx++]->arg;
-  argv_find (argv, argc, "A.B.C.D", &idx);
-  char *mask = argv[idx]->arg;
+  char *prefix = argv[idx]->arg;
+  char *mask = argv[idx+1]->arg;
 
   char prefix_str[BUFSIZ];
   int ret = netmask_str2prefix_str (prefix, mask, prefix_str);
@@ -7443,6 +7642,25 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
       if (binfo->extra && binfo->extra->damp_info)
        bgp_damp_info_vty (vty, binfo, json_path);
 
+      /* Remove Label */
+      if (bgp_labeled_safi(safi) && binfo->extra)
+        {
+          uint32_t label = label_pton(binfo->extra->tag);
+          if (json_paths)
+            json_object_int_add(json_path, "remoteLabel", label);
+          else
+            vty_out(vty, "      Remote label: %d%s", label, VTY_NEWLINE);
+        }
+
+      /* Label Index */
+      if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
+        {
+          if (json_paths)
+            json_object_int_add(json_path, "labelIndex", attr->extra->label_index);
+          else
+            vty_out(vty, "      Label Index: %d%s", attr->extra->label_index, VTY_NEWLINE);
+        }
+
       /* Line 8 display Addpath IDs */
       if (binfo->addpath_rx_id || binfo->addpath_tx_id)
         {
@@ -7840,12 +8058,6 @@ bgp_show (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
       return bgp_show_mpls_vpn(vty, afi, NULL, type, output_arg,
                                0, use_json);
     }
-  if (safi == SAFI_ENCAP) 
-    {
-      return bgp_show_encap(vty, afi, NULL, type, output_arg,
-                            0);
-    }
-
 
   table = bgp->rib[afi][safi];
 
@@ -7859,7 +8071,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;
   int is_first = 1;
 
   if (use_json)
@@ -7885,9 +8096,7 @@ bgp_show_all_instances_routes_vty (struct vty *vty, afi_t afi, safi_t safi,
                    ? "Default" : bgp->name,
                    VTY_NEWLINE);
         }
-      table = bgp->rib[afi][safi];
-      bgp_show_table (vty, bgp, table,
-                      bgp_show_type_normal, NULL, use_json);
+      bgp_show (vty, bgp, afi, safi, bgp_show_type_normal, NULL, use_json);
 
     }
 
@@ -7936,6 +8145,18 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
               ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) ? ":" : "",
               buf2,
               p->prefixlen, VTY_NEWLINE);
+
+      if (bgp_labeled_safi(safi))
+        {
+          vty_out(vty, "Local label: ");
+          if (!bgp_is_valid_label(rn->local_label))
+            vty_out(vty, "not allocated%s", VTY_NEWLINE);
+          else
+            {
+              uint32_t label = label_pton(rn->local_label);
+              vty_out(vty, "%d%s", label, VTY_NEWLINE);
+            }
+        }
     }
 
   for (ri = rn->info; ri; ri = ri->next)
@@ -8217,7 +8438,7 @@ bgp_show_lcommunity_list (struct vty *vty, struct bgp *bgp, const char *lcom,
 
 DEFUN (show_ip_bgp_large_community_list,
        show_ip_bgp_large_community_list_cmd,
-       "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community-list <(1-500)|WORD> [json]",
+       "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community-list <(1-500)|WORD> [json]",
        SHOW_STR
        IP_STR
        BGP_STR
@@ -8263,7 +8484,7 @@ DEFUN (show_ip_bgp_large_community_list,
 }
 DEFUN (show_ip_bgp_large_community,
        show_ip_bgp_large_community_cmd,
-       "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] large-community [AA:BB:CC] [json]",
+       "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community [AA:BB:CC] [json]",
        SHOW_STR
        IP_STR
        BGP_STR
@@ -8429,8 +8650,6 @@ DEFUN (show_ip_bgp,
 
   if (safi == SAFI_MPLS_VPN)
     return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, uj);
-  else if (safi == SAFI_ENCAP)
-    return bgp_show_encap (vty, afi, NULL, bgp_show_type_normal, NULL, 0);
   else
     return bgp_show (vty, bgp, afi, safi, sh_type, NULL, uj);
 }
@@ -8643,6 +8862,7 @@ bgp_show_community (struct vty *vty, struct bgp *bgp, int argc,
   int i;
   char *str;
   int first = 0;
+  int ret = 0;
 
   b = buffer_new (1024);
   for (i = 0; i < argc; i++)
@@ -8671,9 +8891,12 @@ bgp_show_community (struct vty *vty, struct bgp *bgp, int argc,
       return CMD_WARNING;
     }
 
-  return bgp_show (vty, bgp, afi, safi,
-                   (exact ? bgp_show_type_community_exact :
-                   bgp_show_type_community), com, 0);
+  ret = bgp_show (vty, bgp, afi, safi,
+                  (exact ? bgp_show_type_community_exact :
+                 bgp_show_type_community), com, 0);
+  community_free (com);
+
+  return ret;
 }
 
 static int
@@ -9214,7 +9437,7 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_c
 
 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
        show_ip_bgp_instance_neighbor_prefix_counts_cmd,
-       "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap>]] "
+       "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] "
        "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
        SHOW_STR
        IP_STR
@@ -9226,6 +9449,7 @@ DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
        "Address Family modifier\n"
        "Address Family modifier\n"
        "Address Family modifier\n"
+       "Address Family modifier\n"
        "Detailed information on TCP and BGP neighbor connections\n"
        "Neighbor to display information about\n"
        "Neighbor to display information about\n"
@@ -10434,10 +10658,12 @@ bgp_config_write_network_vpn (struct vty *vty, struct bgp *bgp,
            prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN);
            label = decode_label (bgp_static->tag);
 
-           vty_out (vty, "  network %s/%d rd %s label %d",
+           vty_out (vty, "  network %s/%d rd %s",
                     inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), 
-                    p->prefixlen,
-                    rdbuf, label);
+                    p->prefixlen, rdbuf);
+           if (safi == SAFI_MPLS_VPN)
+             vty_out (vty, " label %u", label);
+
             if (bgp_static->rmap.name)
               vty_out (vty, " route-map %s", bgp_static->rmap.name);
             else
@@ -10556,6 +10782,9 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,
                     p->prefixlen);
          }
 
+        if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
+         vty_out (vty, " label-index %u", bgp_static->label_index);
+
        if (bgp_static->rmap.name)
          vty_out (vty, " route-map %s", bgp_static->rmap.name);
        else 
@@ -10682,6 +10911,8 @@ bgp_route_init (void)
   install_element (BGP_IPV4_NODE, &bgp_network_route_map_cmd);
   install_element (BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd);
   install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd);
+  install_element (BGP_IPV4L_NODE, &no_bgp_network_label_index_cmd);
+  install_element (BGP_IPV4L_NODE, &no_bgp_network_label_index_route_map_cmd);
   install_element (BGP_IPV4_NODE, &no_bgp_table_map_cmd);
   install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
   install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd);
@@ -10709,6 +10940,21 @@ bgp_route_init (void)
   install_element (BGP_IPV4M_NODE, &no_aggregate_address_cmd);
   install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
 
+  /* IPv4 labeled-unicast configuration.  */
+  install_element (BGP_IPV4L_NODE, &bgp_table_map_cmd);
+  install_element (BGP_IPV4L_NODE, &bgp_network_cmd);
+  install_element (BGP_IPV4L_NODE, &bgp_network_mask_cmd);
+  install_element (BGP_IPV4L_NODE, &bgp_network_mask_natural_cmd);
+  install_element (BGP_IPV4L_NODE, &bgp_network_route_map_cmd);
+  install_element (BGP_IPV4L_NODE, &bgp_network_mask_route_map_cmd);
+  install_element (BGP_IPV4L_NODE, &bgp_network_mask_natural_route_map_cmd);
+  install_element (BGP_IPV4L_NODE, &bgp_network_label_index_cmd);
+  install_element (BGP_IPV4L_NODE, &bgp_network_label_index_route_map_cmd);
+  install_element (BGP_IPV4L_NODE, &no_bgp_table_map_cmd);
+  install_element (BGP_IPV4L_NODE, &no_bgp_network_cmd);
+  install_element (BGP_IPV4L_NODE, &no_bgp_network_mask_cmd);
+  install_element (BGP_IPV4L_NODE, &no_bgp_network_mask_natural_cmd);
+
   install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
@@ -10742,6 +10988,10 @@ bgp_route_init (void)
   install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd);
   install_element (BGP_IPV6_NODE, &no_bgp_table_map_cmd);
   install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd);
+  install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_label_index_cmd);
+  install_element (BGP_IPV6L_NODE, &no_ipv6_bgp_network_label_index_cmd);
+  install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_label_index_route_map_cmd);
+  install_element (BGP_IPV6L_NODE, &no_ipv6_bgp_network_label_index_route_map_cmd);
 
   install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
   install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
@@ -10749,6 +10999,12 @@ bgp_route_init (void)
   install_element (BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
   install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_network_cmd);
 
+  install_element (BGP_IPV6L_NODE, &bgp_table_map_cmd);
+  install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
+  install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_route_map_cmd);
+  install_element (BGP_IPV6L_NODE, &no_bgp_table_map_cmd);
+  install_element (BGP_IPV6L_NODE, &no_ipv6_bgp_network_cmd);
+
   install_element (BGP_NODE, &bgp_distance_cmd);
   install_element (BGP_NODE, &no_bgp_distance_cmd);
   install_element (BGP_NODE, &bgp_distance_source_cmd);