]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_vty.c
Merge pull request #5717 from pguibert6WIND/flowspec_issue_redistribute
[mirror_frr.git] / bgpd / bgp_vty.c
index fa236a24b74cbac45537f8de53f4c23fe759c169..696233e7a0ea5a3114434b21670412c0c0befaf1 100644 (file)
@@ -32,7 +32,7 @@
 #include "thread.h"
 #include "log.h"
 #include "memory.h"
-#include "memory_vty.h"
+#include "lib_vty.h"
 #include "hash.h"
 #include "queue.h"
 #include "filter.h"
 #include "bgpd/bgp_bfd.h"
 #include "bgpd/bgp_io.h"
 #include "bgpd/bgp_evpn.h"
+#include "bgpd/bgp_evpn_vty.h"
 #include "bgpd/bgp_addpath.h"
 #include "bgpd/bgp_mac.h"
+#include "bgpd/bgp_flowspec.h"
+#if ENABLE_BGP_VNC
+#include "bgpd/rfapi/bgp_rfapi_cfg.h"
+#endif
 
+FRR_CFG_DEFAULT_BOOL(BGP_IMPORT_CHECK,
+       { .val_long = true, .match_profile = "datacenter", },
+       { .val_long = false },
+)
+FRR_CFG_DEFAULT_BOOL(BGP_SHOW_HOSTNAME,
+       { .val_long = true, .match_profile = "datacenter", },
+       { .val_long = false },
+)
+FRR_CFG_DEFAULT_BOOL(BGP_LOG_NEIGHBOR_CHANGES,
+       { .val_long = true, .match_profile = "datacenter", },
+       { .val_long = false },
+)
+FRR_CFG_DEFAULT_BOOL(BGP_DETERMINISTIC_MED,
+       { .val_long = true, .match_profile = "datacenter", },
+       { .val_long = false },
+)
+FRR_CFG_DEFAULT_ULONG(BGP_CONNECT_RETRY,
+       { .val_ulong = 10, .match_profile = "datacenter", },
+       { .val_ulong = 120 },
+)
+FRR_CFG_DEFAULT_ULONG(BGP_HOLDTIME,
+       { .val_ulong = 9, .match_profile = "datacenter", },
+       { .val_ulong = 180 },
+)
+FRR_CFG_DEFAULT_ULONG(BGP_KEEPALIVE,
+       { .val_ulong = 3, .match_profile = "datacenter", },
+       { .val_ulong = 60 },
+)
+
+DEFINE_HOOK(bgp_inst_config_write,
+               (struct bgp *bgp, struct vty *vty),
+               (bgp, vty))
+
+#define GR_NO_OPER "The Graceful Restart No Operation was executed as cmd same as previous one."
+#define GR_INVALID "The Graceful Restart command used is not valid at this moment."
 static struct peer_group *listen_range_exists(struct bgp *bgp,
                                              struct prefix *range, int exact);
 
+/* Show BGP peer's information. */
+enum show_type {
+       show_all,
+       show_peer,
+       show_ipv4_all,
+       show_ipv6_all,
+       show_ipv4_peer,
+       show_ipv6_peer
+};
+
+static struct peer_group *listen_range_exists(
+                                               struct bgp *bgp,
+                                               struct prefix *range,
+                                               int exact);
+
+static void bgp_show_global_graceful_restart_mode_vty(
+                                       struct vty *vty,
+                                       struct bgp *bgp,
+                                       bool use_json,
+                                       json_object *json);
+
+static int bgp_show_neighbor_graceful_restart_afi_all(
+                               struct vty *vty,
+                               enum show_type type,
+                               const char *ip_str,
+                               afi_t afi,
+                               bool use_json);
+
 static enum node_type bgp_node_type(afi_t afi, safi_t safi)
 {
        switch (afi) {
@@ -347,6 +415,29 @@ int argv_find_and_parse_safi(struct cmd_token **argv, int argc, int *index,
        return ret;
 }
 
+int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
+               enum bgp_instance_type inst_type)
+{
+       int ret = bgp_get(bgp, as, name, inst_type);
+
+       if (ret == BGP_CREATED) {
+               bgp_timers_set(*bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME,
+                              DFLT_BGP_CONNECT_RETRY);
+
+               if (DFLT_BGP_IMPORT_CHECK)
+                       bgp_flag_set(*bgp, BGP_FLAG_IMPORT_CHECK);
+               if (DFLT_BGP_SHOW_HOSTNAME)
+                       bgp_flag_set(*bgp, BGP_FLAG_SHOW_HOSTNAME);
+               if (DFLT_BGP_LOG_NEIGHBOR_CHANGES)
+                       bgp_flag_set(*bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+               if (DFLT_BGP_DETERMINISTIC_MED)
+                       bgp_flag_set(*bgp, BGP_FLAG_DETERMINISTIC_MED);
+
+               ret = BGP_SUCCESS;
+       }
+       return ret;
+}
+
 /*
  * bgp_vty_find_and_parse_afi_safi_bgp
  *
@@ -629,7 +720,16 @@ int bgp_vty_return(struct vty *vty, int ret)
                str = "Operation not allowed on a directly connected neighbor";
                break;
        case BGP_ERR_PEER_SAFI_CONFLICT:
-               str = "Cannot activate peer for both 'ipv4 unicast' and 'ipv4 labeled-unicast'";
+               str = GR_INVALID;
+               break;
+       case BGP_ERR_GR_INVALID_CMD:
+               str = "The Graceful Restart command used is not valid at this moment.";
+               break;
+       case BGP_ERR_GR_OPERATION_FAILED:
+               str = "The Graceful Restart Operation failed due to an err.";
+               break;
+       case BGP_GR_NO_OPERATION:
+               str = GR_NO_OPER;
                break;
        }
        if (str) {
@@ -724,7 +824,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
        int ret = 0;
        bool found = false;
        struct peer *peer;
-       struct listnode *node, *nnode;
+
+       VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
 
        /* Clear all neighbors. */
        /*
@@ -734,11 +835,27 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
         */
        if (sort == clear_all) {
                for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+
+                       bgp_peer_gr_flags_update(peer);
+
+                       if (CHECK_FLAG(peer->flags,
+                                       PEER_FLAG_GRACEFUL_RESTART))
+                               gr_router_detected = true;
+
                        ret = bgp_peer_clear(peer, afi, safi, nnode,
                                                          stype);
 
                        if (ret < 0)
                                bgp_clear_vty_error(vty, peer, afi, safi, ret);
+
+               }
+
+               if (gr_router_detected &&
+                       bgp->present_zebra_gr_state == ZEBRA_GR_DISABLE) {
+                       bgp_zebra_send_capabilities(bgp, false);
+               } else if (!gr_router_detected &&
+                       bgp->present_zebra_gr_state == ZEBRA_GR_ENABLE) {
+                       bgp_zebra_send_capabilities(bgp, true);
                }
 
                /* This is to apply read-only mode on this clear. */
@@ -775,6 +892,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                        }
                }
 
+               VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+               VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
+
                ret = bgp_peer_clear(peer, afi, safi, NULL, stype);
 
                /* if afi/safi not defined for this peer, let caller know */
@@ -820,6 +940,12 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                        if (peer->sort == BGP_PEER_IBGP)
                                continue;
 
+                       bgp_peer_gr_flags_update(peer);
+
+                       if (CHECK_FLAG(peer->flags,
+                               PEER_FLAG_GRACEFUL_RESTART))
+                               gr_router_detected = true;
+
                        ret = bgp_peer_clear(peer, afi, safi, nnode, stype);
 
                        if (ret < 0)
@@ -828,6 +954,14 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                                found = true;
                }
 
+               if (gr_router_detected &&
+                       bgp->present_zebra_gr_state == ZEBRA_GR_DISABLE) {
+                       bgp_zebra_send_capabilities(bgp, false);
+               } else if (!gr_router_detected &&
+                       bgp->present_zebra_gr_state == ZEBRA_GR_ENABLE) {
+                       bgp_zebra_send_capabilities(bgp, true);
+               }
+
                if (!found)
                        vty_out(vty,
                                "%%BGP: No external %s peer is configured\n",
@@ -844,6 +978,12 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                        if (peer->as != as)
                                continue;
 
+                       bgp_peer_gr_flags_update(peer);
+
+                       if (CHECK_FLAG(peer->flags,
+                               PEER_FLAG_GRACEFUL_RESTART))
+                               gr_router_detected = true;
+
                        ret = bgp_peer_clear(peer, afi, safi, nnode, stype);
 
                        if (ret < 0)
@@ -852,6 +992,14 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                                found = true;
                }
 
+               if (gr_router_detected &&
+                       bgp->present_zebra_gr_state == ZEBRA_GR_DISABLE) {
+                       bgp_zebra_send_capabilities(bgp, false);
+               } else if (!gr_router_detected &&
+                       bgp->present_zebra_gr_state == ZEBRA_GR_ENABLE) {
+                       bgp_zebra_send_capabilities(bgp, true);
+               }
+
                if (!found)
                        vty_out(vty,
                                "%%BGP: No %s peer is configured with AS %s\n",
@@ -1068,7 +1216,7 @@ DEFUN_NOSH (router_bgp,
                if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
                        is_new_bgp = (bgp_lookup(as, name) == NULL);
 
-               ret = bgp_get(&bgp, &as, name, inst_type);
+               ret = bgp_get_vty(&bgp, &as, name, inst_type);
                switch (ret) {
                case BGP_ERR_AS_MISMATCH:
                        vty_out(vty, "BGP is already running; AS is %u\n", as);
@@ -1777,8 +1925,8 @@ ALIAS_HIDDEN(no_bgp_maxpaths_ibgp, no_bgp_maxpaths_ibgp_hidden_cmd,
             "Number of paths\n"
             "Match the cluster length\n")
 
-void bgp_config_write_maxpaths(struct vty *vty, struct bgp *bgp, afi_t afi,
-                              safi_t safi)
+static void bgp_config_write_maxpaths(struct vty *vty, struct bgp *bgp,
+                                     afi_t afi, safi_t safi)
 {
        if (bgp->maxpaths[afi][safi].maxpaths_ebgp != MULTIPATH_NUM) {
                vty_out(vty, "  maximum-paths %d\n",
@@ -1821,7 +1969,7 @@ DEFUN (bgp_timers,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       bgp_timers_set(bgp, keepalive, holdtime);
+       bgp_timers_set(bgp, keepalive, holdtime, DFLT_BGP_CONNECT_RETRY);
 
        return CMD_SUCCESS;
 }
@@ -1836,7 +1984,8 @@ DEFUN (no_bgp_timers,
        "Holdtime\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_timers_unset(bgp);
+       bgp_timers_set(bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME,
+                      DFLT_BGP_CONNECT_RETRY);
 
        return CMD_SUCCESS;
 }
@@ -2031,37 +2180,68 @@ DEFUN (no_bgp_deterministic_med,
        return CMD_SUCCESS;
 }
 
-/* "bgp graceful-restart" configuration. */
+/* "bgp graceful-restart mode" configuration. */
 DEFUN (bgp_graceful_restart,
-       bgp_graceful_restart_cmd,
-       "bgp graceful-restart",
-       "BGP specific commands\n"
-       "Graceful restart capability parameters\n")
+       bgp_graceful_restart_cmd,
+       "bgp graceful-restart",
+       "BGP specific commands\n"
+       GR_CMD
+      )
 {
+       int ret = BGP_GR_FAILURE;
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug("[BGP_GR] bgp_graceful_restart_cmd : START ");
+
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_GRACEFUL_RESTART);
-       return CMD_SUCCESS;
+
+       ret = bgp_gr_update_all(bgp, GLOBAL_GR_CMD);
+
+       VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp,
+                               bgp->peer, ret);
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug("[BGP_GR] bgp_graceful_restart_cmd : END ");
+       vty_out(vty,
+               "Graceful restart configuration changed, reset all peers to take effect\n");
+       return bgp_vty_return(vty, ret);
 }
 
 DEFUN (no_bgp_graceful_restart,
-       no_bgp_graceful_restart_cmd,
-       "no bgp graceful-restart",
-       NO_STR
-       "BGP specific commands\n"
-       "Graceful restart capability parameters\n")
+       no_bgp_graceful_restart_cmd,
+       "no bgp graceful-restart",
+       NO_STR
+       "BGP specific commands\n"
+       NO_GR_CMD
+      )
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_GRACEFUL_RESTART);
-       return CMD_SUCCESS;
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug("[BGP_GR] no_bgp_graceful_restart_cmd : START ");
+
+       int ret = BGP_GR_FAILURE;
+
+       ret = bgp_gr_update_all(bgp, NO_GLOBAL_GR_CMD);
+
+       VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp,
+                       bgp->peer, ret);
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug("[BGP_GR] no_bgp_graceful_restart_cmd : END ");
+       vty_out(vty,
+               "Graceful restart configuration changed, reset all peers to take effect\n");
+
+       return bgp_vty_return(vty, ret);
 }
 
 DEFUN (bgp_graceful_restart_stalepath_time,
-       bgp_graceful_restart_stalepath_time_cmd,
-       "bgp graceful-restart stalepath-time (1-4095)",
-       "BGP specific commands\n"
-       "Graceful restart capability parameters\n"
-       "Set the max time to hold onto restarting peer's stale paths\n"
-       "Delay value (seconds)\n")
+       bgp_graceful_restart_stalepath_time_cmd,
+       "bgp graceful-restart stalepath-time (1-4095)",
+       "BGP specific commands\n"
+       "Graceful restart capability parameters\n"
+       "Set the max time to hold onto restarting peer's stale paths\n"
+       "Delay value (seconds)\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_number = 3;
@@ -2073,12 +2253,12 @@ DEFUN (bgp_graceful_restart_stalepath_time,
 }
 
 DEFUN (bgp_graceful_restart_restart_time,
-       bgp_graceful_restart_restart_time_cmd,
-       "bgp graceful-restart restart-time (1-4095)",
-       "BGP specific commands\n"
-       "Graceful restart capability parameters\n"
-       "Set the time to wait to delete stale routes before a BGP open message is received\n"
-       "Delay value (seconds)\n")
+       bgp_graceful_restart_restart_time_cmd,
+       "bgp graceful-restart restart-time (1-4095)",
+       "BGP specific commands\n"
+       "Graceful restart capability parameters\n"
+       "Set the time to wait to delete stale routes before a BGP open message is received\n"
+       "Delay value (seconds)\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_number = 3;
@@ -2089,14 +2269,36 @@ DEFUN (bgp_graceful_restart_restart_time,
        return CMD_SUCCESS;
 }
 
-DEFUN (no_bgp_graceful_restart_stalepath_time,
-       no_bgp_graceful_restart_stalepath_time_cmd,
-       "no bgp graceful-restart stalepath-time [(1-4095)]",
-       NO_STR
+DEFUN (bgp_graceful_restart_select_defer_time,
+       bgp_graceful_restart_select_defer_time_cmd,
+       "bgp graceful-restart select-defer-time (0-3600)",
        "BGP specific commands\n"
        "Graceful restart capability parameters\n"
-       "Set the max time to hold onto restarting peer's stale paths\n"
-       "Delay value (seconds)\n")
+       "Set the time to defer the BGP route selection after restart\n"
+       "Delay value (seconds, 0 - disable)\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       int idx_number = 3;
+       uint32_t defer_time;
+
+       defer_time = strtoul(argv[idx_number]->arg, NULL, 10);
+       bgp->select_defer_time = defer_time;
+       if (defer_time == 0)
+               bgp_flag_set(bgp, BGP_FLAG_SELECT_DEFER_DISABLE);
+       else
+               bgp_flag_unset(bgp, BGP_FLAG_SELECT_DEFER_DISABLE);
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_graceful_restart_stalepath_time,
+       no_bgp_graceful_restart_stalepath_time_cmd,
+       "no bgp graceful-restart stalepath-time [(1-4095)]",
+       NO_STR
+       "BGP specific commands\n"
+       "Graceful restart capability parameters\n"
+       "Set the max time to hold onto restarting peer's stale paths\n"
+       "Delay value (seconds)\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
 
@@ -2105,26 +2307,43 @@ DEFUN (no_bgp_graceful_restart_stalepath_time,
 }
 
 DEFUN (no_bgp_graceful_restart_restart_time,
-       no_bgp_graceful_restart_restart_time_cmd,
-       "no bgp graceful-restart restart-time [(1-4095)]",
+       no_bgp_graceful_restart_restart_time_cmd,
+       "no bgp graceful-restart restart-time [(1-4095)]",
+       NO_STR
+       "BGP specific commands\n"
+       "Graceful restart capability parameters\n"
+       "Set the time to wait to delete stale routes before a BGP open message is received\n"
+       "Delay value (seconds)\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+       bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_graceful_restart_select_defer_time,
+       no_bgp_graceful_restart_select_defer_time_cmd,
+       "no bgp graceful-restart select-defer-time [(0-3600)]",
        NO_STR
        "BGP specific commands\n"
        "Graceful restart capability parameters\n"
-       "Set the time to wait to delete stale routes before a BGP open message is received\n"
+       "Set the time to defer the BGP route selection after restart\n"
        "Delay value (seconds)\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
 
-       bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
+       bgp->select_defer_time = BGP_DEFAULT_SELECT_DEFERRAL_TIME;
+       bgp_flag_unset(bgp, BGP_FLAG_SELECT_DEFER_DISABLE);
+
        return CMD_SUCCESS;
 }
 
 DEFUN (bgp_graceful_restart_preserve_fw,
-       bgp_graceful_restart_preserve_fw_cmd,
-       "bgp graceful-restart preserve-fw-state",
-       "BGP specific commands\n"
-       "Graceful restart capability parameters\n"
-       "Sets F-bit indication that fib is preserved while doing Graceful Restart\n")
+       bgp_graceful_restart_preserve_fw_cmd,
+       "bgp graceful-restart preserve-fw-state",
+       "BGP specific commands\n"
+       "Graceful restart capability parameters\n"
+       "Sets F-bit indication that fib is preserved while doing Graceful Restart\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
        bgp_flag_set(bgp, BGP_FLAG_GR_PRESERVE_FWD);
@@ -2132,1757 +2351,2108 @@ DEFUN (bgp_graceful_restart_preserve_fw,
 }
 
 DEFUN (no_bgp_graceful_restart_preserve_fw,
-       no_bgp_graceful_restart_preserve_fw_cmd,
-       "no bgp graceful-restart preserve-fw-state",
-       NO_STR
-       "BGP specific commands\n"
-       "Graceful restart capability parameters\n"
-       "Unsets F-bit indication that fib is preserved while doing Graceful Restart\n")
+       no_bgp_graceful_restart_preserve_fw_cmd,
+       "no bgp graceful-restart preserve-fw-state",
+       NO_STR
+       "BGP specific commands\n"
+       "Graceful restart capability parameters\n"
+       "Unsets F-bit indication that fib is preserved while doing Graceful Restart\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
        bgp_flag_unset(bgp, BGP_FLAG_GR_PRESERVE_FWD);
        return CMD_SUCCESS;
 }
 
-/* "bgp graceful-shutdown" configuration */
-DEFUN (bgp_graceful_shutdown,
-       bgp_graceful_shutdown_cmd,
-       "bgp graceful-shutdown",
-       BGP_STR
-       "Graceful shutdown parameters\n")
+DEFUN (bgp_graceful_restart_disable,
+       bgp_graceful_restart_disable_cmd,
+       "bgp graceful-restart-disable",
+       "BGP specific commands\n"
+       GR_DISABLE)
 {
+       int ret = BGP_GR_FAILURE;
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] bgp_graceful_restart_disable_cmd : START ");
+
        VTY_DECLVAR_CONTEXT(bgp, bgp);
 
-       if (!bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
-               bgp_flag_set(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN);
-               bgp_static_redo_import_check(bgp);
-               bgp_redistribute_redo(bgp);
-               bgp_clear_star_soft_out(vty, bgp->name);
-               bgp_clear_star_soft_in(vty, bgp->name);
-       }
+       ret = bgp_gr_update_all(bgp, GLOBAL_DISABLE_CMD);
 
-       return CMD_SUCCESS;
+       VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp,
+                               bgp->peer, ret);
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] bgp_graceful_restart_disable_cmd : END ");
+       vty_out(vty,
+               "Graceful restart configuration changed, reset all peers to take effect\n");
+
+       return bgp_vty_return(vty, ret);
 }
 
-DEFUN (no_bgp_graceful_shutdown,
-       no_bgp_graceful_shutdown_cmd,
-       "no bgp graceful-shutdown",
-       NO_STR
-       BGP_STR
-       "Graceful shutdown parameters\n")
+DEFUN (no_bgp_graceful_restart_disable,
+       no_bgp_graceful_restart_disable_cmd,
+       "no bgp graceful-restart-disable",
+       NO_STR
+       "BGP specific commands\n"
+       NO_GR_DISABLE
+      )
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
 
-       if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
-               bgp_flag_unset(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN);
-               bgp_static_redo_import_check(bgp);
-               bgp_redistribute_redo(bgp);
-               bgp_clear_star_soft_out(vty, bgp->name);
-               bgp_clear_star_soft_in(vty, bgp->name);
-       }
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] no_bgp_graceful_restart_disable_cmd : START ");
 
-       return CMD_SUCCESS;
-}
+       int ret = BGP_GR_FAILURE;
 
-/* "bgp fast-external-failover" configuration. */
-DEFUN (bgp_fast_external_failover,
-       bgp_fast_external_failover_cmd,
-       "bgp fast-external-failover",
-       BGP_STR
-       "Immediately reset session if a link to a directly connected external peer goes down\n")
-{
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_NO_FAST_EXT_FAILOVER);
-       return CMD_SUCCESS;
-}
+       ret = bgp_gr_update_all(bgp, NO_GLOBAL_DISABLE_CMD);
 
-DEFUN (no_bgp_fast_external_failover,
-       no_bgp_fast_external_failover_cmd,
-       "no bgp fast-external-failover",
-       NO_STR
-       BGP_STR
-       "Immediately reset session if a link to a directly connected external peer goes down\n")
-{
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_NO_FAST_EXT_FAILOVER);
-       return CMD_SUCCESS;
-}
+       VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp,
+                               bgp->peer, ret);
 
-/* "bgp bestpath compare-routerid" configuration.  */
-DEFUN (bgp_bestpath_compare_router_id,
-       bgp_bestpath_compare_router_id_cmd,
-       "bgp bestpath compare-routerid",
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "Compare router-id for identical EBGP paths\n")
-{
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_COMPARE_ROUTER_ID);
-       bgp_recalculate_all_bestpaths(bgp);
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] no_bgp_graceful_restart_disable_cmd : END ");
+       vty_out(vty,
+               "Graceful restart configuration changed, reset all peers to take effect\n");
 
-       return CMD_SUCCESS;
+       return bgp_vty_return(vty, ret);
 }
 
-DEFUN (no_bgp_bestpath_compare_router_id,
-       no_bgp_bestpath_compare_router_id_cmd,
-       "no bgp bestpath compare-routerid",
-       NO_STR
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "Compare router-id for identical EBGP paths\n")
+DEFUN (bgp_neighbor_graceful_restart_set,
+       bgp_neighbor_graceful_restart_set_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> graceful-restart",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       GR_NEIGHBOR_CMD
+      )
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_COMPARE_ROUTER_ID);
-       bgp_recalculate_all_bestpaths(bgp);
+       int idx_peer = 1;
+       struct peer *peer;
+       int ret = BGP_GR_FAILURE;
 
-       return CMD_SUCCESS;
-}
+       VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
 
-/* "bgp bestpath as-path ignore" configuration.  */
-DEFUN (bgp_bestpath_aspath_ignore,
-       bgp_bestpath_aspath_ignore_cmd,
-       "bgp bestpath as-path ignore",
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "AS-path attribute\n"
-       "Ignore as-path length in selecting a route\n")
-{
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_ASPATH_IGNORE);
-       bgp_recalculate_all_bestpaths(bgp);
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] bgp_neighbor_graceful_restart_set_cmd : START ");
 
-       return CMD_SUCCESS;
-}
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
 
-DEFUN (no_bgp_bestpath_aspath_ignore,
-       no_bgp_bestpath_aspath_ignore_cmd,
-       "no bgp bestpath as-path ignore",
-       NO_STR
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "AS-path attribute\n"
-       "Ignore as-path length in selecting a route\n")
-{
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_ASPATH_IGNORE);
-       bgp_recalculate_all_bestpaths(bgp);
+       ret = bgp_neighbor_graceful_restart(peer, PEER_GR_CMD);
 
-       return CMD_SUCCESS;
+       VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+       VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] bgp_neighbor_graceful_restart_set_cmd : END ");
+       vty_out(vty,
+               "Graceful restart configuration changed, reset this peer to take effect\n");
+
+       return bgp_vty_return(vty, ret);
 }
 
-/* "bgp bestpath as-path confed" configuration.  */
-DEFUN (bgp_bestpath_aspath_confed,
-       bgp_bestpath_aspath_confed_cmd,
-       "bgp bestpath as-path confed",
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "AS-path attribute\n"
-       "Compare path lengths including confederation sets & sequences in selecting a route\n")
+DEFUN (no_bgp_neighbor_graceful_restart,
+       no_bgp_neighbor_graceful_restart_set_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> graceful-restart",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       NO_GR_NEIGHBOR_CMD
+      )
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_ASPATH_CONFED);
-       bgp_recalculate_all_bestpaths(bgp);
+       int idx_peer = 2;
+       int ret = BGP_GR_FAILURE;
+       struct peer *peer;
 
-       return CMD_SUCCESS;
+       VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
+
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] no_bgp_neighbor_graceful_restart_set_cmd : START ");
+
+       ret = bgp_neighbor_graceful_restart(peer, NO_PEER_GR_CMD);
+
+       VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+       VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] no_bgp_neighbor_graceful_restart_set_cmd : END ");
+       vty_out(vty,
+               "Graceful restart configuration changed, reset this peer to take effect\n");
+
+       return bgp_vty_return(vty, ret);
 }
 
-DEFUN (no_bgp_bestpath_aspath_confed,
-       no_bgp_bestpath_aspath_confed_cmd,
-       "no bgp bestpath as-path confed",
-       NO_STR
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "AS-path attribute\n"
-       "Compare path lengths including confederation sets & sequences in selecting a route\n")
+DEFUN (bgp_neighbor_graceful_restart_helper_set,
+       bgp_neighbor_graceful_restart_helper_set_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> graceful-restart-helper",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       GR_NEIGHBOR_HELPER_CMD
+      )
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_ASPATH_CONFED);
-       bgp_recalculate_all_bestpaths(bgp);
+       int idx_peer = 1;
+       struct peer *peer;
+       int ret = BGP_GR_FAILURE;
 
-       return CMD_SUCCESS;
-}
+       VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
 
-/* "bgp bestpath as-path multipath-relax" configuration.  */
-DEFUN (bgp_bestpath_aspath_multipath_relax,
-       bgp_bestpath_aspath_multipath_relax_cmd,
-       "bgp bestpath as-path multipath-relax [<as-set|no-as-set>]",
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "AS-path attribute\n"
-       "Allow load sharing across routes that have different AS paths (but same length)\n"
-       "Generate an AS_SET\n"
-       "Do not generate an AS_SET\n")
-{
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx = 0;
-       bgp_flag_set(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] bgp_neighbor_graceful_restart_helper_set_cmd : START ");
 
-       /* no-as-set is now the default behavior so we can silently
-        * ignore it */
-       if (argv_find(argv, argc, "as-set", &idx))
-               bgp_flag_set(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
-       else
-               bgp_flag_unset(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
 
-       bgp_recalculate_all_bestpaths(bgp);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
 
-       return CMD_SUCCESS;
-}
 
-DEFUN (no_bgp_bestpath_aspath_multipath_relax,
-       no_bgp_bestpath_aspath_multipath_relax_cmd,
-       "no bgp bestpath as-path multipath-relax [<as-set|no-as-set>]",
-       NO_STR
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "AS-path attribute\n"
-       "Allow load sharing across routes that have different AS paths (but same length)\n"
-       "Generate an AS_SET\n"
-       "Do not generate an AS_SET\n")
-{
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
-       bgp_flag_unset(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
-       bgp_recalculate_all_bestpaths(bgp);
+       ret = bgp_neighbor_graceful_restart(peer, PEER_HELPER_CMD);
 
-       return CMD_SUCCESS;
-}
+       VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+       VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
 
-/* "bgp log-neighbor-changes" configuration.  */
-DEFUN (bgp_log_neighbor_changes,
-       bgp_log_neighbor_changes_cmd,
-       "bgp log-neighbor-changes",
-       "BGP specific commands\n"
-       "Log neighbor up/down and reset reason\n")
-{
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
-       return CMD_SUCCESS;
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] bgp_neighbor_graceful_restart_helper_set_cmd : END ");
+       vty_out(vty,
+               "Graceful restart configuration changed, reset this peer to take effect\n");
+
+       return bgp_vty_return(vty, ret);
 }
 
-DEFUN (no_bgp_log_neighbor_changes,
-       no_bgp_log_neighbor_changes_cmd,
-       "no bgp log-neighbor-changes",
-       NO_STR
-       "BGP specific commands\n"
-       "Log neighbor up/down and reset reason\n")
+DEFUN (no_bgp_neighbor_graceful_restart_helper,
+       no_bgp_neighbor_graceful_restart_helper_set_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> graceful-restart-helper",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       NO_GR_NEIGHBOR_HELPER_CMD
+      )
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
-       return CMD_SUCCESS;
+       int idx_peer = 2;
+       int ret = BGP_GR_FAILURE;
+       struct peer *peer;
+
+       VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
+
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] no_bgp_neighbor_graceful_restart_helper_set_cmd : START ");
+
+       ret = bgp_neighbor_graceful_restart(peer,
+                       NO_PEER_HELPER_CMD);
+
+       VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+       VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] no_bgp_neighbor_graceful_restart_helper_set_cmd : END ");
+       vty_out(vty,
+               "Graceful restart configuration changed, reset this peer to take effect\n");
+
+       return bgp_vty_return(vty, ret);
 }
 
-/* "bgp bestpath med" configuration. */
-DEFUN (bgp_bestpath_med,
-       bgp_bestpath_med_cmd,
-       "bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>",
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "MED attribute\n"
-       "Compare MED among confederation paths\n"
-       "Treat missing MED as the least preferred one\n"
-       "Treat missing MED as the least preferred one\n"
-       "Compare MED among confederation paths\n")
+DEFUN (bgp_neighbor_graceful_restart_disable_set,
+       bgp_neighbor_graceful_restart_disable_set_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> graceful-restart-disable",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       GR_NEIGHBOR_DISABLE_CMD
+      )
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       int idx_peer = 1;
+       struct peer *peer;
+       int ret = BGP_GR_FAILURE;
 
-       int idx = 0;
-       if (argv_find(argv, argc, "confed", &idx))
-               bgp_flag_set(bgp, BGP_FLAG_MED_CONFED);
-       idx = 0;
-       if (argv_find(argv, argc, "missing-as-worst", &idx))
-               bgp_flag_set(bgp, BGP_FLAG_MED_MISSING_AS_WORST);
+       VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
 
-       bgp_recalculate_all_bestpaths(bgp);
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] bgp_neighbor_graceful_restart_disable_set_cmd : START ");
 
-       return CMD_SUCCESS;
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       ret = bgp_neighbor_graceful_restart(peer,
+                               PEER_DISABLE_CMD);
+
+       if (peer->bgp->t_startup)
+               bgp_peer_gr_flags_update(peer);
+
+       VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+       VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR]bgp_neighbor_graceful_restart_disable_set_cmd : END ");
+       vty_out(vty,
+               "Graceful restart configuration changed, reset this peer to take effect\n");
+
+       return bgp_vty_return(vty, ret);
 }
 
-DEFUN (no_bgp_bestpath_med,
-       no_bgp_bestpath_med_cmd,
-       "no bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>",
-       NO_STR
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "MED attribute\n"
-       "Compare MED among confederation paths\n"
-       "Treat missing MED as the least preferred one\n"
-       "Treat missing MED as the least preferred one\n"
-       "Compare MED among confederation paths\n")
+DEFUN (no_bgp_neighbor_graceful_restart_disable,
+       no_bgp_neighbor_graceful_restart_disable_set_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> graceful-restart-disable",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       NO_GR_NEIGHBOR_DISABLE_CMD
+      )
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       int idx_peer = 2;
+       int ret = BGP_GR_FAILURE;
+       struct peer *peer;
 
-       int idx = 0;
-       if (argv_find(argv, argc, "confed", &idx))
-               bgp_flag_unset(bgp, BGP_FLAG_MED_CONFED);
-       idx = 0;
-       if (argv_find(argv, argc, "missing-as-worst", &idx))
-               bgp_flag_unset(bgp, BGP_FLAG_MED_MISSING_AS_WORST);
+       VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
 
-       bgp_recalculate_all_bestpaths(bgp);
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
 
-       return CMD_SUCCESS;
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] no_bgp_neighbor_graceful_restart_disable_set_cmd : START ");
+
+       ret = bgp_neighbor_graceful_restart(peer, NO_PEER_DISABLE_CMD);
+
+       VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+       VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] no_bgp_neighbor_graceful_restart_disable_set_cmd : END ");
+       vty_out(vty,
+               "Graceful restart configuration changed, reset this peer to take effect\n");
+
+       return bgp_vty_return(vty, ret);
 }
 
-/* "no bgp default ipv4-unicast". */
-DEFUN (no_bgp_default_ipv4_unicast,
-       no_bgp_default_ipv4_unicast_cmd,
-       "no bgp default ipv4-unicast",
-       NO_STR
-       "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "Activate ipv4-unicast for a peer by default\n")
+DEFUN_HIDDEN (bgp_graceful_restart_disable_eor,
+              bgp_graceful_restart_disable_eor_cmd,
+              "bgp graceful-restart disable-eor",
+              "BGP specific commands\n"
+              "Graceful restart configuration parameters\n"
+              "Disable EOR Check\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_NO_DEFAULT_IPV4);
+       bgp_flag_set(bgp, BGP_FLAG_GR_DISABLE_EOR);
+
        return CMD_SUCCESS;
 }
 
-DEFUN (bgp_default_ipv4_unicast,
-       bgp_default_ipv4_unicast_cmd,
-       "bgp default ipv4-unicast",
-       "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "Activate ipv4-unicast for a peer by default\n")
+DEFUN_HIDDEN (no_bgp_graceful_restart_disable_eor,
+              no_bgp_graceful_restart_disable_eor_cmd,
+              "no bgp graceful-restart disable-eor",
+              NO_STR
+              "BGP specific commands\n"
+              "Graceful restart configuration parameters\n"
+              "Disable EOR Check\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_NO_DEFAULT_IPV4);
+       bgp_flag_unset(bgp, BGP_FLAG_GR_DISABLE_EOR);
+
        return CMD_SUCCESS;
 }
 
-/* Display hostname in certain command outputs */
-DEFUN (bgp_default_show_hostname,
-       bgp_default_show_hostname_cmd,
-       "bgp default show-hostname",
+DEFUN (bgp_graceful_restart_rib_stale_time,
+       bgp_graceful_restart_rib_stale_time_cmd,
+       "bgp graceful-restart rib-stale-time (1-3600)",
        "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "Show hostname in certain command outputs\n")
+       "Graceful restart configuration parameters\n"
+       "Specify the stale route removal timer in rib\n"
+       "Delay value (seconds)\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_SHOW_HOSTNAME);
+       int idx_number = 3;
+       uint32_t stale_time;
+
+       stale_time = strtoul(argv[idx_number]->arg, NULL, 10);
+       bgp->rib_stale_time = stale_time;
+       /* Send the stale timer update message to RIB */
+       if (bgp_zebra_stale_timer_update(bgp))
+               return CMD_WARNING;
+
        return CMD_SUCCESS;
 }
 
-DEFUN (no_bgp_default_show_hostname,
-       no_bgp_default_show_hostname_cmd,
-       "no bgp default show-hostname",
+DEFUN (no_bgp_graceful_restart_rib_stale_time,
+       no_bgp_graceful_restart_rib_stale_time_cmd,
+       "no bgp graceful-restart rib-stale-time [(1-3600)]",
        NO_STR
        "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "Show hostname in certain command outputs\n")
+       "Graceful restart configuration parameters\n"
+       "Specify the stale route removal timer in rib\n"
+       "Delay value (seconds)\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_SHOW_HOSTNAME);
+
+       bgp->rib_stale_time = BGP_DEFAULT_RIB_STALE_TIME;
+       /* Send the stale timer update message to RIB */
+       if (bgp_zebra_stale_timer_update(bgp))
+               return CMD_WARNING;
+
        return CMD_SUCCESS;
 }
 
-/* "bgp network import-check" configuration.  */
-DEFUN (bgp_network_import_check,
-       bgp_network_import_check_cmd,
-       "bgp network import-check",
-       "BGP specific commands\n"
-       "BGP network command\n"
-       "Check BGP network route exists in IGP\n")
+/* "bgp graceful-shutdown" configuration */
+DEFUN (bgp_graceful_shutdown,
+       bgp_graceful_shutdown_cmd,
+       "bgp graceful-shutdown",
+       BGP_STR
+       "Graceful shutdown parameters\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       if (!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) {
-               bgp_flag_set(bgp, BGP_FLAG_IMPORT_CHECK);
+
+       if (!bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
+               bgp_flag_set(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN);
                bgp_static_redo_import_check(bgp);
+               bgp_redistribute_redo(bgp);
+               bgp_clear_star_soft_out(vty, bgp->name);
+               bgp_clear_star_soft_in(vty, bgp->name);
        }
 
        return CMD_SUCCESS;
 }
 
-ALIAS_HIDDEN(bgp_network_import_check, bgp_network_import_check_exact_cmd,
-            "bgp network import-check exact",
-            "BGP specific commands\n"
-            "BGP network command\n"
-            "Check BGP network route exists in IGP\n"
-            "Match route precisely\n")
-
-DEFUN (no_bgp_network_import_check,
-       no_bgp_network_import_check_cmd,
-       "no bgp network import-check",
+DEFUN (no_bgp_graceful_shutdown,
+       no_bgp_graceful_shutdown_cmd,
+       "no bgp graceful-shutdown",
        NO_STR
-       "BGP specific commands\n"
-       "BGP network command\n"
-       "Check BGP network route exists in IGP\n")
+       BGP_STR
+       "Graceful shutdown parameters\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) {
-               bgp_flag_unset(bgp, BGP_FLAG_IMPORT_CHECK);
+
+       if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
+               bgp_flag_unset(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN);
                bgp_static_redo_import_check(bgp);
+               bgp_redistribute_redo(bgp);
+               bgp_clear_star_soft_out(vty, bgp->name);
+               bgp_clear_star_soft_in(vty, bgp->name);
        }
 
        return CMD_SUCCESS;
 }
 
-DEFUN (bgp_default_local_preference,
-       bgp_default_local_preference_cmd,
-       "bgp default local-preference (0-4294967295)",
-       "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "local preference (higher=more preferred)\n"
-       "Configure default local preference value\n")
+/* "bgp fast-external-failover" configuration. */
+DEFUN (bgp_fast_external_failover,
+       bgp_fast_external_failover_cmd,
+       "bgp fast-external-failover",
+       BGP_STR
+       "Immediately reset session if a link to a directly connected external peer goes down\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_number = 3;
-       uint32_t local_pref;
-
-       local_pref = strtoul(argv[idx_number]->arg, NULL, 10);
-
-       bgp_default_local_preference_set(bgp, local_pref);
-       bgp_clear_star_soft_in(vty, bgp->name);
-
+       bgp_flag_unset(bgp, BGP_FLAG_NO_FAST_EXT_FAILOVER);
        return CMD_SUCCESS;
 }
 
-DEFUN (no_bgp_default_local_preference,
-       no_bgp_default_local_preference_cmd,
-       "no bgp default local-preference [(0-4294967295)]",
+DEFUN (no_bgp_fast_external_failover,
+       no_bgp_fast_external_failover_cmd,
+       "no bgp fast-external-failover",
        NO_STR
+       BGP_STR
+       "Immediately reset session if a link to a directly connected external peer goes down\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       bgp_flag_set(bgp, BGP_FLAG_NO_FAST_EXT_FAILOVER);
+       return CMD_SUCCESS;
+}
+
+/* "bgp bestpath compare-routerid" configuration.  */
+DEFUN (bgp_bestpath_compare_router_id,
+       bgp_bestpath_compare_router_id_cmd,
+       "bgp bestpath compare-routerid",
        "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "local preference (higher=more preferred)\n"
-       "Configure default local preference value\n")
+       "Change the default bestpath selection\n"
+       "Compare router-id for identical EBGP paths\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_default_local_preference_unset(bgp);
-       bgp_clear_star_soft_in(vty, bgp->name);
+       bgp_flag_set(bgp, BGP_FLAG_COMPARE_ROUTER_ID);
+       bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
 }
 
-
-DEFUN (bgp_default_subgroup_pkt_queue_max,
-       bgp_default_subgroup_pkt_queue_max_cmd,
-       "bgp default subgroup-pkt-queue-max (20-100)",
+DEFUN (no_bgp_bestpath_compare_router_id,
+       no_bgp_bestpath_compare_router_id_cmd,
+       "no bgp bestpath compare-routerid",
+       NO_STR
        "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "subgroup-pkt-queue-max\n"
-       "Configure subgroup packet queue max\n")
+       "Change the default bestpath selection\n"
+       "Compare router-id for identical EBGP paths\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_number = 3;
-       uint32_t max_size;
+       bgp_flag_unset(bgp, BGP_FLAG_COMPARE_ROUTER_ID);
+       bgp_recalculate_all_bestpaths(bgp);
 
-       max_size = strtoul(argv[idx_number]->arg, NULL, 10);
+       return CMD_SUCCESS;
+}
 
-       bgp_default_subgroup_pkt_queue_max_set(bgp, max_size);
+/* "bgp bestpath as-path ignore" configuration.  */
+DEFUN (bgp_bestpath_aspath_ignore,
+       bgp_bestpath_aspath_ignore_cmd,
+       "bgp bestpath as-path ignore",
+       "BGP specific commands\n"
+       "Change the default bestpath selection\n"
+       "AS-path attribute\n"
+       "Ignore as-path length in selecting a route\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       bgp_flag_set(bgp, BGP_FLAG_ASPATH_IGNORE);
+       bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
 }
 
-DEFUN (no_bgp_default_subgroup_pkt_queue_max,
-       no_bgp_default_subgroup_pkt_queue_max_cmd,
-       "no bgp default subgroup-pkt-queue-max [(20-100)]",
+DEFUN (no_bgp_bestpath_aspath_ignore,
+       no_bgp_bestpath_aspath_ignore_cmd,
+       "no bgp bestpath as-path ignore",
        NO_STR
        "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "subgroup-pkt-queue-max\n"
-       "Configure subgroup packet queue max\n")
+       "Change the default bestpath selection\n"
+       "AS-path attribute\n"
+       "Ignore as-path length in selecting a route\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_default_subgroup_pkt_queue_max_unset(bgp);
+       bgp_flag_unset(bgp, BGP_FLAG_ASPATH_IGNORE);
+       bgp_recalculate_all_bestpaths(bgp);
+
        return CMD_SUCCESS;
 }
 
-
-DEFUN (bgp_rr_allow_outbound_policy,
-       bgp_rr_allow_outbound_policy_cmd,
-       "bgp route-reflector allow-outbound-policy",
+/* "bgp bestpath as-path confed" configuration.  */
+DEFUN (bgp_bestpath_aspath_confed,
+       bgp_bestpath_aspath_confed_cmd,
+       "bgp bestpath as-path confed",
        "BGP specific commands\n"
-       "Allow modifications made by out route-map\n"
-       "on ibgp neighbors\n")
+       "Change the default bestpath selection\n"
+       "AS-path attribute\n"
+       "Compare path lengths including confederation sets & sequences in selecting a route\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-
-       if (!bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
-               bgp_flag_set(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
-               update_group_announce_rrclients(bgp);
-               bgp_clear_star_soft_out(vty, bgp->name);
-       }
+       bgp_flag_set(bgp, BGP_FLAG_ASPATH_CONFED);
+       bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
 }
 
-DEFUN (no_bgp_rr_allow_outbound_policy,
-       no_bgp_rr_allow_outbound_policy_cmd,
-       "no bgp route-reflector allow-outbound-policy",
+DEFUN (no_bgp_bestpath_aspath_confed,
+       no_bgp_bestpath_aspath_confed_cmd,
+       "no bgp bestpath as-path confed",
        NO_STR
        "BGP specific commands\n"
-       "Allow modifications made by out route-map\n"
-       "on ibgp neighbors\n")
+       "Change the default bestpath selection\n"
+       "AS-path attribute\n"
+       "Compare path lengths including confederation sets & sequences in selecting a route\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-
-       if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
-               bgp_flag_unset(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
-               update_group_announce_rrclients(bgp);
-               bgp_clear_star_soft_out(vty, bgp->name);
-       }
+       bgp_flag_unset(bgp, BGP_FLAG_ASPATH_CONFED);
+       bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
 }
 
-DEFUN (bgp_listen_limit,
-       bgp_listen_limit_cmd,
-       "bgp listen limit (1-5000)",
+/* "bgp bestpath as-path multipath-relax" configuration.  */
+DEFUN (bgp_bestpath_aspath_multipath_relax,
+       bgp_bestpath_aspath_multipath_relax_cmd,
+       "bgp bestpath as-path multipath-relax [<as-set|no-as-set>]",
        "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "maximum number of BGP Dynamic Neighbors that can be created\n"
-       "Configure Dynamic Neighbors listen limit value\n")
+       "Change the default bestpath selection\n"
+       "AS-path attribute\n"
+       "Allow load sharing across routes that have different AS paths (but same length)\n"
+       "Generate an AS_SET\n"
+       "Do not generate an AS_SET\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_number = 3;
-       int listen_limit;
+       int idx = 0;
+       bgp_flag_set(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
 
-       listen_limit = strtoul(argv[idx_number]->arg, NULL, 10);
+       /* no-as-set is now the default behavior so we can silently
+        * ignore it */
+       if (argv_find(argv, argc, "as-set", &idx))
+               bgp_flag_set(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
+       else
+               bgp_flag_unset(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
 
-       bgp_listen_limit_set(bgp, listen_limit);
+       bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
 }
 
-DEFUN (no_bgp_listen_limit,
-       no_bgp_listen_limit_cmd,
-       "no bgp listen limit [(1-5000)]",
+DEFUN (no_bgp_bestpath_aspath_multipath_relax,
+       no_bgp_bestpath_aspath_multipath_relax_cmd,
+       "no bgp bestpath as-path multipath-relax [<as-set|no-as-set>]",
+       NO_STR
        "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "unset maximum number of BGP Dynamic Neighbors that can be created\n"
-       "Configure Dynamic Neighbors listen limit value to default\n"
-       "Configure Dynamic Neighbors listen limit value\n")
+       "Change the default bestpath selection\n"
+       "AS-path attribute\n"
+       "Allow load sharing across routes that have different AS paths (but same length)\n"
+       "Generate an AS_SET\n"
+       "Do not generate an AS_SET\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_listen_limit_unset(bgp);
+       bgp_flag_unset(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
+       bgp_flag_unset(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
+       bgp_recalculate_all_bestpaths(bgp);
+
        return CMD_SUCCESS;
 }
 
-
-/*
- * Check if this listen range is already configured. Check for exact
- * match or overlap based on input.
- */
-static struct peer_group *listen_range_exists(struct bgp *bgp,
-                                             struct prefix *range, int exact)
+/* "bgp log-neighbor-changes" configuration.  */
+DEFUN (bgp_log_neighbor_changes,
+       bgp_log_neighbor_changes_cmd,
+       "bgp log-neighbor-changes",
+       "BGP specific commands\n"
+       "Log neighbor up/down and reset reason\n")
 {
-       struct listnode *node, *nnode;
-       struct listnode *node1, *nnode1;
-       struct peer_group *group;
-       struct prefix *lr;
-       afi_t afi;
-       int match;
-
-       afi = family2afi(range->family);
-       for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
-               for (ALL_LIST_ELEMENTS(group->listen_range[afi], node1, nnode1,
-                                      lr)) {
-                       if (exact)
-                               match = prefix_same(range, lr);
-                       else
-                               match = (prefix_match(range, lr)
-                                        || prefix_match(lr, range));
-                       if (match)
-                               return group;
-               }
-       }
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       bgp_flag_set(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+       return CMD_SUCCESS;
+}
 
-       return NULL;
+DEFUN (no_bgp_log_neighbor_changes,
+       no_bgp_log_neighbor_changes_cmd,
+       "no bgp log-neighbor-changes",
+       NO_STR
+       "BGP specific commands\n"
+       "Log neighbor up/down and reset reason\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       bgp_flag_unset(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+       return CMD_SUCCESS;
 }
 
-DEFUN (bgp_listen_range,
-       bgp_listen_range_cmd,
-       "bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME",
+/* "bgp bestpath med" configuration. */
+DEFUN (bgp_bestpath_med,
+       bgp_bestpath_med_cmd,
+       "bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>",
        "BGP specific commands\n"
-       "Configure BGP dynamic neighbors listen range\n"
-       "Configure BGP dynamic neighbors listen range\n"
-       NEIGHBOR_ADDR_STR
-       "Member of the peer-group\n"
-       "Peer-group name\n")
+       "Change the default bestpath selection\n"
+       "MED attribute\n"
+       "Compare MED among confederation paths\n"
+       "Treat missing MED as the least preferred one\n"
+       "Treat missing MED as the least preferred one\n"
+       "Compare MED among confederation paths\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       struct prefix range;
-       struct peer_group *group, *existing_group;
-       afi_t afi;
-       int ret;
-       int idx = 0;
 
-       argv_find(argv, argc, "A.B.C.D/M", &idx);
-       argv_find(argv, argc, "X:X::X:X/M", &idx);
-       char *prefix = argv[idx]->arg;
-       argv_find(argv, argc, "PGNAME", &idx);
-       char *peergroup = argv[idx]->arg;
+       int idx = 0;
+       if (argv_find(argv, argc, "confed", &idx))
+               bgp_flag_set(bgp, BGP_FLAG_MED_CONFED);
+       idx = 0;
+       if (argv_find(argv, argc, "missing-as-worst", &idx))
+               bgp_flag_set(bgp, BGP_FLAG_MED_MISSING_AS_WORST);
 
-       /* Convert IP prefix string to struct prefix. */
-       ret = str2prefix(prefix, &range);
-       if (!ret) {
-               vty_out(vty, "%% Malformed listen range\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       bgp_recalculate_all_bestpaths(bgp);
 
-       afi = family2afi(range.family);
+       return CMD_SUCCESS;
+}
 
-       if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&range.u.prefix6)) {
-               vty_out(vty,
-                       "%% Malformed listen range (link-local address)\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       apply_mask(&range);
-
-       /* Check if same listen range is already configured. */
-       existing_group = listen_range_exists(bgp, &range, 1);
-       if (existing_group) {
-               if (strcmp(existing_group->name, peergroup) == 0)
-                       return CMD_SUCCESS;
-               else {
-                       vty_out(vty,
-                               "%% Same listen range is attached to peer-group %s\n",
-                               existing_group->name);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
+DEFUN (no_bgp_bestpath_med,
+       no_bgp_bestpath_med_cmd,
+       "no bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>",
+       NO_STR
+       "BGP specific commands\n"
+       "Change the default bestpath selection\n"
+       "MED attribute\n"
+       "Compare MED among confederation paths\n"
+       "Treat missing MED as the least preferred one\n"
+       "Treat missing MED as the least preferred one\n"
+       "Compare MED among confederation paths\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
 
-       /* Check if an overlapping listen range exists. */
-       if (listen_range_exists(bgp, &range, 0)) {
-               vty_out(vty,
-                       "%% Listen range overlaps with existing listen range\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       int idx = 0;
+       if (argv_find(argv, argc, "confed", &idx))
+               bgp_flag_unset(bgp, BGP_FLAG_MED_CONFED);
+       idx = 0;
+       if (argv_find(argv, argc, "missing-as-worst", &idx))
+               bgp_flag_unset(bgp, BGP_FLAG_MED_MISSING_AS_WORST);
 
-       group = peer_group_lookup(bgp, peergroup);
-       if (!group) {
-               vty_out(vty, "%% Configure the peer-group first\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       bgp_recalculate_all_bestpaths(bgp);
 
-       ret = peer_group_listen_range_add(group, &range);
-       return bgp_vty_return(vty, ret);
+       return CMD_SUCCESS;
 }
 
-DEFUN (no_bgp_listen_range,
-       no_bgp_listen_range_cmd,
-       "no bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME",
+/* "no bgp default ipv4-unicast". */
+DEFUN (no_bgp_default_ipv4_unicast,
+       no_bgp_default_ipv4_unicast_cmd,
+       "no bgp default ipv4-unicast",
        NO_STR
        "BGP specific commands\n"
-       "Unconfigure BGP dynamic neighbors listen range\n"
-       "Unconfigure BGP dynamic neighbors listen range\n"
-       NEIGHBOR_ADDR_STR
-       "Member of the peer-group\n"
-       "Peer-group name\n")
+       "Configure BGP defaults\n"
+       "Activate ipv4-unicast for a peer by default\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       struct prefix range;
-       struct peer_group *group;
-       afi_t afi;
-       int ret;
-       int idx = 0;
-
-       argv_find(argv, argc, "A.B.C.D/M", &idx);
-       argv_find(argv, argc, "X:X::X:X/M", &idx);
-       char *prefix = argv[idx]->arg;
-       argv_find(argv, argc, "WORD", &idx);
-       char *peergroup = argv[idx]->arg;
-
-       /* Convert IP prefix string to struct prefix. */
-       ret = str2prefix(prefix, &range);
-       if (!ret) {
-               vty_out(vty, "%% Malformed listen range\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       bgp_flag_set(bgp, BGP_FLAG_NO_DEFAULT_IPV4);
+       return CMD_SUCCESS;
+}
 
-       afi = family2afi(range.family);
+DEFUN (bgp_default_ipv4_unicast,
+       bgp_default_ipv4_unicast_cmd,
+       "bgp default ipv4-unicast",
+       "BGP specific commands\n"
+       "Configure BGP defaults\n"
+       "Activate ipv4-unicast for a peer by default\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       bgp_flag_unset(bgp, BGP_FLAG_NO_DEFAULT_IPV4);
+       return CMD_SUCCESS;
+}
 
-       if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&range.u.prefix6)) {
-               vty_out(vty,
-                       "%% Malformed listen range (link-local address)\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+/* Display hostname in certain command outputs */
+DEFUN (bgp_default_show_hostname,
+       bgp_default_show_hostname_cmd,
+       "bgp default show-hostname",
+       "BGP specific commands\n"
+       "Configure BGP defaults\n"
+       "Show hostname in certain command outputs\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       bgp_flag_set(bgp, BGP_FLAG_SHOW_HOSTNAME);
+       return CMD_SUCCESS;
+}
 
-       apply_mask(&range);
+DEFUN (no_bgp_default_show_hostname,
+       no_bgp_default_show_hostname_cmd,
+       "no bgp default show-hostname",
+       NO_STR
+       "BGP specific commands\n"
+       "Configure BGP defaults\n"
+       "Show hostname in certain command outputs\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       bgp_flag_unset(bgp, BGP_FLAG_SHOW_HOSTNAME);
+       return CMD_SUCCESS;
+}
 
-       group = peer_group_lookup(bgp, peergroup);
-       if (!group) {
-               vty_out(vty, "%% Peer-group does not exist\n");
-               return CMD_WARNING_CONFIG_FAILED;
+/* "bgp network import-check" configuration.  */
+DEFUN (bgp_network_import_check,
+       bgp_network_import_check_cmd,
+       "bgp network import-check",
+       "BGP specific commands\n"
+       "BGP network command\n"
+       "Check BGP network route exists in IGP\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       if (!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) {
+               bgp_flag_set(bgp, BGP_FLAG_IMPORT_CHECK);
+               bgp_static_redo_import_check(bgp);
        }
 
-       ret = peer_group_listen_range_del(group, &range);
-       return bgp_vty_return(vty, ret);
+       return CMD_SUCCESS;
 }
 
-void bgp_config_write_listen(struct vty *vty, struct bgp *bgp)
-{
-       struct peer_group *group;
-       struct listnode *node, *nnode, *rnode, *nrnode;
-       struct prefix *range;
-       afi_t afi;
-       char buf[PREFIX2STR_BUFFER];
-
-       if (bgp->dynamic_neighbors_limit != BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT)
-               vty_out(vty, " bgp listen limit %d\n",
-                       bgp->dynamic_neighbors_limit);
+ALIAS_HIDDEN(bgp_network_import_check, bgp_network_import_check_exact_cmd,
+            "bgp network import-check exact",
+            "BGP specific commands\n"
+            "BGP network command\n"
+            "Check BGP network route exists in IGP\n"
+            "Match route precisely\n")
 
-       for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
-               for (afi = AFI_IP; afi < AFI_MAX; afi++) {
-                       for (ALL_LIST_ELEMENTS(group->listen_range[afi], rnode,
-                                              nrnode, range)) {
-                               prefix2str(range, buf, sizeof(buf));
-                               vty_out(vty,
-                                       " bgp listen range %s peer-group %s\n",
-                                       buf, group->name);
-                       }
-               }
+DEFUN (no_bgp_network_import_check,
+       no_bgp_network_import_check_cmd,
+       "no bgp network import-check",
+       NO_STR
+       "BGP specific commands\n"
+       "BGP network command\n"
+       "Check BGP network route exists in IGP\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) {
+               bgp_flag_unset(bgp, BGP_FLAG_IMPORT_CHECK);
+               bgp_static_redo_import_check(bgp);
        }
-}
 
+       return CMD_SUCCESS;
+}
 
-DEFUN (bgp_disable_connected_route_check,
-       bgp_disable_connected_route_check_cmd,
-       "bgp disable-ebgp-connected-route-check",
+DEFUN (bgp_default_local_preference,
+       bgp_default_local_preference_cmd,
+       "bgp default local-preference (0-4294967295)",
        "BGP specific commands\n"
-       "Disable checking if nexthop is connected on ebgp sessions\n")
+       "Configure BGP defaults\n"
+       "local preference (higher=more preferred)\n"
+       "Configure default local preference value\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
+       int idx_number = 3;
+       uint32_t local_pref;
+
+       local_pref = strtoul(argv[idx_number]->arg, NULL, 10);
+
+       bgp_default_local_preference_set(bgp, local_pref);
        bgp_clear_star_soft_in(vty, bgp->name);
 
        return CMD_SUCCESS;
 }
 
-DEFUN (no_bgp_disable_connected_route_check,
-       no_bgp_disable_connected_route_check_cmd,
-       "no bgp disable-ebgp-connected-route-check",
+DEFUN (no_bgp_default_local_preference,
+       no_bgp_default_local_preference_cmd,
+       "no bgp default local-preference [(0-4294967295)]",
        NO_STR
        "BGP specific commands\n"
-       "Disable checking if nexthop is connected on ebgp sessions\n")
+       "Configure BGP defaults\n"
+       "local preference (higher=more preferred)\n"
+       "Configure default local preference value\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
+       bgp_default_local_preference_unset(bgp);
        bgp_clear_star_soft_in(vty, bgp->name);
 
        return CMD_SUCCESS;
 }
 
 
-static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
-                             const char *as_str, afi_t afi, safi_t safi)
+DEFUN (bgp_default_subgroup_pkt_queue_max,
+       bgp_default_subgroup_pkt_queue_max_cmd,
+       "bgp default subgroup-pkt-queue-max (20-100)",
+       "BGP specific commands\n"
+       "Configure BGP defaults\n"
+       "subgroup-pkt-queue-max\n"
+       "Configure subgroup packet queue max\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int ret;
-       as_t as;
-       int as_type = AS_SPECIFIED;
-       union sockunion su;
-
-       if (as_str[0] == 'i') {
-               as = 0;
-               as_type = AS_INTERNAL;
-       } else if (as_str[0] == 'e') {
-               as = 0;
-               as_type = AS_EXTERNAL;
-       } else {
-               /* Get AS number.  */
-               as = strtoul(as_str, NULL, 10);
-       }
+       int idx_number = 3;
+       uint32_t max_size;
 
-       /* If peer is peer group or interface peer, call proper function. */
-       ret = str2sockunion(peer_str, &su);
-       if (ret < 0) {
-               struct peer *peer;
+       max_size = strtoul(argv[idx_number]->arg, NULL, 10);
 
-               /* Check if existing interface peer */
-               peer = peer_lookup_by_conf_if(bgp, peer_str);
+       bgp_default_subgroup_pkt_queue_max_set(bgp, max_size);
 
-               ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type, afi,
-                                    safi);
+       return CMD_SUCCESS;
+}
 
-               /* if not interface peer, check peer-group settings */
-               if (ret < 0 && !peer) {
-                       ret = peer_group_remote_as(bgp, peer_str, &as, as_type);
-                       if (ret < 0) {
-                               vty_out(vty,
-                                       "%% Create the peer-group or interface first\n");
-                               return CMD_WARNING_CONFIG_FAILED;
-                       }
-                       return CMD_SUCCESS;
-               }
-       } else {
-               if (peer_address_self_check(bgp, &su)) {
-                       vty_out(vty,
-                               "%% Can not configure the local system as neighbor\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-               ret = peer_remote_as(bgp, &su, NULL, &as, as_type, afi, safi);
-       }
-
-       /* This peer belongs to peer group.  */
-       switch (ret) {
-       case BGP_ERR_PEER_GROUP_MEMBER:
-               vty_out(vty,
-                       "%% Peer-group member cannot override remote-as of peer-group\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       case BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT:
-               vty_out(vty,
-                       "%% Peer-group members must be all internal or all external\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       return bgp_vty_return(vty, ret);
-}
-
-DEFUN (bgp_default_shutdown,
-       bgp_default_shutdown_cmd,
-       "[no] bgp default shutdown",
+DEFUN (no_bgp_default_subgroup_pkt_queue_max,
+       no_bgp_default_subgroup_pkt_queue_max_cmd,
+       "no bgp default subgroup-pkt-queue-max [(20-100)]",
        NO_STR
-       BGP_STR
+       "BGP specific commands\n"
        "Configure BGP defaults\n"
-       "Apply administrative shutdown to newly configured peers\n")
+       "subgroup-pkt-queue-max\n"
+       "Configure subgroup packet queue max\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp->autoshutdown = !strmatch(argv[0]->text, "no");
+       bgp_default_subgroup_pkt_queue_max_unset(bgp);
        return CMD_SUCCESS;
 }
 
-DEFUN (neighbor_remote_as,
-       neighbor_remote_as_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> remote-as <(1-4294967295)|internal|external>",
-       NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Specify a BGP neighbor\n"
-       AS_STR
-       "Internal BGP peer\n"
-       "External BGP peer\n")
+
+DEFUN (bgp_rr_allow_outbound_policy,
+       bgp_rr_allow_outbound_policy_cmd,
+       "bgp route-reflector allow-outbound-policy",
+       "BGP specific commands\n"
+       "Allow modifications made by out route-map\n"
+       "on ibgp neighbors\n")
 {
-       int idx_peer = 1;
-       int idx_remote_as = 3;
-       return peer_remote_as_vty(vty, argv[idx_peer]->arg,
-                                 argv[idx_remote_as]->arg, AFI_IP,
-                                 SAFI_UNICAST);
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+       if (!bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
+               bgp_flag_set(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
+               update_group_announce_rrclients(bgp);
+               bgp_clear_star_soft_out(vty, bgp->name);
+       }
+
+       return CMD_SUCCESS;
 }
 
-static int peer_conf_interface_get(struct vty *vty, const char *conf_if,
-                                  afi_t afi, safi_t safi, int v6only,
-                                  const char *peer_group_name,
-                                  const char *as_str)
+DEFUN (no_bgp_rr_allow_outbound_policy,
+       no_bgp_rr_allow_outbound_policy_cmd,
+       "no bgp route-reflector allow-outbound-policy",
+       NO_STR
+       "BGP specific commands\n"
+       "Allow modifications made by out route-map\n"
+       "on ibgp neighbors\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       as_t as = 0;
-       int as_type = AS_UNSPECIFIED;
-       struct peer *peer;
-       struct peer_group *group;
-       int ret = 0;
-       union sockunion su;
-
-       group = peer_group_lookup(bgp, conf_if);
 
-       if (group) {
-               vty_out(vty, "%% Name conflict with peer-group \n");
-               return CMD_WARNING_CONFIG_FAILED;
+       if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
+               bgp_flag_unset(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
+               update_group_announce_rrclients(bgp);
+               bgp_clear_star_soft_out(vty, bgp->name);
        }
 
-       if (as_str) {
-               if (as_str[0] == 'i') {
-                       as_type = AS_INTERNAL;
-               } else if (as_str[0] == 'e') {
-                       as_type = AS_EXTERNAL;
-               } else {
-                       /* Get AS number.  */
-                       as = strtoul(as_str, NULL, 10);
-                       as_type = AS_SPECIFIED;
-               }
-       }
+       return CMD_SUCCESS;
+}
 
-       peer = peer_lookup_by_conf_if(bgp, conf_if);
-       if (peer) {
-               if (as_str)
-                       ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type,
-                                            afi, safi);
-       } else {
-               if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4)
-                   && afi == AFI_IP && safi == SAFI_UNICAST)
-                       peer = peer_create(NULL, conf_if, bgp, bgp->as, as,
-                                          as_type, 0, 0, NULL);
-               else
-                       peer = peer_create(NULL, conf_if, bgp, bgp->as, as,
-                                          as_type, afi, safi, NULL);
+DEFUN (bgp_listen_limit,
+       bgp_listen_limit_cmd,
+       "bgp listen limit (1-5000)",
+       "BGP specific commands\n"
+       "BGP Dynamic Neighbors listen commands\n"
+       "Maximum number of BGP Dynamic Neighbors that can be created\n"
+       "Configure Dynamic Neighbors listen limit value\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       int idx_number = 3;
+       int listen_limit;
 
-               if (!peer) {
-                       vty_out(vty, "%% BGP failed to create peer\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
+       listen_limit = strtoul(argv[idx_number]->arg, NULL, 10);
 
-               if (v6only)
-                       peer_flag_set(peer, PEER_FLAG_IFPEER_V6ONLY);
+       bgp_listen_limit_set(bgp, listen_limit);
 
-               /* Request zebra to initiate IPv6 RAs on this interface. We do
-                * this
-                * any unnumbered peer in order to not worry about run-time
-                * transitions
-                * (e.g., peering is initially IPv4, but the IPv4 /30 or /31
-                * address
-                * gets deleted later etc.)
-                */
-               if (peer->ifp)
-                       bgp_zebra_initiate_radv(bgp, peer);
-       }
+       return CMD_SUCCESS;
+}
 
-       if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
-           || (!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))) {
-               if (v6only)
-                       peer_flag_set(peer, PEER_FLAG_IFPEER_V6ONLY);
-               else
-                       peer_flag_unset(peer, PEER_FLAG_IFPEER_V6ONLY);
+DEFUN (no_bgp_listen_limit,
+       no_bgp_listen_limit_cmd,
+       "no bgp listen limit [(1-5000)]",
+       NO_STR
+       "BGP specific commands\n"
+       "BGP Dynamic Neighbors listen commands\n"
+       "Maximum number of BGP Dynamic Neighbors that can be created\n"
+       "Configure Dynamic Neighbors listen limit value\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       bgp_listen_limit_unset(bgp);
+       return CMD_SUCCESS;
+}
 
-               /* v6only flag changed. Reset bgp seesion */
-               if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
-                       peer->last_reset = PEER_DOWN_V6ONLY_CHANGE;
-                       bgp_notify_send(peer, BGP_NOTIFY_CEASE,
-                                       BGP_NOTIFY_CEASE_CONFIG_CHANGE);
-               } else
-                       bgp_session_reset(peer);
-       }
 
-       if (!CHECK_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE)) {
-               SET_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE);
-               SET_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE);
-               SET_FLAG(peer->flags_override, PEER_FLAG_CAPABILITY_ENHE);
-       }
+/*
+ * Check if this listen range is already configured. Check for exact
+ * match or overlap based on input.
+ */
+static struct peer_group *listen_range_exists(struct bgp *bgp,
+                                             struct prefix *range, int exact)
+{
+       struct listnode *node, *nnode;
+       struct listnode *node1, *nnode1;
+       struct peer_group *group;
+       struct prefix *lr;
+       afi_t afi;
+       int match;
 
-       if (peer_group_name) {
-               group = peer_group_lookup(bgp, peer_group_name);
-               if (!group) {
-                       vty_out(vty, "%% Configure the peer-group first\n");
-                       return CMD_WARNING_CONFIG_FAILED;
+       afi = family2afi(range->family);
+       for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
+               for (ALL_LIST_ELEMENTS(group->listen_range[afi], node1, nnode1,
+                                      lr)) {
+                       if (exact)
+                               match = prefix_same(range, lr);
+                       else
+                               match = (prefix_match(range, lr)
+                                        || prefix_match(lr, range));
+                       if (match)
+                               return group;
                }
-
-               ret = peer_group_bind(bgp, &su, peer, group, &as);
        }
 
-       return bgp_vty_return(vty, ret);
+       return NULL;
 }
 
-DEFUN (neighbor_interface_config,
-       neighbor_interface_config_cmd,
-       "neighbor WORD interface [peer-group PGNAME]",
-       NEIGHBOR_STR
-       "Interface name or neighbor tag\n"
-       "Enable BGP on interface\n"
+DEFUN (bgp_listen_range,
+       bgp_listen_range_cmd,
+       "bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME",
+       "BGP specific commands\n"
+       "Configure BGP dynamic neighbors listen range\n"
+       "Configure BGP dynamic neighbors listen range\n"
+       NEIGHBOR_ADDR_STR
        "Member of the peer-group\n"
        "Peer-group name\n")
 {
-       int idx_word = 1;
-       int idx_peer_group_word = 4;
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       struct prefix range;
+       struct peer_group *group, *existing_group;
+       afi_t afi;
+       int ret;
+       int idx = 0;
 
-       if (argc > idx_peer_group_word)
-               return peer_conf_interface_get(
-                       vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 0,
-                       argv[idx_peer_group_word]->arg, NULL);
-       else
-               return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
-                                              SAFI_UNICAST, 0, NULL, NULL);
-}
+       argv_find(argv, argc, "A.B.C.D/M", &idx);
+       argv_find(argv, argc, "X:X::X:X/M", &idx);
+       char *prefix = argv[idx]->arg;
+       argv_find(argv, argc, "PGNAME", &idx);
+       char *peergroup = argv[idx]->arg;
 
-DEFUN (neighbor_interface_config_v6only,
-       neighbor_interface_config_v6only_cmd,
-       "neighbor WORD interface v6only [peer-group PGNAME]",
-       NEIGHBOR_STR
-       "Interface name or neighbor tag\n"
-       "Enable BGP on interface\n"
-       "Enable BGP with v6 link-local only\n"
-       "Member of the peer-group\n"
-       "Peer-group name\n")
-{
-       int idx_word = 1;
-       int idx_peer_group_word = 5;
+       /* Convert IP prefix string to struct prefix. */
+       ret = str2prefix(prefix, &range);
+       if (!ret) {
+               vty_out(vty, "%% Malformed listen range\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
 
-       if (argc > idx_peer_group_word)
-               return peer_conf_interface_get(
-                       vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 1,
-                       argv[idx_peer_group_word]->arg, NULL);
+       afi = family2afi(range.family);
 
-       return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
-                                      SAFI_UNICAST, 1, NULL, NULL);
-}
+       if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&range.u.prefix6)) {
+               vty_out(vty,
+                       "%% Malformed listen range (link-local address)\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
 
+       apply_mask(&range);
 
-DEFUN (neighbor_interface_config_remote_as,
-       neighbor_interface_config_remote_as_cmd,
-       "neighbor WORD interface remote-as <(1-4294967295)|internal|external>",
-       NEIGHBOR_STR
-       "Interface name or neighbor tag\n"
-       "Enable BGP on interface\n"
-       "Specify a BGP neighbor\n"
-       AS_STR
-       "Internal BGP peer\n"
-       "External BGP peer\n")
-{
-       int idx_word = 1;
-       int idx_remote_as = 4;
-       return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
-                                      SAFI_UNICAST, 0, NULL,
-                                      argv[idx_remote_as]->arg);
-}
+       /* Check if same listen range is already configured. */
+       existing_group = listen_range_exists(bgp, &range, 1);
+       if (existing_group) {
+               if (strcmp(existing_group->name, peergroup) == 0)
+                       return CMD_SUCCESS;
+               else {
+                       vty_out(vty,
+                               "%% Same listen range is attached to peer-group %s\n",
+                               existing_group->name);
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+       }
 
-DEFUN (neighbor_interface_v6only_config_remote_as,
-       neighbor_interface_v6only_config_remote_as_cmd,
-       "neighbor WORD interface v6only remote-as <(1-4294967295)|internal|external>",
-       NEIGHBOR_STR
-       "Interface name or neighbor tag\n"
-       "Enable BGP with v6 link-local only\n"
-       "Enable BGP on interface\n"
-       "Specify a BGP neighbor\n"
-       AS_STR
-       "Internal BGP peer\n"
-       "External BGP peer\n")
-{
-       int idx_word = 1;
-       int idx_remote_as = 5;
-       return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
-                                      SAFI_UNICAST, 1, NULL,
-                                      argv[idx_remote_as]->arg);
+       /* Check if an overlapping listen range exists. */
+       if (listen_range_exists(bgp, &range, 0)) {
+               vty_out(vty,
+                       "%% Listen range overlaps with existing listen range\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       group = peer_group_lookup(bgp, peergroup);
+       if (!group) {
+               vty_out(vty, "%% Configure the peer-group first\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       ret = peer_group_listen_range_add(group, &range);
+       return bgp_vty_return(vty, ret);
 }
 
-DEFUN (neighbor_peer_group,
-       neighbor_peer_group_cmd,
-       "neighbor WORD peer-group",
-       NEIGHBOR_STR
-       "Interface name or neighbor tag\n"
-       "Configure peer-group\n")
+DEFUN (no_bgp_listen_range,
+       no_bgp_listen_range_cmd,
+       "no bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME",
+       NO_STR
+       "BGP specific commands\n"
+       "Unconfigure BGP dynamic neighbors listen range\n"
+       "Unconfigure BGP dynamic neighbors listen range\n"
+       NEIGHBOR_ADDR_STR
+       "Member of the peer-group\n"
+       "Peer-group name\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_word = 1;
-       struct peer *peer;
+       struct prefix range;
        struct peer_group *group;
+       afi_t afi;
+       int ret;
+       int idx = 0;
 
-       peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
-       if (peer) {
-               vty_out(vty, "%% Name conflict with interface: \n");
+       argv_find(argv, argc, "A.B.C.D/M", &idx);
+       argv_find(argv, argc, "X:X::X:X/M", &idx);
+       char *prefix = argv[idx]->arg;
+       argv_find(argv, argc, "PGNAME", &idx);
+       char *peergroup = argv[idx]->arg;
+
+       /* Convert IP prefix string to struct prefix. */
+       ret = str2prefix(prefix, &range);
+       if (!ret) {
+               vty_out(vty, "%% Malformed listen range\n");
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       group = peer_group_get(bgp, argv[idx_word]->arg);
+       afi = family2afi(range.family);
+
+       if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&range.u.prefix6)) {
+               vty_out(vty,
+                       "%% Malformed listen range (link-local address)\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       apply_mask(&range);
+
+       group = peer_group_lookup(bgp, peergroup);
        if (!group) {
-               vty_out(vty, "%% BGP failed to find or create peer-group\n");
+               vty_out(vty, "%% Peer-group does not exist\n");
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       return CMD_SUCCESS;
+       ret = peer_group_listen_range_del(group, &range);
+       return bgp_vty_return(vty, ret);
 }
 
-DEFUN (no_neighbor,
-       no_neighbor_cmd,
-       "no neighbor <WORD|<A.B.C.D|X:X::X:X> [remote-as <(1-4294967295)|internal|external>]>",
-       NO_STR
-       NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Specify a BGP neighbor\n"
-       AS_STR
-       "Internal BGP peer\n"
-       "External BGP peer\n")
+void bgp_config_write_listen(struct vty *vty, struct bgp *bgp)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_peer = 2;
-       int ret;
-       union sockunion su;
        struct peer_group *group;
-       struct peer *peer;
-       struct peer *other;
+       struct listnode *node, *nnode, *rnode, *nrnode;
+       struct prefix *range;
+       afi_t afi;
+       char buf[PREFIX2STR_BUFFER];
 
-       ret = str2sockunion(argv[idx_peer]->arg, &su);
-       if (ret < 0) {
-               /* look up for neighbor by interface name config. */
-               peer = peer_lookup_by_conf_if(bgp, argv[idx_peer]->arg);
-               if (peer) {
-                       /* Request zebra to terminate IPv6 RAs on this
-                        * interface. */
-                       if (peer->ifp)
-                               bgp_zebra_terminate_radv(peer->bgp, peer);
-                       peer_notify_unconfig(peer);
-                       peer_delete(peer);
-                       return CMD_SUCCESS;
-               }
+       if (bgp->dynamic_neighbors_limit != BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT)
+               vty_out(vty, " bgp listen limit %d\n",
+                       bgp->dynamic_neighbors_limit);
 
-               group = peer_group_lookup(bgp, argv[idx_peer]->arg);
-               if (group) {
-                       peer_group_notify_unconfig(group);
-                       peer_group_delete(group);
-               } else {
-                       vty_out(vty, "%% Create the peer-group first\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       } else {
-               peer = peer_lookup(bgp, &su);
-               if (peer) {
-                       if (peer_dynamic_neighbor(peer)) {
+       for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
+               for (afi = AFI_IP; afi < AFI_MAX; afi++) {
+                       for (ALL_LIST_ELEMENTS(group->listen_range[afi], rnode,
+                                              nrnode, range)) {
+                               prefix2str(range, buf, sizeof(buf));
                                vty_out(vty,
-                                       "%% Operation not allowed on a dynamic neighbor\n");
-                               return CMD_WARNING_CONFIG_FAILED;
-                       }
-
-                       other = peer->doppelganger;
-                       peer_notify_unconfig(peer);
-                       peer_delete(peer);
-                       if (other && other->status != Deleted) {
-                               peer_notify_unconfig(other);
-                               peer_delete(other);
+                                       " bgp listen range %s peer-group %s\n",
+                                       buf, group->name);
                        }
                }
        }
+}
+
+
+DEFUN (bgp_disable_connected_route_check,
+       bgp_disable_connected_route_check_cmd,
+       "bgp disable-ebgp-connected-route-check",
+       "BGP specific commands\n"
+       "Disable checking if nexthop is connected on ebgp sessions\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       bgp_flag_set(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
+       bgp_clear_star_soft_in(vty, bgp->name);
 
        return CMD_SUCCESS;
 }
 
-DEFUN (no_neighbor_interface_config,
-       no_neighbor_interface_config_cmd,
-       "no neighbor WORD interface [v6only] [peer-group PGNAME] [remote-as <(1-4294967295)|internal|external>]",
+DEFUN (no_bgp_disable_connected_route_check,
+       no_bgp_disable_connected_route_check_cmd,
+       "no bgp disable-ebgp-connected-route-check",
        NO_STR
-       NEIGHBOR_STR
-       "Interface name\n"
-       "Configure BGP on interface\n"
-       "Enable BGP with v6 link-local only\n"
-       "Member of the peer-group\n"
-       "Peer-group name\n"
-       "Specify a BGP neighbor\n"
-       AS_STR
-       "Internal BGP peer\n"
-       "External BGP peer\n")
+       "BGP specific commands\n"
+       "Disable checking if nexthop is connected on ebgp sessions\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_word = 2;
-       struct peer *peer;
+       bgp_flag_unset(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
+       bgp_clear_star_soft_in(vty, bgp->name);
 
-       /* look up for neighbor by interface name config. */
-       peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
-       if (peer) {
-               /* Request zebra to terminate IPv6 RAs on this interface. */
-               if (peer->ifp)
-                       bgp_zebra_terminate_radv(peer->bgp, peer);
-               peer_notify_unconfig(peer);
-               peer_delete(peer);
-       } else {
-               vty_out(vty, "%% Create the bgp interface first\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
        return CMD_SUCCESS;
 }
 
-DEFUN (no_neighbor_peer_group,
-       no_neighbor_peer_group_cmd,
-       "no neighbor WORD peer-group",
-       NO_STR
-       NEIGHBOR_STR
-       "Neighbor tag\n"
-       "Configure peer-group\n")
+
+static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
+                             const char *as_str, afi_t afi, safi_t safi)
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_word = 2;
-       struct peer_group *group;
+       int ret;
+       as_t as;
+       int as_type = AS_SPECIFIED;
+       union sockunion su;
 
-       group = peer_group_lookup(bgp, argv[idx_word]->arg);
-       if (group) {
-               peer_group_notify_unconfig(group);
-               peer_group_delete(group);
+       if (as_str[0] == 'i') {
+               as = 0;
+               as_type = AS_INTERNAL;
+       } else if (as_str[0] == 'e') {
+               as = 0;
+               as_type = AS_EXTERNAL;
        } else {
-               vty_out(vty, "%% Create the peer-group first\n");
+               /* Get AS number.  */
+               as = strtoul(as_str, NULL, 10);
+       }
+
+       /* If peer is peer group or interface peer, call proper function. */
+       ret = str2sockunion(peer_str, &su);
+       if (ret < 0) {
+               struct peer *peer;
+
+               /* Check if existing interface peer */
+               peer = peer_lookup_by_conf_if(bgp, peer_str);
+
+               ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type, afi,
+                                    safi);
+
+               /* if not interface peer, check peer-group settings */
+               if (ret < 0 && !peer) {
+                       ret = peer_group_remote_as(bgp, peer_str, &as, as_type);
+                       if (ret < 0) {
+                               vty_out(vty,
+                                       "%% Create the peer-group or interface first\n");
+                               return CMD_WARNING_CONFIG_FAILED;
+                       }
+                       return CMD_SUCCESS;
+               }
+       } else {
+               if (peer_address_self_check(bgp, &su)) {
+                       vty_out(vty,
+                               "%% Can not configure the local system as neighbor\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+               ret = peer_remote_as(bgp, &su, NULL, &as, as_type, afi, safi);
+       }
+
+       /* This peer belongs to peer group.  */
+       switch (ret) {
+       case BGP_ERR_PEER_GROUP_MEMBER:
+               vty_out(vty,
+                       "%% Peer-group member cannot override remote-as of peer-group\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       case BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT:
+               vty_out(vty,
+                       "%% Peer-group members must be all internal or all external\n");
                return CMD_WARNING_CONFIG_FAILED;
        }
-       return CMD_SUCCESS;
+       return bgp_vty_return(vty, ret);
 }
 
-DEFUN (no_neighbor_interface_peer_group_remote_as,
-       no_neighbor_interface_peer_group_remote_as_cmd,
-       "no neighbor WORD remote-as <(1-4294967295)|internal|external>",
+DEFUN (bgp_default_shutdown,
+       bgp_default_shutdown_cmd,
+       "[no] bgp default shutdown",
        NO_STR
+       BGP_STR
+       "Configure BGP defaults\n"
+       "Apply administrative shutdown to newly configured peers\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       bgp->autoshutdown = !strmatch(argv[0]->text, "no");
+       return CMD_SUCCESS;
+}
+
+DEFUN (neighbor_remote_as,
+       neighbor_remote_as_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> remote-as <(1-4294967295)|internal|external>",
        NEIGHBOR_STR
-       "Interface name or neighbor tag\n"
+       NEIGHBOR_ADDR_STR2
        "Specify a BGP neighbor\n"
        AS_STR
        "Internal BGP peer\n"
        "External BGP peer\n")
+{
+       int idx_peer = 1;
+       int idx_remote_as = 3;
+       return peer_remote_as_vty(vty, argv[idx_peer]->arg,
+                                 argv[idx_remote_as]->arg, AFI_IP,
+                                 SAFI_UNICAST);
+}
+
+static int peer_conf_interface_get(struct vty *vty, const char *conf_if,
+                                  afi_t afi, safi_t safi, int v6only,
+                                  const char *peer_group_name,
+                                  const char *as_str)
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_word = 2;
-       struct peer_group *group;
+       as_t as = 0;
+       int as_type = AS_UNSPECIFIED;
        struct peer *peer;
+       struct peer_group *group;
+       int ret = 0;
+       union sockunion su;
 
-       /* look up for neighbor by interface name config. */
-       peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
-       if (peer) {
-               peer_as_change(peer, 0, AS_UNSPECIFIED);
-               return CMD_SUCCESS;
-       }
+       group = peer_group_lookup(bgp, conf_if);
 
-       group = peer_group_lookup(bgp, argv[idx_word]->arg);
-       if (group)
-               peer_group_remote_as_delete(group);
-       else {
-               vty_out(vty, "%% Create the peer-group or interface first\n");
+       if (group) {
+               vty_out(vty, "%% Name conflict with peer-group \n");
                return CMD_WARNING_CONFIG_FAILED;
        }
-       return CMD_SUCCESS;
-}
 
-DEFUN (neighbor_local_as,
-       neighbor_local_as_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295)",
-       NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Specify a local-as number\n"
-       "AS number used as local AS\n")
-{
-       int idx_peer = 1;
-       int idx_number = 3;
-       struct peer *peer;
-       int ret;
-       as_t as;
+       if (as_str) {
+               if (as_str[0] == 'i') {
+                       as_type = AS_INTERNAL;
+               } else if (as_str[0] == 'e') {
+                       as_type = AS_EXTERNAL;
+               } else {
+                       /* Get AS number.  */
+                       as = strtoul(as_str, NULL, 10);
+                       as_type = AS_SPECIFIED;
+               }
+       }
 
-       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
-       if (!peer)
-               return CMD_WARNING_CONFIG_FAILED;
+       peer = peer_lookup_by_conf_if(bgp, conf_if);
+       if (peer) {
+               if (as_str)
+                       ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type,
+                                            afi, safi);
+       } else {
+               if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4)
+                   && afi == AFI_IP && safi == SAFI_UNICAST)
+                       peer = peer_create(NULL, conf_if, bgp, bgp->as, as,
+                                          as_type, 0, 0, NULL);
+               else
+                       peer = peer_create(NULL, conf_if, bgp, bgp->as, as,
+                                          as_type, afi, safi, NULL);
 
-       as = strtoul(argv[idx_number]->arg, NULL, 10);
-       ret = peer_local_as_set(peer, as, 0, 0);
-       return bgp_vty_return(vty, ret);
-}
+               if (!peer) {
+                       vty_out(vty, "%% BGP failed to create peer\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
 
-DEFUN (neighbor_local_as_no_prepend,
-       neighbor_local_as_no_prepend_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295) no-prepend",
-       NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Specify a local-as number\n"
-       "AS number used as local AS\n"
-       "Do not prepend local-as to updates from ebgp peers\n")
-{
-       int idx_peer = 1;
-       int idx_number = 3;
-       struct peer *peer;
-       int ret;
-       as_t as;
+               if (v6only)
+                       peer_flag_set(peer, PEER_FLAG_IFPEER_V6ONLY);
 
-       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
-       if (!peer)
-               return CMD_WARNING_CONFIG_FAILED;
+               /* Request zebra to initiate IPv6 RAs on this interface. We do
+                * this
+                * any unnumbered peer in order to not worry about run-time
+                * transitions
+                * (e.g., peering is initially IPv4, but the IPv4 /30 or /31
+                * address
+                * gets deleted later etc.)
+                */
+               if (peer->ifp)
+                       bgp_zebra_initiate_radv(bgp, peer);
+       }
 
-       as = strtoul(argv[idx_number]->arg, NULL, 10);
-       ret = peer_local_as_set(peer, as, 1, 0);
-       return bgp_vty_return(vty, ret);
-}
+       if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
+           || (!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))) {
+               if (v6only)
+                       peer_flag_set(peer, PEER_FLAG_IFPEER_V6ONLY);
+               else
+                       peer_flag_unset(peer, PEER_FLAG_IFPEER_V6ONLY);
 
-DEFUN (neighbor_local_as_no_prepend_replace_as,
-       neighbor_local_as_no_prepend_replace_as_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295) no-prepend replace-as",
-       NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Specify a local-as number\n"
-       "AS number used as local AS\n"
-       "Do not prepend local-as to updates from ebgp peers\n"
-       "Do not prepend local-as to updates from ibgp peers\n")
-{
-       int idx_peer = 1;
-       int idx_number = 3;
-       struct peer *peer;
-       int ret;
-       as_t as;
+               /* v6only flag changed. Reset bgp seesion */
+               if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
+                       peer->last_reset = PEER_DOWN_V6ONLY_CHANGE;
+                       bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+                                       BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+               } else
+                       bgp_session_reset(peer);
+       }
 
-       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
-       if (!peer)
-               return CMD_WARNING_CONFIG_FAILED;
+       if (!CHECK_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE)) {
+               SET_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE);
+               SET_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE);
+               SET_FLAG(peer->flags_override, PEER_FLAG_CAPABILITY_ENHE);
+       }
+
+       if (peer_group_name) {
+               group = peer_group_lookup(bgp, peer_group_name);
+               if (!group) {
+                       vty_out(vty, "%% Configure the peer-group first\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+
+               ret = peer_group_bind(bgp, &su, peer, group, &as);
+       }
 
-       as = strtoul(argv[idx_number]->arg, NULL, 10);
-       ret = peer_local_as_set(peer, as, 1, 1);
        return bgp_vty_return(vty, ret);
 }
 
-DEFUN (no_neighbor_local_as,
-       no_neighbor_local_as_cmd,
-       "no neighbor <A.B.C.D|X:X::X:X|WORD> local-as [(1-4294967295) [no-prepend [replace-as]]]",
-       NO_STR
+DEFUN (neighbor_interface_config,
+       neighbor_interface_config_cmd,
+       "neighbor WORD interface [peer-group PGNAME]",
        NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Specify a local-as number\n"
-       "AS number used as local AS\n"
-       "Do not prepend local-as to updates from ebgp peers\n"
-       "Do not prepend local-as to updates from ibgp peers\n")
+       "Interface name or neighbor tag\n"
+       "Enable BGP on interface\n"
+       "Member of the peer-group\n"
+       "Peer-group name\n")
 {
-       int idx_peer = 2;
-       struct peer *peer;
-       int ret;
-
-       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
-       if (!peer)
-               return CMD_WARNING_CONFIG_FAILED;
+       int idx_word = 1;
+       int idx_peer_group_word = 4;
 
-       ret = peer_local_as_unset(peer);
-       return bgp_vty_return(vty, ret);
+       if (argc > idx_peer_group_word)
+               return peer_conf_interface_get(
+                       vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 0,
+                       argv[idx_peer_group_word]->arg, NULL);
+       else
+               return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
+                                              SAFI_UNICAST, 0, NULL, NULL);
 }
 
-
-DEFUN (neighbor_solo,
-       neighbor_solo_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> solo",
+DEFUN (neighbor_interface_config_v6only,
+       neighbor_interface_config_v6only_cmd,
+       "neighbor WORD interface v6only [peer-group PGNAME]",
        NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Solo peer - part of its own update group\n")
+       "Interface name or neighbor tag\n"
+       "Enable BGP on interface\n"
+       "Enable BGP with v6 link-local only\n"
+       "Member of the peer-group\n"
+       "Peer-group name\n")
 {
-       int idx_peer = 1;
-       struct peer *peer;
-       int ret;
+       int idx_word = 1;
+       int idx_peer_group_word = 5;
 
-       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
-       if (!peer)
-               return CMD_WARNING_CONFIG_FAILED;
+       if (argc > idx_peer_group_word)
+               return peer_conf_interface_get(
+                       vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 1,
+                       argv[idx_peer_group_word]->arg, NULL);
 
-       ret = update_group_adjust_soloness(peer, 1);
-       return bgp_vty_return(vty, ret);
+       return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
+                                      SAFI_UNICAST, 1, NULL, NULL);
 }
 
-DEFUN (no_neighbor_solo,
-       no_neighbor_solo_cmd,
-       "no neighbor <A.B.C.D|X:X::X:X|WORD> solo",
-       NO_STR
-       NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Solo peer - part of its own update group\n")
-{
-       int idx_peer = 2;
-       struct peer *peer;
-       int ret;
-
-       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
-       if (!peer)
-               return CMD_WARNING_CONFIG_FAILED;
-
-       ret = update_group_adjust_soloness(peer, 0);
-       return bgp_vty_return(vty, ret);
-}
 
-DEFUN (neighbor_password,
-       neighbor_password_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> password LINE",
+DEFUN (neighbor_interface_config_remote_as,
+       neighbor_interface_config_remote_as_cmd,
+       "neighbor WORD interface remote-as <(1-4294967295)|internal|external>",
        NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Set a password\n"
-       "The password\n")
+       "Interface name or neighbor tag\n"
+       "Enable BGP on interface\n"
+       "Specify a BGP neighbor\n"
+       AS_STR
+       "Internal BGP peer\n"
+       "External BGP peer\n")
 {
-       int idx_peer = 1;
-       int idx_line = 3;
-       struct peer *peer;
-       int ret;
-
-       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
-       if (!peer)
-               return CMD_WARNING_CONFIG_FAILED;
-
-       ret = peer_password_set(peer, argv[idx_line]->arg);
-       return bgp_vty_return(vty, ret);
+       int idx_word = 1;
+       int idx_remote_as = 4;
+       return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
+                                      SAFI_UNICAST, 0, NULL,
+                                      argv[idx_remote_as]->arg);
 }
 
-DEFUN (no_neighbor_password,
-       no_neighbor_password_cmd,
-       "no neighbor <A.B.C.D|X:X::X:X|WORD> password [LINE]",
-       NO_STR
+DEFUN (neighbor_interface_v6only_config_remote_as,
+       neighbor_interface_v6only_config_remote_as_cmd,
+       "neighbor WORD interface v6only remote-as <(1-4294967295)|internal|external>",
        NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Set a password\n"
-       "The password\n")
+       "Interface name or neighbor tag\n"
+       "Enable BGP with v6 link-local only\n"
+       "Enable BGP on interface\n"
+       "Specify a BGP neighbor\n"
+       AS_STR
+       "Internal BGP peer\n"
+       "External BGP peer\n")
 {
-       int idx_peer = 2;
-       struct peer *peer;
-       int ret;
-
-       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
-       if (!peer)
-               return CMD_WARNING_CONFIG_FAILED;
-
-       ret = peer_password_unset(peer);
-       return bgp_vty_return(vty, ret);
+       int idx_word = 1;
+       int idx_remote_as = 5;
+       return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
+                                      SAFI_UNICAST, 1, NULL,
+                                      argv[idx_remote_as]->arg);
 }
 
-DEFUN (neighbor_activate,
-       neighbor_activate_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> activate",
+DEFUN (neighbor_peer_group,
+       neighbor_peer_group_cmd,
+       "neighbor WORD peer-group",
        NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Enable the Address Family for this Neighbor\n")
+       "Interface name or neighbor tag\n"
+       "Configure peer-group\n")
 {
-       int idx_peer = 1;
-       int ret;
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       int idx_word = 1;
        struct peer *peer;
+       struct peer_group *group;
 
-       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
-       if (!peer)
+       peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
+       if (peer) {
+               vty_out(vty, "%% Name conflict with interface: \n");
                return CMD_WARNING_CONFIG_FAILED;
+       }
 
-       ret = peer_activate(peer, bgp_node_afi(vty), bgp_node_safi(vty));
-       return bgp_vty_return(vty, ret);
-}
-
-ALIAS_HIDDEN(neighbor_activate, neighbor_activate_hidden_cmd,
-            "neighbor <A.B.C.D|X:X::X:X|WORD> activate",
-            NEIGHBOR_STR NEIGHBOR_ADDR_STR2
-            "Enable the Address Family for this Neighbor\n")
-
-DEFUN (no_neighbor_activate,
-       no_neighbor_activate_cmd,
-       "no neighbor <A.B.C.D|X:X::X:X|WORD> activate",
-       NO_STR
-       NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Enable the Address Family for this Neighbor\n")
-{
-       int idx_peer = 2;
-       int ret;
-       struct peer *peer;
-
-       /* Lookup peer. */
-       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
-       if (!peer)
+       group = peer_group_get(bgp, argv[idx_word]->arg);
+       if (!group) {
+               vty_out(vty, "%% BGP failed to find or create peer-group\n");
                return CMD_WARNING_CONFIG_FAILED;
+       }
 
-       ret = peer_deactivate(peer, bgp_node_afi(vty), bgp_node_safi(vty));
-       return bgp_vty_return(vty, ret);
+       return CMD_SUCCESS;
 }
 
-ALIAS_HIDDEN(no_neighbor_activate, no_neighbor_activate_hidden_cmd,
-            "no neighbor <A.B.C.D|X:X::X:X|WORD> activate",
-            NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
-            "Enable the Address Family for this Neighbor\n")
-
-DEFUN (neighbor_set_peer_group,
-       neighbor_set_peer_group_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
+DEFUN (no_neighbor,
+       no_neighbor_cmd,
+       "no neighbor <WORD|<A.B.C.D|X:X::X:X> [remote-as <(1-4294967295)|internal|external>]>",
+       NO_STR
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Member of the peer-group\n"
-       "Peer-group name\n")
+       "Specify a BGP neighbor\n"
+       AS_STR
+       "Internal BGP peer\n"
+       "External BGP peer\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_peer = 1;
-       int idx_word = 3;
+       int idx_peer = 2;
        int ret;
-       as_t as;
        union sockunion su;
-       struct peer *peer;
        struct peer_group *group;
+       struct peer *peer;
+       struct peer *other;
 
        ret = str2sockunion(argv[idx_peer]->arg, &su);
        if (ret < 0) {
+               /* look up for neighbor by interface name config. */
                peer = peer_lookup_by_conf_if(bgp, argv[idx_peer]->arg);
-               if (!peer) {
-                       vty_out(vty, "%% Malformed address or name: %s\n",
-                               argv[idx_peer]->arg);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       } else {
-               if (peer_address_self_check(bgp, &su)) {
-                       vty_out(vty,
-                               "%% Can not configure the local system as neighbor\n");
-                       return CMD_WARNING_CONFIG_FAILED;
+               if (peer) {
+                       /* Request zebra to terminate IPv6 RAs on this
+                        * interface. */
+                       if (peer->ifp)
+                               bgp_zebra_terminate_radv(peer->bgp, peer);
+                       peer_notify_unconfig(peer);
+                       peer_delete(peer);
+                       return CMD_SUCCESS;
                }
 
-               /* Disallow for dynamic neighbor. */
-               peer = peer_lookup(bgp, &su);
-               if (peer && peer_dynamic_neighbor(peer)) {
-                       vty_out(vty,
-                               "%% Operation not allowed on a dynamic neighbor\n");
+               group = peer_group_lookup(bgp, argv[idx_peer]->arg);
+               if (group) {
+                       peer_group_notify_unconfig(group);
+                       peer_group_delete(group);
+               } else {
+                       vty_out(vty, "%% Create the peer-group first\n");
                        return CMD_WARNING_CONFIG_FAILED;
                }
-       }
-
-       group = peer_group_lookup(bgp, argv[idx_word]->arg);
-       if (!group) {
-               vty_out(vty, "%% Configure the peer-group first\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       ret = peer_group_bind(bgp, &su, peer, group, &as);
+       } else {
+               peer = peer_lookup(bgp, &su);
+               if (peer) {
+                       if (peer_dynamic_neighbor(peer)) {
+                               vty_out(vty,
+                                       "%% Operation not allowed on a dynamic neighbor\n");
+                               return CMD_WARNING_CONFIG_FAILED;
+                       }
 
-       if (ret == BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT) {
-               vty_out(vty,
-                       "%% Peer with AS %u cannot be in this peer-group, members must be all internal or all external\n",
-                       as);
-               return CMD_WARNING_CONFIG_FAILED;
+                       other = peer->doppelganger;
+                       peer_notify_unconfig(peer);
+                       peer_delete(peer);
+                       if (other && other->status != Deleted) {
+                               peer_notify_unconfig(other);
+                               peer_delete(other);
+                       }
+               }
        }
 
-       return bgp_vty_return(vty, ret);
+       return CMD_SUCCESS;
 }
 
-ALIAS_HIDDEN(neighbor_set_peer_group, neighbor_set_peer_group_hidden_cmd,
-            "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
-            NEIGHBOR_STR NEIGHBOR_ADDR_STR2
-            "Member of the peer-group\n"
-            "Peer-group name\n")
-
-DEFUN (no_neighbor_set_peer_group,
-       no_neighbor_set_peer_group_cmd,
-       "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
+DEFUN (no_neighbor_interface_config,
+       no_neighbor_interface_config_cmd,
+       "no neighbor WORD interface [v6only] [peer-group PGNAME] [remote-as <(1-4294967295)|internal|external>]",
        NO_STR
        NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
+       "Interface name\n"
+       "Configure BGP on interface\n"
+       "Enable BGP with v6 link-local only\n"
        "Member of the peer-group\n"
-       "Peer-group name\n")
+       "Peer-group name\n"
+       "Specify a BGP neighbor\n"
+       AS_STR
+       "Internal BGP peer\n"
+       "External BGP peer\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_peer = 2;
-       int idx_word = 4;
-       int ret;
+       int idx_word = 2;
        struct peer *peer;
-       struct peer_group *group;
 
-       peer = peer_lookup_vty(vty, argv[idx_peer]->arg);
-       if (!peer)
+       /* look up for neighbor by interface name config. */
+       peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
+       if (peer) {
+               /* Request zebra to terminate IPv6 RAs on this interface. */
+               if (peer->ifp)
+                       bgp_zebra_terminate_radv(peer->bgp, peer);
+               peer_notify_unconfig(peer);
+               peer_delete(peer);
+       } else {
+               vty_out(vty, "%% Create the bgp interface first\n");
                return CMD_WARNING_CONFIG_FAILED;
+       }
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_neighbor_peer_group,
+       no_neighbor_peer_group_cmd,
+       "no neighbor WORD peer-group",
+       NO_STR
+       NEIGHBOR_STR
+       "Neighbor tag\n"
+       "Configure peer-group\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       int idx_word = 2;
+       struct peer_group *group;
 
        group = peer_group_lookup(bgp, argv[idx_word]->arg);
-       if (!group) {
-               vty_out(vty, "%% Configure the peer-group first\n");
+       if (group) {
+               peer_group_notify_unconfig(group);
+               peer_group_delete(group);
+       } else {
+               vty_out(vty, "%% Create the peer-group first\n");
                return CMD_WARNING_CONFIG_FAILED;
        }
-
-       peer_notify_unconfig(peer);
-       ret = peer_delete(peer);
-
-       return bgp_vty_return(vty, ret);
+       return CMD_SUCCESS;
 }
 
-ALIAS_HIDDEN(no_neighbor_set_peer_group, no_neighbor_set_peer_group_hidden_cmd,
-            "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
-            NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
-            "Member of the peer-group\n"
-            "Peer-group name\n")
-
-static int peer_flag_modify_vty(struct vty *vty, const char *ip_str,
-                               uint32_t flag, int set)
+DEFUN (no_neighbor_interface_peer_group_remote_as,
+       no_neighbor_interface_peer_group_remote_as_cmd,
+       "no neighbor WORD remote-as <(1-4294967295)|internal|external>",
+       NO_STR
+       NEIGHBOR_STR
+       "Interface name or neighbor tag\n"
+       "Specify a BGP neighbor\n"
+       AS_STR
+       "Internal BGP peer\n"
+       "External BGP peer\n")
 {
-       int ret;
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       int idx_word = 2;
+       struct peer_group *group;
        struct peer *peer;
 
-       peer = peer_and_group_lookup_vty(vty, ip_str);
-       if (!peer)
-               return CMD_WARNING_CONFIG_FAILED;
+       /* look up for neighbor by interface name config. */
+       peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
+       if (peer) {
+               peer_as_change(peer, 0, AS_UNSPECIFIED);
+               return CMD_SUCCESS;
+       }
 
-       /*
-        * If 'neighbor <interface>', then this is for directly connected peers,
-        * we should not accept disable-connected-check.
-        */
-       if (peer->conf_if && (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)) {
-               vty_out(vty,
-                       "%s is directly connected peer, cannot accept disable-"
-                       "connected-check\n",
-                       ip_str);
+       group = peer_group_lookup(bgp, argv[idx_word]->arg);
+       if (group)
+               peer_group_remote_as_delete(group);
+       else {
+               vty_out(vty, "%% Create the peer-group or interface first\n");
                return CMD_WARNING_CONFIG_FAILED;
        }
+       return CMD_SUCCESS;
+}
 
-       if (!set && flag == PEER_FLAG_SHUTDOWN)
-               peer_tx_shutdown_message_unset(peer);
+DEFUN (neighbor_local_as,
+       neighbor_local_as_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295)",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Specify a local-as number\n"
+       "AS number used as local AS\n")
+{
+       int idx_peer = 1;
+       int idx_number = 3;
+       struct peer *peer;
+       int ret;
+       as_t as;
 
-       if (set)
-               ret = peer_flag_set(peer, flag);
-       else
-               ret = peer_flag_unset(peer, flag);
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
 
+       as = strtoul(argv[idx_number]->arg, NULL, 10);
+       ret = peer_local_as_set(peer, as, 0, 0);
        return bgp_vty_return(vty, ret);
 }
 
-static int peer_flag_set_vty(struct vty *vty, const char *ip_str, uint32_t flag)
+DEFUN (neighbor_local_as_no_prepend,
+       neighbor_local_as_no_prepend_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295) no-prepend",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Specify a local-as number\n"
+       "AS number used as local AS\n"
+       "Do not prepend local-as to updates from ebgp peers\n")
 {
-       return peer_flag_modify_vty(vty, ip_str, flag, 1);
-}
+       int idx_peer = 1;
+       int idx_number = 3;
+       struct peer *peer;
+       int ret;
+       as_t as;
 
-static int peer_flag_unset_vty(struct vty *vty, const char *ip_str,
-                              uint32_t flag)
-{
-       return peer_flag_modify_vty(vty, ip_str, flag, 0);
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       as = strtoul(argv[idx_number]->arg, NULL, 10);
+       ret = peer_local_as_set(peer, as, 1, 0);
+       return bgp_vty_return(vty, ret);
 }
 
-/* neighbor passive. */
-DEFUN (neighbor_passive,
-       neighbor_passive_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> passive",
+DEFUN (neighbor_local_as_no_prepend_replace_as,
+       neighbor_local_as_no_prepend_replace_as_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295) no-prepend replace-as",
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Don't send open messages to this neighbor\n")
+       "Specify a local-as number\n"
+       "AS number used as local AS\n"
+       "Do not prepend local-as to updates from ebgp peers\n"
+       "Do not prepend local-as to updates from ibgp peers\n")
 {
        int idx_peer = 1;
-       return peer_flag_set_vty(vty, argv[idx_peer]->arg, PEER_FLAG_PASSIVE);
+       int idx_number = 3;
+       struct peer *peer;
+       int ret;
+       as_t as;
+
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       as = strtoul(argv[idx_number]->arg, NULL, 10);
+       ret = peer_local_as_set(peer, as, 1, 1);
+       return bgp_vty_return(vty, ret);
 }
 
-DEFUN (no_neighbor_passive,
-       no_neighbor_passive_cmd,
-       "no neighbor <A.B.C.D|X:X::X:X|WORD> passive",
+DEFUN (no_neighbor_local_as,
+       no_neighbor_local_as_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> local-as [(1-4294967295) [no-prepend [replace-as]]]",
        NO_STR
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Don't send open messages to this neighbor\n")
+       "Specify a local-as number\n"
+       "AS number used as local AS\n"
+       "Do not prepend local-as to updates from ebgp peers\n"
+       "Do not prepend local-as to updates from ibgp peers\n")
 {
        int idx_peer = 2;
-       return peer_flag_unset_vty(vty, argv[idx_peer]->arg, PEER_FLAG_PASSIVE);
+       struct peer *peer;
+       int ret;
+
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       ret = peer_local_as_unset(peer);
+       return bgp_vty_return(vty, ret);
 }
 
-/* neighbor shutdown. */
-DEFUN (neighbor_shutdown_msg,
-       neighbor_shutdown_msg_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown message MSG...",
+
+DEFUN (neighbor_solo,
+       neighbor_solo_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> solo",
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Administratively shut down this neighbor\n"
-       "Add a shutdown message (draft-ietf-idr-shutdown-06)\n"
-       "Shutdown message\n")
+       "Solo peer - part of its own update group\n")
 {
        int idx_peer = 1;
+       struct peer *peer;
+       int ret;
 
-       if (argc >= 5) {
-               struct peer *peer =
-                       peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
-               char *message;
-
-               if (!peer)
-                       return CMD_WARNING_CONFIG_FAILED;
-               message = argv_concat(argv, argc, 4);
-               peer_tx_shutdown_message_set(peer, message);
-               XFREE(MTYPE_TMP, message);
-       }
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
 
-       return peer_flag_set_vty(vty, argv[idx_peer]->arg, PEER_FLAG_SHUTDOWN);
+       ret = update_group_adjust_soloness(peer, 1);
+       return bgp_vty_return(vty, ret);
 }
 
-ALIAS(neighbor_shutdown_msg, neighbor_shutdown_cmd,
-      "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
-      NEIGHBOR_STR NEIGHBOR_ADDR_STR2
-      "Administratively shut down this neighbor\n")
-
-DEFUN (no_neighbor_shutdown_msg,
-       no_neighbor_shutdown_msg_cmd,
-       "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown message MSG...",
+DEFUN (no_neighbor_solo,
+       no_neighbor_solo_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> solo",
        NO_STR
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Administratively shut down this neighbor\n"
-       "Remove a shutdown message (draft-ietf-idr-shutdown-06)\n"
-       "Shutdown message\n")
+       "Solo peer - part of its own update group\n")
 {
        int idx_peer = 2;
+       struct peer *peer;
+       int ret;
 
-       return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
-                                  PEER_FLAG_SHUTDOWN);
-}
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
 
-ALIAS(no_neighbor_shutdown_msg, no_neighbor_shutdown_cmd,
-      "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
-      NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
-      "Administratively shut down this neighbor\n")
+       ret = update_group_adjust_soloness(peer, 0);
+       return bgp_vty_return(vty, ret);
+}
 
-/* neighbor capability dynamic. */
-DEFUN (neighbor_capability_dynamic,
-       neighbor_capability_dynamic_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> capability dynamic",
+DEFUN (neighbor_password,
+       neighbor_password_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> password LINE",
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Advertise capability to the peer\n"
-       "Advertise dynamic capability to this neighbor\n")
+       "Set a password\n"
+       "The password\n")
 {
        int idx_peer = 1;
-       return peer_flag_set_vty(vty, argv[idx_peer]->arg,
-                                PEER_FLAG_DYNAMIC_CAPABILITY);
+       int idx_line = 3;
+       struct peer *peer;
+       int ret;
+
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       ret = peer_password_set(peer, argv[idx_line]->arg);
+       return bgp_vty_return(vty, ret);
 }
 
-DEFUN (no_neighbor_capability_dynamic,
-       no_neighbor_capability_dynamic_cmd,
-       "no neighbor <A.B.C.D|X:X::X:X|WORD> capability dynamic",
+DEFUN (no_neighbor_password,
+       no_neighbor_password_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> password [LINE]",
        NO_STR
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Advertise capability to the peer\n"
-       "Advertise dynamic capability to this neighbor\n")
+       "Set a password\n"
+       "The password\n")
 {
        int idx_peer = 2;
-       return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
-                                  PEER_FLAG_DYNAMIC_CAPABILITY);
+       struct peer *peer;
+       int ret;
+
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       ret = peer_password_unset(peer);
+       return bgp_vty_return(vty, ret);
 }
 
-/* neighbor dont-capability-negotiate */
-DEFUN (neighbor_dont_capability_negotiate,
-       neighbor_dont_capability_negotiate_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> dont-capability-negotiate",
+DEFUN (neighbor_activate,
+       neighbor_activate_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> activate",
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Do not perform capability negotiation\n")
+       "Enable the Address Family for this Neighbor\n")
 {
        int idx_peer = 1;
-       return peer_flag_set_vty(vty, argv[idx_peer]->arg,
-                                PEER_FLAG_DONT_CAPABILITY);
+       int ret;
+       struct peer *peer;
+
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       ret = peer_activate(peer, bgp_node_afi(vty), bgp_node_safi(vty));
+       return bgp_vty_return(vty, ret);
 }
 
-DEFUN (no_neighbor_dont_capability_negotiate,
-       no_neighbor_dont_capability_negotiate_cmd,
-       "no neighbor <A.B.C.D|X:X::X:X|WORD> dont-capability-negotiate",
+ALIAS_HIDDEN(neighbor_activate, neighbor_activate_hidden_cmd,
+            "neighbor <A.B.C.D|X:X::X:X|WORD> activate",
+            NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+            "Enable the Address Family for this Neighbor\n")
+
+DEFUN (no_neighbor_activate,
+       no_neighbor_activate_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> activate",
        NO_STR
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Do not perform capability negotiation\n")
+       "Enable the Address Family for this Neighbor\n")
 {
        int idx_peer = 2;
-       return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
-                                  PEER_FLAG_DONT_CAPABILITY);
+       int ret;
+       struct peer *peer;
+
+       /* Lookup peer. */
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       ret = peer_deactivate(peer, bgp_node_afi(vty), bgp_node_safi(vty));
+       return bgp_vty_return(vty, ret);
 }
 
-/* neighbor capability extended next hop encoding */
-DEFUN (neighbor_capability_enhe,
-       neighbor_capability_enhe_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> capability extended-nexthop",
+ALIAS_HIDDEN(no_neighbor_activate, no_neighbor_activate_hidden_cmd,
+            "no neighbor <A.B.C.D|X:X::X:X|WORD> activate",
+            NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+            "Enable the Address Family for this Neighbor\n")
+
+DEFUN (neighbor_set_peer_group,
+       neighbor_set_peer_group_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Advertise capability to the peer\n"
-       "Advertise extended next-hop capability to the peer\n")
+       "Member of the peer-group\n"
+       "Peer-group name\n")
 {
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_peer = 1;
-       return peer_flag_set_vty(vty, argv[idx_peer]->arg,
-                                PEER_FLAG_CAPABILITY_ENHE);
+       int idx_word = 3;
+       int ret;
+       as_t as;
+       union sockunion su;
+       struct peer *peer;
+       struct peer_group *group;
+
+       ret = str2sockunion(argv[idx_peer]->arg, &su);
+       if (ret < 0) {
+               peer = peer_lookup_by_conf_if(bgp, argv[idx_peer]->arg);
+               if (!peer) {
+                       vty_out(vty, "%% Malformed address or name: %s\n",
+                               argv[idx_peer]->arg);
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+       } else {
+               if (peer_address_self_check(bgp, &su)) {
+                       vty_out(vty,
+                               "%% Can not configure the local system as neighbor\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+
+               /* Disallow for dynamic neighbor. */
+               peer = peer_lookup(bgp, &su);
+               if (peer && peer_dynamic_neighbor(peer)) {
+                       vty_out(vty,
+                               "%% Operation not allowed on a dynamic neighbor\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+       }
+
+       group = peer_group_lookup(bgp, argv[idx_word]->arg);
+       if (!group) {
+               vty_out(vty, "%% Configure the peer-group first\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       ret = peer_group_bind(bgp, &su, peer, group, &as);
+
+       if (ret == BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT) {
+               vty_out(vty,
+                       "%% Peer with AS %u cannot be in this peer-group, members must be all internal or all external\n",
+                       as);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       return bgp_vty_return(vty, ret);
 }
 
-DEFUN (no_neighbor_capability_enhe,
-       no_neighbor_capability_enhe_cmd,
-       "no neighbor <A.B.C.D|X:X::X:X|WORD> capability extended-nexthop",
+ALIAS_HIDDEN(neighbor_set_peer_group, neighbor_set_peer_group_hidden_cmd,
+            "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
+            NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+            "Member of the peer-group\n"
+            "Peer-group name\n")
+
+DEFUN (no_neighbor_set_peer_group,
+       no_neighbor_set_peer_group_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
        NO_STR
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
-       "Advertise capability to the peer\n"
-       "Advertise extended next-hop capability to the peer\n")
+       "Member of the peer-group\n"
+       "Peer-group name\n")
 {
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_peer = 2;
-       return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
-                                  PEER_FLAG_CAPABILITY_ENHE);
-}
-
-static int peer_af_flag_modify_vty(struct vty *vty, const char *peer_str,
-                                  afi_t afi, safi_t safi, uint32_t flag,
-                                  int set)
-{
+       int idx_word = 4;
        int ret;
        struct peer *peer;
+       struct peer_group *group;
 
-       peer = peer_and_group_lookup_vty(vty, peer_str);
+       peer = peer_lookup_vty(vty, argv[idx_peer]->arg);
        if (!peer)
                return CMD_WARNING_CONFIG_FAILED;
 
-       if (set)
-               ret = peer_af_flag_set(peer, afi, safi, flag);
-       else
-               ret = peer_af_flag_unset(peer, afi, safi, flag);
+       group = peer_group_lookup(bgp, argv[idx_word]->arg);
+       if (!group) {
+               vty_out(vty, "%% Configure the peer-group first\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       peer_notify_unconfig(peer);
+       ret = peer_delete(peer);
 
        return bgp_vty_return(vty, ret);
 }
 
-static int peer_af_flag_set_vty(struct vty *vty, const char *peer_str,
-                               afi_t afi, safi_t safi, uint32_t flag)
-{
-       return peer_af_flag_modify_vty(vty, peer_str, afi, safi, flag, 1);
-}
+ALIAS_HIDDEN(no_neighbor_set_peer_group, no_neighbor_set_peer_group_hidden_cmd,
+            "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
+            NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+            "Member of the peer-group\n"
+            "Peer-group name\n")
 
-static int peer_af_flag_unset_vty(struct vty *vty, const char *peer_str,
-                                 afi_t afi, safi_t safi, uint32_t flag)
+static int peer_flag_modify_vty(struct vty *vty, const char *ip_str,
+                               uint32_t flag, int set)
 {
-       return peer_af_flag_modify_vty(vty, peer_str, afi, safi, flag, 0);
+       int ret;
+       struct peer *peer;
+
+       peer = peer_and_group_lookup_vty(vty, ip_str);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       /*
+        * If 'neighbor <interface>', then this is for directly connected peers,
+        * we should not accept disable-connected-check.
+        */
+       if (peer->conf_if && (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)) {
+               vty_out(vty,
+                       "%s is directly connected peer, cannot accept disable-"
+                       "connected-check\n",
+                       ip_str);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       if (!set && flag == PEER_FLAG_SHUTDOWN)
+               peer_tx_shutdown_message_unset(peer);
+
+       if (set)
+               ret = peer_flag_set(peer, flag);
+       else
+               ret = peer_flag_unset(peer, flag);
+
+       return bgp_vty_return(vty, ret);
+}
+
+static int peer_flag_set_vty(struct vty *vty, const char *ip_str, uint32_t flag)
+{
+       return peer_flag_modify_vty(vty, ip_str, flag, 1);
+}
+
+static int peer_flag_unset_vty(struct vty *vty, const char *ip_str,
+                              uint32_t flag)
+{
+       return peer_flag_modify_vty(vty, ip_str, flag, 0);
+}
+
+/* neighbor passive. */
+DEFUN (neighbor_passive,
+       neighbor_passive_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> passive",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Don't send open messages to this neighbor\n")
+{
+       int idx_peer = 1;
+       return peer_flag_set_vty(vty, argv[idx_peer]->arg, PEER_FLAG_PASSIVE);
+}
+
+DEFUN (no_neighbor_passive,
+       no_neighbor_passive_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> passive",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Don't send open messages to this neighbor\n")
+{
+       int idx_peer = 2;
+       return peer_flag_unset_vty(vty, argv[idx_peer]->arg, PEER_FLAG_PASSIVE);
+}
+
+/* neighbor shutdown. */
+DEFUN (neighbor_shutdown_msg,
+       neighbor_shutdown_msg_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown message MSG...",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Administratively shut down this neighbor\n"
+       "Add a shutdown message (draft-ietf-idr-shutdown-06)\n"
+       "Shutdown message\n")
+{
+       int idx_peer = 1;
+
+       if (argc >= 5) {
+               struct peer *peer =
+                       peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+               char *message;
+
+               if (!peer)
+                       return CMD_WARNING_CONFIG_FAILED;
+               message = argv_concat(argv, argc, 4);
+               peer_tx_shutdown_message_set(peer, message);
+               XFREE(MTYPE_TMP, message);
+       }
+
+       return peer_flag_set_vty(vty, argv[idx_peer]->arg, PEER_FLAG_SHUTDOWN);
+}
+
+ALIAS(neighbor_shutdown_msg, neighbor_shutdown_cmd,
+      "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
+      NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+      "Administratively shut down this neighbor\n")
+
+DEFUN (no_neighbor_shutdown_msg,
+       no_neighbor_shutdown_msg_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown message MSG...",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Administratively shut down this neighbor\n"
+       "Remove a shutdown message (draft-ietf-idr-shutdown-06)\n"
+       "Shutdown message\n")
+{
+       int idx_peer = 2;
+
+       return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
+                                  PEER_FLAG_SHUTDOWN);
+}
+
+ALIAS(no_neighbor_shutdown_msg, no_neighbor_shutdown_cmd,
+      "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
+      NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+      "Administratively shut down this neighbor\n")
+
+/* neighbor capability dynamic. */
+DEFUN (neighbor_capability_dynamic,
+       neighbor_capability_dynamic_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> capability dynamic",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Advertise capability to the peer\n"
+       "Advertise dynamic capability to this neighbor\n")
+{
+       int idx_peer = 1;
+       return peer_flag_set_vty(vty, argv[idx_peer]->arg,
+                                PEER_FLAG_DYNAMIC_CAPABILITY);
+}
+
+DEFUN (no_neighbor_capability_dynamic,
+       no_neighbor_capability_dynamic_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> capability dynamic",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Advertise capability to the peer\n"
+       "Advertise dynamic capability to this neighbor\n")
+{
+       int idx_peer = 2;
+       return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
+                                  PEER_FLAG_DYNAMIC_CAPABILITY);
+}
+
+/* neighbor dont-capability-negotiate */
+DEFUN (neighbor_dont_capability_negotiate,
+       neighbor_dont_capability_negotiate_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> dont-capability-negotiate",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Do not perform capability negotiation\n")
+{
+       int idx_peer = 1;
+       return peer_flag_set_vty(vty, argv[idx_peer]->arg,
+                                PEER_FLAG_DONT_CAPABILITY);
+}
+
+DEFUN (no_neighbor_dont_capability_negotiate,
+       no_neighbor_dont_capability_negotiate_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> dont-capability-negotiate",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Do not perform capability negotiation\n")
+{
+       int idx_peer = 2;
+       return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
+                                  PEER_FLAG_DONT_CAPABILITY);
+}
+
+/* neighbor capability extended next hop encoding */
+DEFUN (neighbor_capability_enhe,
+       neighbor_capability_enhe_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> capability extended-nexthop",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Advertise capability to the peer\n"
+       "Advertise extended next-hop capability to the peer\n")
+{
+       int idx_peer = 1;
+       return peer_flag_set_vty(vty, argv[idx_peer]->arg,
+                                PEER_FLAG_CAPABILITY_ENHE);
+}
+
+DEFUN (no_neighbor_capability_enhe,
+       no_neighbor_capability_enhe_cmd,
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> capability extended-nexthop",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Advertise capability to the peer\n"
+       "Advertise extended next-hop capability to the peer\n")
+{
+       int idx_peer = 2;
+       return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
+                                  PEER_FLAG_CAPABILITY_ENHE);
+}
+
+static int peer_af_flag_modify_vty(struct vty *vty, const char *peer_str,
+                                  afi_t afi, safi_t safi, uint32_t flag,
+                                  int set)
+{
+       int ret;
+       struct peer *peer;
+
+       peer = peer_and_group_lookup_vty(vty, peer_str);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       if (set)
+               ret = peer_af_flag_set(peer, afi, safi, flag);
+       else
+               ret = peer_af_flag_unset(peer, afi, safi, flag);
+
+       return bgp_vty_return(vty, ret);
+}
+
+static int peer_af_flag_set_vty(struct vty *vty, const char *peer_str,
+                               afi_t afi, safi_t safi, uint32_t flag)
+{
+       return peer_af_flag_modify_vty(vty, peer_str, afi, safi, flag, 1);
+}
+
+static int peer_af_flag_unset_vty(struct vty *vty, const char *peer_str,
+                                 afi_t afi, safi_t safi, uint32_t flag)
+{
+       return peer_af_flag_modify_vty(vty, peer_str, afi, safi, flag, 0);
 }
 
 /* neighbor capability orf prefix-list. */
@@ -5996,31 +6566,81 @@ static int peer_maximum_prefix_unset_vty(struct vty *vty, const char *ip_str,
        return bgp_vty_return(vty, ret);
 }
 
-/* Maximum number of prefix configuration.  prefix count is different
-   for each peer configuration.  So this configuration can be set for
-   each peer configuration. */
-DEFUN (neighbor_maximum_prefix,
-       neighbor_maximum_prefix_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295)",
-       NEIGHBOR_STR
-       NEIGHBOR_ADDR_STR2
-       "Maximum number of prefix accept from this peer\n"
-       "maximum no. of prefix limit\n")
+/* Maximum number of prefix to be sent to the neighbor. */
+DEFUN(neighbor_maximum_prefix_out,
+      neighbor_maximum_prefix_out_cmd,
+      "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix-out (1-4294967295)",
+      NEIGHBOR_STR
+      NEIGHBOR_ADDR_STR2
+      "Maximum number of prefixes to be sent to this peer\n"
+      "Maximum no. of prefix limit\n")
 {
        int idx_peer = 1;
        int idx_number = 3;
-       return peer_maximum_prefix_set_vty(
-               vty, argv[idx_peer]->arg, bgp_node_afi(vty), bgp_node_safi(vty),
-               argv[idx_number]->arg, NULL, 0, NULL);
-}
+       struct peer *peer;
+       uint32_t max;
+       afi_t afi = bgp_node_afi(vty);
+       safi_t safi = bgp_node_safi(vty);
 
-ALIAS_HIDDEN(neighbor_maximum_prefix, neighbor_maximum_prefix_hidden_cmd,
-            "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295)",
-            NEIGHBOR_STR NEIGHBOR_ADDR_STR2
-            "Maximum number of prefix accept from this peer\n"
-            "maximum no. of prefix limit\n")
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
 
-DEFUN (neighbor_maximum_prefix_threshold,
+       max = strtoul(argv[idx_number]->arg, NULL, 10);
+
+       SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT);
+       peer->pmax_out[afi][safi] = max;
+
+       return CMD_SUCCESS;
+}
+
+DEFUN(no_neighbor_maximum_prefix_out,
+      no_neighbor_maximum_prefix_out_cmd,
+      "no neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix-out",
+      NO_STR
+      NEIGHBOR_STR
+      NEIGHBOR_ADDR_STR2
+      "Maximum number of prefixes to be sent to this peer\n")
+{
+       int idx_peer = 2;
+       struct peer *peer;
+       afi_t afi = bgp_node_afi(vty);
+       safi_t safi = bgp_node_safi(vty);
+
+       peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+       if (!peer)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       peer->pmax_out[afi][safi] = 0;
+
+       return CMD_SUCCESS;
+}
+
+/* Maximum number of prefix configuration.  prefix count is different
+   for each peer configuration.  So this configuration can be set for
+   each peer configuration. */
+DEFUN (neighbor_maximum_prefix,
+       neighbor_maximum_prefix_cmd,
+       "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295)",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Maximum number of prefix accept from this peer\n"
+       "maximum no. of prefix limit\n")
+{
+       int idx_peer = 1;
+       int idx_number = 3;
+       return peer_maximum_prefix_set_vty(
+               vty, argv[idx_peer]->arg, bgp_node_afi(vty), bgp_node_safi(vty),
+               argv[idx_number]->arg, NULL, 0, NULL);
+}
+
+ALIAS_HIDDEN(neighbor_maximum_prefix, neighbor_maximum_prefix_hidden_cmd,
+            "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295)",
+            NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+            "Maximum number of prefix accept from this peer\n"
+            "maximum no. of prefix limit\n")
+
+DEFUN (neighbor_maximum_prefix_threshold,
        neighbor_maximum_prefix_threshold_cmd,
        "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100)",
        NEIGHBOR_STR
@@ -6956,8 +7576,8 @@ DEFPY(af_import_vrf_route_map, af_import_vrf_route_map_cmd,
                as_t as = bgp->as;
 
                /* Auto-create assuming the same AS */
-               ret = bgp_get(&bgp_default, &as, NULL,
-                             BGP_INSTANCE_TYPE_DEFAULT);
+               ret = bgp_get_vty(&bgp_default, &as, NULL,
+                                 BGP_INSTANCE_TYPE_DEFAULT);
 
                if (ret) {
                        vty_out(vty,
@@ -7042,8 +7662,8 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
        bgp_default = bgp_get_default();
        if (!bgp_default) {
                /* Auto-create assuming the same AS */
-               ret = bgp_get(&bgp_default, &as, NULL,
-                             BGP_INSTANCE_TYPE_DEFAULT);
+               ret = bgp_get_vty(&bgp_default, &as, NULL,
+                                 BGP_INSTANCE_TYPE_DEFAULT);
 
                if (ret) {
                        vty_out(vty,
@@ -7058,7 +7678,7 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
                        vrf_bgp = bgp_default;
                else
                        /* Auto-create assuming the same AS */
-                       ret = bgp_get(&vrf_bgp, &as, import_name, bgp_type);
+                       ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type);
 
                if (ret) {
                        vty_out(vty,
@@ -7631,7 +8251,7 @@ DEFUN (show_bgp_vrfs,
                if (!uj && count == 1) {
                        vty_out(vty,
                                "%4s  %-5s  %-16s  %9s  %10s  %-37s\n",
-                               "Type", "Id", "routerId", "#PeersVfg",
+                               "Type", "Id", "routerId", "#PeersCfg",
                                "#PeersEstb", "Name");
                        vty_out(vty, "%11s  %-16s  %-21s  %-6s\n", " ",
                                "L3-VNI", "RouterMAC", "Interface");
@@ -8770,8 +9390,6 @@ const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json)
                return get_afi_safi_vty_str(afi, safi);
 }
 
-/* Show BGP peer's information. */
-enum show_type { show_all, show_peer, show_ipv4_all, show_ipv6_all, show_ipv4_peer, show_ipv6_peer };
 
 static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p,
                                      afi_t afi, safi_t safi,
@@ -8836,6 +9454,390 @@ static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p,
        }
 }
 
+static void bgp_show_neighnor_graceful_restart_rbit(struct vty *vty,
+                                                   struct peer *p,
+                                                   bool use_json,
+                                                   json_object *json)
+{
+       bool rbit_status = 0;
+
+       if (!use_json)
+               vty_out(vty, "\n    R bit          : ");
+
+       if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV)
+           && (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV))
+           && (p->status == Established)) {
+
+               if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_BIT_RCV))
+                       rbit_status = 1;
+               else
+                       rbit_status = 0;
+       }
+
+       if (rbit_status) {
+               if (use_json)
+                       json_object_boolean_true_add(json, "rBit");
+               else
+                       vty_out(vty, "True\n");
+       } else {
+               if (use_json)
+                       json_object_boolean_false_add(json, "rBit");
+               else
+                       vty_out(vty, "False\n");
+       }
+}
+
+static void bgp_show_neighbor_graceful_restart_remote_mode(struct vty *vty,
+                                                          struct peer *peer,
+                                                          bool use_json,
+                                                          json_object *json)
+{
+       const char *mode = "NotApplicable";
+
+       if (!use_json)
+               vty_out(vty, "\n    Remote GR Mode : ");
+
+       if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV)
+           && (peer->status == Established)) {
+
+               if ((peer->nsf_af_count == 0)
+                   && !CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
+
+                       mode = "Disable";
+
+               } else if (peer->nsf_af_count == 0
+                          && CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
+
+                       mode = "Helper";
+
+               } else if (peer->nsf_af_count != 0
+                          && CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
+
+                       mode = "Restart";
+               }
+       }
+
+       if (use_json) {
+               json_object_string_add(json, "remoteGrMode", mode);
+       } else
+               vty_out(vty, mode, "\n");
+}
+
+static void bgp_show_neighbor_graceful_restart_local_mode(struct vty *vty,
+                                                         struct peer *p,
+                                                         bool use_json,
+                                                         json_object *json)
+{
+       const char *mode = "Invalid";
+
+       if (!use_json)
+               vty_out(vty, "    Local GR Mode  : ");
+
+       if (bgp_peer_gr_mode_get(p) == PEER_HELPER)
+               mode = "Helper";
+       else if (bgp_peer_gr_mode_get(p) == PEER_GR)
+               mode = "Restart";
+       else if (bgp_peer_gr_mode_get(p) == PEER_DISABLE)
+               mode = "Disable";
+       else if (bgp_peer_gr_mode_get(p) == PEER_GLOBAL_INHERIT) {
+               if (bgp_global_gr_mode_get(p->bgp) == GLOBAL_HELPER)
+                       mode = "Helper*";
+               else if (bgp_global_gr_mode_get(p->bgp) == GLOBAL_GR)
+                       mode = "Restart*";
+               else if (bgp_global_gr_mode_get(p->bgp) == GLOBAL_DISABLE)
+                       mode = "Disable*";
+               else
+                       mode = "Invalid*";
+       }
+
+       if (use_json) {
+               json_object_string_add(json, "localGrMode", mode);
+       } else {
+               vty_out(vty, mode, "\n");
+       }
+}
+
+static void bgp_show_neighbor_graceful_restart_capability_per_afi_safi(
+       struct vty *vty, struct peer *peer, bool use_json, json_object *json)
+{
+       afi_t afi;
+       safi_t safi;
+       json_object *json_afi_safi = NULL;
+       json_object *json_timer = NULL;
+       json_object *json_endofrib_status = NULL;
+       bool eor_flag = false;
+
+       for (afi = AFI_IP; afi < AFI_MAX; afi++) {
+               for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++) {
+                       if (!peer->afc[afi][safi])
+                               continue;
+
+                       if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV)
+                           || !CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV))
+                               continue;
+
+                       if (use_json) {
+                               json_afi_safi = json_object_new_object();
+                               json_endofrib_status = json_object_new_object();
+                               json_timer = json_object_new_object();
+                       }
+
+                       if (peer->eor_stime[afi][safi]
+                           >= peer->pkt_stime[afi][safi])
+                               eor_flag = true;
+                       else
+                               eor_flag = false;
+
+                       if (!use_json) {
+                               vty_out(vty, "    %s :\n",
+                                       get_afi_safi_str(afi, safi, false));
+
+                               vty_out(vty, "     F bit                 : ");
+                       }
+
+                       if (peer->nsf[afi][safi]
+                           && CHECK_FLAG(peer->af_cap[afi][safi],
+                                         PEER_CAP_RESTART_AF_PRESERVE_RCV)) {
+
+                               if (use_json) {
+                                       json_object_boolean_true_add(
+                                               json_afi_safi, "fBit");
+                               } else
+                                       vty_out(vty, "True\n");
+                       } else {
+                               if (use_json)
+                                       json_object_boolean_false_add(
+                                               json_afi_safi, "fBit");
+                               else
+                                       vty_out(vty, "False\n");
+                       }
+
+                       if (!use_json)
+                               vty_out(vty, "     End-of-RIB Received   : ");
+
+                       if (CHECK_FLAG(peer->af_sflags[afi][safi],
+                                      PEER_STATUS_EOR_RECEIVED)) {
+                               if (use_json)
+                                       json_object_boolean_true_add(
+                                               json_endofrib_status,
+                                               "endOfRibRecv");
+                               else
+                                       vty_out(vty, "Yes\n");
+                       } else {
+                               if (use_json)
+                                       json_object_boolean_false_add(
+                                               json_endofrib_status,
+                                               "endOfRibRecv");
+                               else
+                                       vty_out(vty, "No\n");
+                       }
+
+                       if (!use_json)
+                               vty_out(vty, "     End-of-RIB Send       : ");
+
+                       if (CHECK_FLAG(peer->af_sflags[afi][safi],
+                                      PEER_STATUS_EOR_SEND)) {
+                               if (use_json) {
+                                       json_object_boolean_true_add(
+                                               json_endofrib_status,
+                                               "endOfRibSend");
+
+                                       PRINT_EOR_JSON(eor_flag);
+                               } else {
+                                       vty_out(vty, "Yes\n");
+                                       vty_out(vty,
+                                               "     EoRSentAfterUpdate   : ");
+
+                                       PRINT_EOR(eor_flag);
+                               }
+                       } else {
+                               if (use_json) {
+                                       json_object_boolean_false_add(
+                                               json_endofrib_status,
+                                               "endOfRibSend");
+                                       json_object_boolean_false_add(
+                                               json_endofrib_status,
+                                               "endOfRibSentAfterUpdate");
+                               } else {
+                                       vty_out(vty, "No\n");
+                                       vty_out(vty,
+                                               "     EoRSentAfterUpdate   : ");
+                                       vty_out(vty, "No\n");
+                               }
+                       }
+
+                       if (use_json) {
+                               json_object_int_add(json_timer,
+                                                   "stalePathTimer",
+                                                   peer->bgp->stalepath_time);
+
+                               if (peer->t_gr_stale != NULL) {
+                                       json_object_int_add(
+                                               json_timer,
+                                               "stalePathTimerRemaining",
+                                               thread_timer_remain_second(
+                                                       peer->t_gr_stale));
+                               }
+
+                               /* Display Configured Selection
+                                * Deferral only when when
+                                * Gr mode is enabled.
+                                */
+                               if (CHECK_FLAG(peer->flags,
+                                              PEER_FLAG_GRACEFUL_RESTART)) {
+                                       json_object_int_add(
+                                               json_timer,
+                                               "selectionDeferralTimer",
+                                               peer->bgp->stalepath_time);
+                               }
+
+                               if (peer->bgp->gr_info[afi][safi]
+                                           .t_select_deferral
+                                   != NULL) {
+
+                                       json_object_int_add(
+                                               json_timer,
+                                               "selectionDeferralTimerRemaining",
+                                               thread_timer_remain_second(
+                                                       peer->bgp
+                                                               ->gr_info[afi]
+                                                                        [safi]
+                                                               .t_select_deferral));
+                               }
+                       } else {
+                               vty_out(vty, "     Timers:\n");
+
+                               vty_out(vty, "%*s", 6, "");
+                               vty_out(vty,
+                                       "Configured Stale Path Time(sec)%*s: %u\n",
+                                       8, "", peer->bgp->stalepath_time);
+
+                               if (peer->t_gr_stale != NULL) {
+                                       vty_out(vty, "%*s", 6, "");
+                                       vty_out(vty,
+                                               "Stale Path Remaining(sec)%*s: %ld\n",
+                                               14, "",
+                                               thread_timer_remain_second(
+                                                       peer->t_gr_stale));
+                               }
+                               /* Display Configured Selection
+                                * Deferral only when when
+                                * Gr mode is enabled.
+                                */
+                               if (CHECK_FLAG(peer->flags,
+                                              PEER_FLAG_GRACEFUL_RESTART)) {
+                                       vty_out(vty, "%*s", 6, "");
+                                       vty_out(vty,
+                                               "Configured Selection Deferral Time(sec): %u\n",
+                                               peer->bgp->select_defer_time);
+                               }
+
+                               if (peer->bgp->gr_info[afi][safi]
+                                           .t_select_deferral
+                                   != NULL) {
+
+                                       vty_out(vty, "%*s", 6, "");
+                                       vty_out(vty,
+                                               "Selection Deferral Time Remaining(sec) : %ld\n",
+                                               thread_timer_remain_second(
+                                                       peer->bgp
+                                                               ->gr_info[afi]
+                                                                        [safi]
+                                                               .t_select_deferral));
+                               }
+                       }
+                       if (use_json) {
+                               json_object_object_add(json_afi_safi,
+                                                      "endOfRibStatus",
+                                                      json_endofrib_status);
+                               json_object_object_add(json_afi_safi, "timers",
+                                                      json_timer);
+                               json_object_object_add(
+                                       json, get_afi_safi_str(afi, safi, true),
+                                       json_afi_safi);
+                       }
+               }
+       }
+}
+
+static void  bgp_show_neighbor_graceful_restart_time(struct vty *vty,
+                                                       struct peer *p,
+                                                       bool use_json,
+                                                       json_object *json)
+{
+       if (use_json) {
+               json_object *json_timer = NULL;
+
+               json_timer = json_object_new_object();
+
+               json_object_int_add(json_timer, "configuredRestartTimer",
+                                   p->bgp->restart_time);
+
+               json_object_int_add(json_timer, "receivedRestartTimer",
+                                   p->v_gr_restart);
+
+               if (p->t_gr_restart != NULL)
+                       json_object_int_add(
+                               json_timer, "restartTimerRemaining",
+                               thread_timer_remain_second(p->t_gr_restart));
+
+               json_object_object_add(json, "timers", json_timer);
+       } else {
+
+               vty_out(vty, "    Timers :\n");
+               vty_out(vty, "     Configured Restart Time(sec)  : %u\n",
+                       p->bgp->restart_time);
+
+               vty_out(vty, "     Received Restart Time(sec)    : %u\n",
+                       p->v_gr_restart);
+               if (p->t_gr_restart != NULL)
+                       vty_out(vty,
+                               "     Restart Time Remaining(sec)   : %ld\n",
+                               thread_timer_remain_second(p->t_gr_restart));
+       }
+}
+
+static void bgp_show_peer_gr_status(struct vty *vty, struct peer *p,
+                                       bool use_json,
+                                       json_object *json)
+{
+       char buf[SU_ADDRSTRLEN] = {0};
+       char dn_flag[2] = {0};
+       char neighborAddr[INET6_ADDRSTRLEN] = {0};
+
+       if (!p->conf_if && peer_dynamic_neighbor(p))
+               dn_flag[0] = '*';
+
+       if (p->conf_if) {
+               if (use_json)
+                       json_object_string_add(
+                               json, "neighborAddr",
+                               BGP_PEER_SU_UNSPEC(p)
+                                       ? "none"
+                                       : sockunion2str(&p->su, buf,
+                                                       SU_ADDRSTRLEN));
+               else
+                       vty_out(vty, "BGP neighbor on %s: %s\n", p->conf_if,
+                               BGP_PEER_SU_UNSPEC(p)
+                                       ? "none"
+                                       : sockunion2str(&p->su, buf,
+                                                       SU_ADDRSTRLEN));
+       } else {
+               sprintf(neighborAddr, "%s%s", dn_flag, p->host);
+
+               if (use_json)
+                       json_object_string_add(
+                               json, "neighborAddr",
+                               neighborAddr);
+               else
+                       vty_out(vty, "BGP neighbor is %s\n",
+                               neighborAddr);
+       }
+
+       /* more gr info in new format */
+       BGP_SHOW_PEER_GR_CAPABILITY(vty, p, use_json, json);
+}
+
 static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
                              safi_t safi, bool use_json,
                              json_object *json_neigh)
@@ -9128,6 +10130,11 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
                        json_object_int_add(json_addr, "sentPrefixCounter",
                                                (PAF_SUBGRP(paf))->scount);
 
+               /* Maximum prefix */
+               if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT))
+                       json_object_int_add(json_addr, "prefixOutAllowedMax",
+                                           p->pmax_out[afi][safi]);
+
                /* Maximum prefix */
                if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) {
                        json_object_int_add(json_addr, "prefixAllowedMax",
@@ -9145,7 +10152,9 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
                                        "prefixAllowedRestartIntervalMsecs",
                                        p->pmax_restart[afi][safi] * 60000);
                }
-               json_object_object_add(json_neigh, get_afi_safi_str(afi, safi, true),
+               json_object_object_add(json_neigh,
+                                       get_afi_safi_str(afi,
+                                               safi, true),
                                       json_addr);
 
        } else {
@@ -9414,6 +10423,13 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
                vty_out(vty, "  %" PRIu32 " accepted prefixes\n",
                        p->pcount[afi][safi]);
 
+               /* maximum-prefix-out */
+               if (CHECK_FLAG(p->af_flags[afi][safi],
+                              PEER_FLAG_MAX_PREFIX_OUT))
+                       vty_out(vty,
+                               "  Maximum allowed prefixes sent %" PRIu32 "\n",
+                               p->pmax_out[afi][safi]);
+
                /* Maximum prefix */
                if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) {
                        vty_out(vty,
@@ -9649,23 +10665,6 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                        uptime -= p->uptime;
                        epoch_tbuf = time(NULL) - uptime;
 
-#if CONFDATE > 20200101
-                       CPP_NOTICE(
-                               "bgpTimerUp should be deprecated and can be removed now");
-#endif
-                       /*
-                        * bgpTimerUp was miliseconds that was accurate
-                        * up to 1 day, then the value returned
-                        * became garbage.  So in order to provide
-                        * some level of backwards compatability,
-                        * we still provde the data, but now
-                        * we are returning the correct value
-                        * and also adding a new bgpTimerUpMsec
-                        * which will allow us to deprecate
-                        * this eventually
-                        */
-                       json_object_int_add(json_neigh, "bgpTimerUp",
-                                           uptime * 1000);
                        json_object_int_add(json_neigh, "bgpTimerUpMsec",
                                            uptime * 1000);
                        json_object_string_add(json_neigh, "bgpTimerUpString",
@@ -9725,9 +10724,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                json_neigh,
                                "bgpTimerConfiguredKeepAliveIntervalMsecs",
                                p->keepalive * 1000);
-               } else if ((bgp->default_holdtime != BGP_DEFAULT_HOLDTIME)
-                          || (bgp->default_keepalive
-                              != BGP_DEFAULT_KEEPALIVE)) {
+               } else if ((bgp->default_holdtime != SAVE_BGP_HOLDTIME)
+                          || (bgp->default_keepalive != SAVE_BGP_KEEPALIVE)) {
                        json_object_int_add(json_neigh,
                                            "bgpTimerConfiguredHoldTimeMsecs",
                                            bgp->default_holdtime);
@@ -9789,9 +10787,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                p->holdtime);
                        vty_out(vty, ", keepalive interval is %d seconds\n",
                                p->keepalive);
-               } else if ((bgp->default_holdtime != BGP_DEFAULT_HOLDTIME)
-                          || (bgp->default_keepalive
-                              != BGP_DEFAULT_KEEPALIVE)) {
+               } else if ((bgp->default_holdtime != SAVE_BGP_HOLDTIME)
+                          || (bgp->default_keepalive != SAVE_BGP_KEEPALIVE)) {
                        vty_out(vty, "  Configured hold time is %d",
                                bgp->default_holdtime);
                        vty_out(vty, ", keepalive interval is %d seconds\n",
@@ -10596,14 +11593,12 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                                        vty_out(vty, "none");
                                                vty_out(vty, "\n");
                                        }
-                               }
+                               } /* Gracefull Restart */
                        }
                }
        }
 
        /* graceful restart information */
-       if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV) || p->t_gr_restart
-           || p->t_gr_stale) {
                json_object *json_grace = NULL;
                json_object *json_grace_send = NULL;
                json_object *json_grace_recv = NULL;
@@ -10615,10 +11610,11 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                        json_grace_send = json_object_new_object();
                        json_grace_recv = json_object_new_object();
 
-                       if (p->status == Established) {
+                       if ((p->status == Established) &&
+                                       CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) {
                                FOREACH_AFI_SAFI (afi, safi) {
                                        if (CHECK_FLAG(p->af_sflags[afi][safi],
-                                                      PEER_STATUS_EOR_SEND)) {
+                                               PEER_STATUS_EOR_SEND)) {
                                                json_object_boolean_true_add(
                                                        json_grace_send,
                                                        get_afi_safi_str(afi,
@@ -10629,8 +11625,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                }
                                FOREACH_AFI_SAFI (afi, safi) {
                                        if (CHECK_FLAG(
-                                                   p->af_sflags[afi][safi],
-                                                   PEER_STATUS_EOR_RECEIVED)) {
+                                               p->af_sflags[afi][safi],
+                                               PEER_STATUS_EOR_RECEIVED)) {
                                                json_object_boolean_true_add(
                                                        json_grace_recv,
                                                        get_afi_safi_str(afi,
@@ -10640,11 +11636,13 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                        }
                                }
                        }
+                       json_object_object_add(json_grace,
+                                               "endOfRibSend",
+                                                       json_grace_send);
+                       json_object_object_add(json_grace,
+                                               "endOfRibRecv",
+                                               json_grace_recv);
 
-                       json_object_object_add(json_grace, "endOfRibSend",
-                                              json_grace_send);
-                       json_object_object_add(json_grace, "endOfRibRecv",
-                                              json_grace_recv);
 
                        if (p->t_gr_restart)
                                json_object_int_add(json_grace,
@@ -10660,12 +11658,16 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                        thread_timer_remain_second(
                                                p->t_gr_stale)
                                                * 1000);
-
+                       /* more gr info in new format */
+                       BGP_SHOW_PEER_GR_CAPABILITY(vty, p, use_json,
+                                                       json_grace);
                        json_object_object_add(
                                json_neigh, "gracefulRestartInfo", json_grace);
                } else {
-                       vty_out(vty, "  Graceful restart information:\n");
-                       if (p->status == Established) {
+                       vty_out(vty, "  Graceful restart informations:\n");
+                       if ((p->status == Established) &&
+                               CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) {
+
                                vty_out(vty, "    End-of-RIB send: ");
                                FOREACH_AFI_SAFI (afi, safi) {
                                        if (CHECK_FLAG(p->af_sflags[afi][safi],
@@ -10674,8 +11676,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                                        eor_send_af_count ? ", "
                                                                          : "",
                                                        get_afi_safi_str(afi,
-                                                                        safi,
-                                                                        false));
+                                                                       safi,
+                                                                       false));
                                                eor_send_af_count++;
                                        }
                                }
@@ -10709,8 +11711,11 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                        "    The remaining time of stalepath timer is %ld\n",
                                        thread_timer_remain_second(
                                                p->t_gr_stale));
+
+                       /* more gr info in new format */
+                       BGP_SHOW_PEER_GR_CAPABILITY(vty, p, use_json, NULL);
                }
-       }
+
        if (use_json) {
                json_object *json_stat = NULL;
                json_stat = json_object_new_object();
@@ -11124,35 +12129,112 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
        }
 }
 
-static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
-                            enum show_type type, union sockunion *su,
-                            const char *conf_if, bool use_json,
-                            json_object *json)
+static int bgp_show_neighbor_graceful_restart(struct vty *vty,
+                                       struct bgp *bgp,
+                                       enum show_type type,
+                                       union sockunion *su,
+                                       const char *conf_if, afi_t afi,
+                                       bool use_json, json_object *json)
 {
        struct listnode *node, *nnode;
        struct peer *peer;
        int find = 0;
-       bool nbr_output = false;
-       afi_t afi = AFI_MAX;
-       safi_t safi = SAFI_MAX;
-
-       if (type == show_ipv4_peer || type == show_ipv4_all) {
-               afi = AFI_IP;
-       } else if (type == show_ipv6_peer || type == show_ipv6_all) {
-               afi = AFI_IP6;
-       }
+       safi_t safi = SAFI_UNICAST;
+       json_object *json_neighbor = NULL;
 
        for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+
                if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
                        continue;
 
-               switch (type) {
-               case show_all:
-                       bgp_show_peer(vty, peer, use_json, json);
-                       nbr_output = true;
-                       break;
-               case show_peer:
-                       if (conf_if) {
+               if ((peer->afc[afi][safi]) == 0)
+                       continue;
+
+               if (use_json)
+                       json_neighbor = json_object_new_object();
+
+               if (type == show_all) {
+                       bgp_show_peer_gr_status(vty, peer, use_json,
+                                               json_neighbor);
+
+                       if (use_json)
+                               json_object_object_add(json, peer->host,
+                                                      json_neighbor);
+
+               } else if (type == show_peer) {
+                       if (conf_if) {
+                               if ((peer->conf_if
+                                    && !strcmp(peer->conf_if, conf_if))
+                                   || (peer->hostname
+                                       && !strcmp(peer->hostname, conf_if))) {
+                                       find = 1;
+                                       bgp_show_peer_gr_status(vty, peer,
+                                                               use_json,
+                                                               json_neighbor);
+                               }
+                       } else {
+                               if (sockunion_same(&peer->su, su)) {
+                                       find = 1;
+                                       bgp_show_peer_gr_status(vty, peer,
+                                                               use_json,
+                                                               json_neighbor);
+                               }
+                       }
+                       if (use_json && find)
+                               json_object_object_add(json, peer->host,
+                                                      json_neighbor);
+               }
+
+               if (find)
+                       break;
+       }
+
+       if (type == show_peer && !find) {
+               if (use_json)
+                       json_object_boolean_true_add(json, "bgpNoSuchNeighbor");
+               else
+                       vty_out(vty, "%% No such neighbor\n");
+       }
+       if (use_json) {
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json, JSON_C_TO_STRING_PRETTY));
+       } else {
+               vty_out(vty, "\n");
+       }
+
+       return CMD_SUCCESS;
+}
+
+static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
+                            enum show_type type, union sockunion *su,
+                            const char *conf_if, bool use_json,
+                            json_object *json)
+{
+       struct listnode *node, *nnode;
+       struct peer *peer;
+       int find = 0;
+       bool nbr_output = false;
+       afi_t afi = AFI_MAX;
+       safi_t safi = SAFI_MAX;
+
+       if (type == show_ipv4_peer || type == show_ipv4_all) {
+               afi = AFI_IP;
+       } else if (type == show_ipv6_peer || type == show_ipv6_all) {
+               afi = AFI_IP6;
+       }
+
+       for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+               if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+                       continue;
+
+               switch (type) {
+               case show_all:
+                       bgp_show_peer(vty, peer, use_json, json);
+                       nbr_output = true;
+                       break;
+               case show_peer:
+                       if (conf_if) {
                                if ((peer->conf_if
                                     && !strcmp(peer->conf_if, conf_if))
                                    || (peer->hostname
@@ -11229,6 +12311,41 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
        return CMD_SUCCESS;
 }
 
+static void  bgp_show_neighbor_graceful_restart_vty(struct vty *vty,
+                                enum show_type type, const char *ip_str,
+                                afi_t afi, bool use_json)
+{
+
+       int ret;
+       struct bgp *bgp;
+       union sockunion su;
+       json_object *json = NULL;
+
+       bgp = bgp_get_default();
+
+       if (!bgp)
+               return;
+
+       if (!use_json)
+               bgp_show_global_graceful_restart_mode_vty(vty, bgp, use_json,
+                                                         NULL);
+
+       json = json_object_new_object();
+       if (ip_str) {
+               ret = str2sockunion(ip_str, &su);
+               if (ret < 0)
+                       bgp_show_neighbor_graceful_restart(vty, bgp, type, NULL,
+                                                          ip_str, afi,
+                                                          use_json, json);
+               else
+                       bgp_show_neighbor_graceful_restart(
+                               vty, bgp, type, &su, NULL, afi, use_json, json);
+       } else
+               bgp_show_neighbor_graceful_restart(vty, bgp, type, NULL, NULL,
+                                                  afi, use_json, json);
+       json_object_free(json);
+}
+
 static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
                                                 enum show_type type,
                                                 const char *ip_str,
@@ -11366,6 +12483,51 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
        return CMD_SUCCESS;
 }
 
+
+
+/* "show [ip] bgp neighbors graceful-restart" commands.  */
+DEFUN (show_ip_bgp_neighbors_gracrful_restart,
+       show_ip_bgp_neighbors_graceful_restart_cmd,
+       "show bgp [<ipv4|ipv6>] neighbors [<A.B.C.D|X:X::X:X|WORD>] graceful-restart [json]",
+       SHOW_STR
+       BGP_STR
+       IP_STR
+       IPV6_STR
+       NEIGHBOR_STR
+       "Neighbor to display information about\n"
+       "Neighbor to display information about\n"
+       "Neighbor on BGP configured interface\n"
+       GR_SHOW
+       JSON_STR)
+{
+       char *sh_arg = NULL;
+       enum show_type sh_type;
+       int idx = 0;
+       afi_t afi = AFI_MAX;
+       bool uj = use_json(argc, argv);
+
+       if      (!argv_find_and_parse_afi(argv, argc, &idx, &afi))
+               afi = AFI_MAX;
+
+       idx++;
+
+       if (argv_find(argv, argc, "A.B.C.D", &idx)
+           || argv_find(argv, argc, "X:X::X:X", &idx)
+           || argv_find(argv, argc, "WORD", &idx)) {
+               sh_type = show_peer;
+               sh_arg = argv[idx]->arg;
+       } else
+               sh_type = show_all;
+
+       if (!argv_find(argv, argc, "graceful-restart", &idx))
+               return CMD_SUCCESS;
+
+
+       return bgp_show_neighbor_graceful_restart_afi_all(vty,
+                                               sh_type, sh_arg,
+                                               afi, uj);
+}
+
 /* "show [ip] bgp neighbors" commands.  */
 DEFUN (show_ip_bgp_neighbors,
        show_ip_bgp_neighbors_cmd,
@@ -11504,8 +12666,69 @@ DEFUN (show_ip_bgp_lcommunity_info,
 
        return CMD_SUCCESS;
 }
+/* Graceful Restart */
+
+static void bgp_show_global_graceful_restart_mode_vty(struct vty *vty,
+                                       struct bgp *bgp,
+                                       bool use_json,
+                                       json_object *json)
+{
 
 
+       vty_out(vty, "\n%s", SHOW_GR_HEADER);
+
+       enum global_mode bgp_global_gr_mode = bgp_global_gr_mode_get(bgp);
+
+       switch (bgp_global_gr_mode) {
+
+       case GLOBAL_HELPER:
+               vty_out(vty, "Global BGP GR Mode :  Helper\n");
+               break;
+
+       case GLOBAL_GR:
+               vty_out(vty, "Global BGP GR Mode :  Restart\n");
+               break;
+
+       case GLOBAL_DISABLE:
+               vty_out(vty, "Global BGP GR Mode :  Disable\n");
+               break;
+
+       case GLOBAL_INVALID:
+               vty_out(vty,
+                       "Global BGP GR Mode  Invalid\n");
+               break;
+       }
+       vty_out(vty, "\n");
+}
+
+static int  bgp_show_neighbor_graceful_restart_afi_all(struct vty *vty,
+                                               enum show_type type,
+                                               const char *ip_str,
+                                               afi_t afi,
+                                               bool use_json)
+{
+       if ((afi == AFI_MAX) && (ip_str == NULL)) {
+               afi = AFI_IP;
+
+               while ((afi != AFI_L2VPN) && (afi < AFI_MAX)) {
+
+                       bgp_show_neighbor_graceful_restart_vty(vty,
+                                                       type, ip_str,
+                                                       afi, use_json);
+                       afi++;
+               }
+       } else if (afi != AFI_MAX) {
+               bgp_show_neighbor_graceful_restart_vty(vty,
+                                                       type, ip_str,
+                                                       afi, use_json);
+       } else {
+               return CMD_ERR_INCOMPLETE;
+       }
+
+       return CMD_SUCCESS;
+}
+/* Graceful Restart */
+
 DEFUN (show_ip_bgp_attr_info,
        show_ip_bgp_attr_info_cmd,
        "show [ip] bgp attribute-info",
@@ -12806,146 +14029,1232 @@ DEFUN (no_bgp_redistribute_ipv6,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       return bgp_redistribute_unset(bgp, AFI_IP6, type, 0);
-}
+       return bgp_redistribute_unset(bgp, AFI_IP6, type, 0);
+}
+
+static void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp,
+                                         afi_t afi, safi_t safi)
+{
+       int i;
+
+       /* Unicast redistribution only.  */
+       if (safi != SAFI_UNICAST)
+               return;
+
+       for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
+               /* Redistribute BGP does not make sense.  */
+               if (i != ZEBRA_ROUTE_BGP) {
+                       struct list *red_list;
+                       struct listnode *node;
+                       struct bgp_redist *red;
+
+                       red_list = bgp->redist[afi][i];
+                       if (!red_list)
+                               continue;
+
+                       for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+                               /* "redistribute" configuration.  */
+                               vty_out(vty, "  redistribute %s",
+                                       zebra_route_string(i));
+                               if (red->instance)
+                                       vty_out(vty, " %d", red->instance);
+                               if (red->redist_metric_flag)
+                                       vty_out(vty, " metric %u",
+                                               red->redist_metric);
+                               if (red->rmap.name)
+                                       vty_out(vty, " route-map %s",
+                                               red->rmap.name);
+                               vty_out(vty, "\n");
+                       }
+               }
+       }
+}
+
+/* peer-group helpers for config-write */
+
+static bool peergroup_flag_check(struct peer *peer, uint32_t flag)
+{
+       if (!peer_group_active(peer)) {
+               if (CHECK_FLAG(peer->flags_invert, flag))
+                       return !CHECK_FLAG(peer->flags, flag);
+               else
+                       return !!CHECK_FLAG(peer->flags, flag);
+       }
+
+       return !!CHECK_FLAG(peer->flags_override, flag);
+}
+
+static bool peergroup_af_flag_check(struct peer *peer, afi_t afi, safi_t safi,
+                                   uint32_t flag)
+{
+       if (!peer_group_active(peer)) {
+               if (CHECK_FLAG(peer->af_flags_invert[afi][safi], flag))
+                       return !peer_af_flag_check(peer, afi, safi, flag);
+               else
+                       return !!peer_af_flag_check(peer, afi, safi, flag);
+       }
+
+       return !!CHECK_FLAG(peer->af_flags_override[afi][safi], flag);
+}
+
+static bool peergroup_filter_check(struct peer *peer, afi_t afi, safi_t safi,
+                                  uint8_t type, int direct)
+{
+       struct bgp_filter *filter;
+
+       if (peer_group_active(peer))
+               return !!CHECK_FLAG(peer->filter_override[afi][safi][direct],
+                                   type);
+
+       filter = &peer->filter[afi][safi];
+       switch (type) {
+       case PEER_FT_DISTRIBUTE_LIST:
+               return !!(filter->dlist[direct].name);
+       case PEER_FT_FILTER_LIST:
+               return !!(filter->aslist[direct].name);
+       case PEER_FT_PREFIX_LIST:
+               return !!(filter->plist[direct].name);
+       case PEER_FT_ROUTE_MAP:
+               return !!(filter->map[direct].name);
+       case PEER_FT_UNSUPPRESS_MAP:
+               return !!(filter->usmap.name);
+       default:
+               return false;
+       }
+}
+
+/* Return true if the addpath type is set for peer and different from
+ * peer-group.
+ */
+static int peergroup_af_addpath_check(struct peer *peer, afi_t afi, safi_t safi)
+{
+       enum bgp_addpath_strat type, g_type;
+
+       type = peer->addpath_type[afi][safi];
+
+       if (type != BGP_ADDPATH_NONE) {
+               if (peer_group_active(peer)) {
+                       g_type = peer->group->conf->addpath_type[afi][safi];
+
+                       if (type != g_type)
+                               return 1;
+                       else
+                               return 0;
+               }
+
+               return 1;
+       }
+
+       return 0;
+}
+
+/* This is part of the address-family block (unicast only) */
+static void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp,
+                                           afi_t afi)
+{
+       int indent = 2;
+
+       if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]) {
+               if (listcount(bgp->vpn_policy[afi].import_vrf))
+                       vty_out(vty, "%*simport vrf route-map %s\n", indent, "",
+                               bgp->vpn_policy[afi]
+                               .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]);
+               else
+                       vty_out(vty, "%*sroute-map vpn import %s\n", indent, "",
+                               bgp->vpn_policy[afi]
+                               .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]);
+       }
+       if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
+                      BGP_CONFIG_VRF_TO_VRF_IMPORT)
+           || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
+                         BGP_CONFIG_VRF_TO_VRF_EXPORT))
+               return;
+
+       if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
+               BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
+
+               vty_out(vty, "%*slabel vpn export %s\n", indent, "", "auto");
+
+       } else {
+               if (bgp->vpn_policy[afi].tovpn_label != MPLS_LABEL_NONE) {
+                       vty_out(vty, "%*slabel vpn export %u\n", indent, "",
+                               bgp->vpn_policy[afi].tovpn_label);
+               }
+       }
+       if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
+                      BGP_VPN_POLICY_TOVPN_RD_SET)) {
+               char buf[RD_ADDRSTRLEN];
+               vty_out(vty, "%*srd vpn export %s\n", indent, "",
+                       prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
+                                     sizeof(buf)));
+       }
+       if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
+                      BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
+
+               char buf[PREFIX_STRLEN];
+               if (inet_ntop(bgp->vpn_policy[afi].tovpn_nexthop.family,
+                             &bgp->vpn_policy[afi].tovpn_nexthop.u.prefix, buf,
+                             sizeof(buf))) {
+
+                       vty_out(vty, "%*snexthop vpn export %s\n",
+                               indent, "", buf);
+               }
+       }
+       if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]
+           && bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]
+           && ecommunity_cmp(
+                      bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
+                      bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN])) {
+
+               char *b = ecommunity_ecom2str(
+                       bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN],
+                       ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET);
+               vty_out(vty, "%*srt vpn both %s\n", indent, "", b);
+               XFREE(MTYPE_ECOMMUNITY_STR, b);
+       } else {
+               if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]) {
+                       char *b = ecommunity_ecom2str(
+                               bgp->vpn_policy[afi]
+                                       .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
+                               ECOMMUNITY_FORMAT_ROUTE_MAP,
+                               ECOMMUNITY_ROUTE_TARGET);
+                       vty_out(vty, "%*srt vpn import %s\n", indent, "", b);
+                       XFREE(MTYPE_ECOMMUNITY_STR, b);
+               }
+               if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]) {
+                       char *b = ecommunity_ecom2str(
+                               bgp->vpn_policy[afi]
+                                       .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
+                               ECOMMUNITY_FORMAT_ROUTE_MAP,
+                               ECOMMUNITY_ROUTE_TARGET);
+                       vty_out(vty, "%*srt vpn export %s\n", indent, "", b);
+                       XFREE(MTYPE_ECOMMUNITY_STR, b);
+               }
+       }
+
+       if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN])
+               vty_out(vty, "%*sroute-map vpn export %s\n", indent, "",
+                       bgp->vpn_policy[afi]
+                               .rmap_name[BGP_VPN_POLICY_DIR_TOVPN]);
+
+       if (bgp->vpn_policy[afi].import_redirect_rtlist) {
+               char *b = ecommunity_ecom2str(
+                                       bgp->vpn_policy[afi]
+                                       .import_redirect_rtlist,
+                                       ECOMMUNITY_FORMAT_ROUTE_MAP,
+                                       ECOMMUNITY_ROUTE_TARGET);
+
+               vty_out(vty, "%*srt redirect import %s\n", indent, "", b);
+               XFREE(MTYPE_ECOMMUNITY_STR, b);
+       }
+}
+
+static void bgp_config_write_filter(struct vty *vty, struct peer *peer,
+                                   afi_t afi, safi_t safi)
+{
+       struct bgp_filter *filter;
+       char *addr;
+
+       addr = peer->host;
+       filter = &peer->filter[afi][safi];
+
+       /* distribute-list. */
+       if (peergroup_filter_check(peer, afi, safi, PEER_FT_DISTRIBUTE_LIST,
+                                  FILTER_IN))
+               vty_out(vty, "  neighbor %s distribute-list %s in\n", addr,
+                       filter->dlist[FILTER_IN].name);
+
+       if (peergroup_filter_check(peer, afi, safi, PEER_FT_DISTRIBUTE_LIST,
+                                  FILTER_OUT))
+               vty_out(vty, "  neighbor %s distribute-list %s out\n", addr,
+                       filter->dlist[FILTER_OUT].name);
+
+       /* prefix-list. */
+       if (peergroup_filter_check(peer, afi, safi, PEER_FT_PREFIX_LIST,
+                                  FILTER_IN))
+               vty_out(vty, "  neighbor %s prefix-list %s in\n", addr,
+                       filter->plist[FILTER_IN].name);
+
+       if (peergroup_filter_check(peer, afi, safi, PEER_FT_PREFIX_LIST,
+                                  FILTER_OUT))
+               vty_out(vty, "  neighbor %s prefix-list %s out\n", addr,
+                       filter->plist[FILTER_OUT].name);
+
+       /* route-map. */
+       if (peergroup_filter_check(peer, afi, safi, PEER_FT_ROUTE_MAP, RMAP_IN))
+               vty_out(vty, "  neighbor %s route-map %s in\n", addr,
+                       filter->map[RMAP_IN].name);
+
+       if (peergroup_filter_check(peer, afi, safi, PEER_FT_ROUTE_MAP,
+                                  RMAP_OUT))
+               vty_out(vty, "  neighbor %s route-map %s out\n", addr,
+                       filter->map[RMAP_OUT].name);
+
+       /* unsuppress-map */
+       if (peergroup_filter_check(peer, afi, safi, PEER_FT_UNSUPPRESS_MAP, 0))
+               vty_out(vty, "  neighbor %s unsuppress-map %s\n", addr,
+                       filter->usmap.name);
+
+       /* filter-list. */
+       if (peergroup_filter_check(peer, afi, safi, PEER_FT_FILTER_LIST,
+                                  FILTER_IN))
+               vty_out(vty, "  neighbor %s filter-list %s in\n", addr,
+                       filter->aslist[FILTER_IN].name);
+
+       if (peergroup_filter_check(peer, afi, safi, PEER_FT_FILTER_LIST,
+                                  FILTER_OUT))
+               vty_out(vty, "  neighbor %s filter-list %s out\n", addr,
+                       filter->aslist[FILTER_OUT].name);
+}
+
+/* BGP peer configuration display function. */
+static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
+                                        struct peer *peer)
+{
+       struct peer *g_peer = NULL;
+       char buf[SU_ADDRSTRLEN];
+       char *addr;
+       int if_pg_printed = false;
+       int if_ras_printed = false;
+
+       /* Skip dynamic neighbors. */
+       if (peer_dynamic_neighbor(peer))
+               return;
+
+       if (peer->conf_if)
+               addr = peer->conf_if;
+       else
+               addr = peer->host;
+
+       /************************************
+        ****** Global to the neighbor ******
+        ************************************/
+       if (peer->conf_if) {
+               if (CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
+                       vty_out(vty, " neighbor %s interface v6only", addr);
+               else
+                       vty_out(vty, " neighbor %s interface", addr);
+
+               if (peer_group_active(peer)) {
+                       vty_out(vty, " peer-group %s", peer->group->name);
+                       if_pg_printed = true;
+               } else if (peer->as_type == AS_SPECIFIED) {
+                       vty_out(vty, " remote-as %u", peer->as);
+                       if_ras_printed = true;
+               } else if (peer->as_type == AS_INTERNAL) {
+                       vty_out(vty, " remote-as internal");
+                       if_ras_printed = true;
+               } else if (peer->as_type == AS_EXTERNAL) {
+                       vty_out(vty, " remote-as external");
+                       if_ras_printed = true;
+               }
+
+               vty_out(vty, "\n");
+       }
+
+       /* remote-as and peer-group */
+       /* peer is a member of a peer-group */
+       if (peer_group_active(peer)) {
+               g_peer = peer->group->conf;
+
+               if (g_peer->as_type == AS_UNSPECIFIED && !if_ras_printed) {
+                       if (peer->as_type == AS_SPECIFIED) {
+                               vty_out(vty, " neighbor %s remote-as %u\n",
+                                       addr, peer->as);
+                       } else if (peer->as_type == AS_INTERNAL) {
+                               vty_out(vty,
+                                       " neighbor %s remote-as internal\n",
+                                       addr);
+                       } else if (peer->as_type == AS_EXTERNAL) {
+                               vty_out(vty,
+                                       " neighbor %s remote-as external\n",
+                                       addr);
+                       }
+               }
+
+               /* For swpX peers we displayed the peer-group
+                * via 'neighbor swpX interface peer-group PGNAME' */
+               if (!if_pg_printed)
+                       vty_out(vty, " neighbor %s peer-group %s\n", addr,
+                               peer->group->name);
+       }
+
+       /* peer is NOT a member of a peer-group */
+       else {
+               /* peer is a peer-group, declare the peer-group */
+               if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
+                       vty_out(vty, " neighbor %s peer-group\n", addr);
+               }
+
+               if (!if_ras_printed) {
+                       if (peer->as_type == AS_SPECIFIED) {
+                               vty_out(vty, " neighbor %s remote-as %u\n",
+                                       addr, peer->as);
+                       } else if (peer->as_type == AS_INTERNAL) {
+                               vty_out(vty,
+                                       " neighbor %s remote-as internal\n",
+                                       addr);
+                       } else if (peer->as_type == AS_EXTERNAL) {
+                               vty_out(vty,
+                                       " neighbor %s remote-as external\n",
+                                       addr);
+                       }
+               }
+       }
+
+       /* local-as */
+       if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS)) {
+               vty_out(vty, " neighbor %s local-as %u", addr,
+                       peer->change_local_as);
+               if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND))
+                       vty_out(vty, " no-prepend");
+               if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS))
+                       vty_out(vty, " replace-as");
+               vty_out(vty, "\n");
+       }
+
+       /* description */
+       if (peer->desc) {
+               vty_out(vty, " neighbor %s description %s\n", addr, peer->desc);
+       }
+
+       /* shutdown */
+       if (peergroup_flag_check(peer, PEER_FLAG_SHUTDOWN)) {
+               if (peer->tx_shutdown_message)
+                       vty_out(vty, " neighbor %s shutdown message %s\n", addr,
+                               peer->tx_shutdown_message);
+               else
+                       vty_out(vty, " neighbor %s shutdown\n", addr);
+       }
+
+       /* bfd */
+       if (peer->bfd_info) {
+               if (!peer_group_active(peer) || !g_peer->bfd_info) {
+                       bgp_bfd_peer_config_write(vty, peer, addr);
+               }
+       }
+
+       /* password */
+       if (peergroup_flag_check(peer, PEER_FLAG_PASSWORD))
+               vty_out(vty, " neighbor %s password %s\n", addr,
+                       peer->password);
+
+       /* neighbor solo */
+       if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL)) {
+               if (!peer_group_active(peer)) {
+                       vty_out(vty, " neighbor %s solo\n", addr);
+               }
+       }
+
+       /* BGP port */
+       if (peer->port != BGP_PORT_DEFAULT) {
+               vty_out(vty, " neighbor %s port %d\n", addr, peer->port);
+       }
+
+       /* Local interface name */
+       if (peer->ifname) {
+               vty_out(vty, " neighbor %s interface %s\n", addr, peer->ifname);
+       }
+
+       /* passive */
+       if (peergroup_flag_check(peer, PEER_FLAG_PASSIVE))
+               vty_out(vty, " neighbor %s passive\n", addr);
+
+       /* ebgp-multihop */
+       if (peer->sort != BGP_PEER_IBGP && peer->ttl != BGP_DEFAULT_TTL
+           && !(peer->gtsm_hops != 0 && peer->ttl == MAXTTL)) {
+               if (!peer_group_active(peer) || g_peer->ttl != peer->ttl) {
+                       vty_out(vty, " neighbor %s ebgp-multihop %d\n", addr,
+                               peer->ttl);
+               }
+       }
+
+       /* ttl-security hops */
+       if (peer->gtsm_hops != 0) {
+               if (!peer_group_active(peer)
+                   || g_peer->gtsm_hops != peer->gtsm_hops) {
+                       vty_out(vty, " neighbor %s ttl-security hops %d\n",
+                               addr, peer->gtsm_hops);
+               }
+       }
+
+       /* disable-connected-check */
+       if (peergroup_flag_check(peer, PEER_FLAG_DISABLE_CONNECTED_CHECK))
+               vty_out(vty, " neighbor %s disable-connected-check\n", addr);
+
+       /* enforce-first-as */
+       if (peergroup_flag_check(peer, PEER_FLAG_ENFORCE_FIRST_AS))
+               vty_out(vty, " neighbor %s enforce-first-as\n", addr);
+
+       /* update-source */
+       if (peergroup_flag_check(peer, PEER_FLAG_UPDATE_SOURCE)) {
+               if (peer->update_source)
+                       vty_out(vty, " neighbor %s update-source %s\n", addr,
+                               sockunion2str(peer->update_source, buf,
+                                             SU_ADDRSTRLEN));
+               else if (peer->update_if)
+                       vty_out(vty, " neighbor %s update-source %s\n", addr,
+                               peer->update_if);
+       }
+
+       /* advertisement-interval */
+       if (peergroup_flag_check(peer, PEER_FLAG_ROUTEADV))
+               vty_out(vty, " neighbor %s advertisement-interval %u\n", addr,
+                       peer->routeadv);
+
+       /* timers */
+       if (peergroup_flag_check(peer, PEER_FLAG_TIMER))
+               vty_out(vty, " neighbor %s timers %u %u\n", addr,
+                       peer->keepalive, peer->holdtime);
+
+       /* timers connect */
+       if (peergroup_flag_check(peer, PEER_FLAG_TIMER_CONNECT))
+               vty_out(vty, " neighbor %s timers connect %u\n", addr,
+                       peer->connect);
+       /* need special-case handling for changed default values due to
+        * config profile / version (because there is no "timers bgp connect"
+        * command, we need to save this per-peer :/)
+        */
+       else if (!peer_group_active(peer) && !peer->connect &&
+                peer->bgp->default_connect_retry != SAVE_BGP_CONNECT_RETRY)
+               vty_out(vty, " neighbor %s timers connect %u\n", addr,
+                       peer->bgp->default_connect_retry);
+
+       /* capability dynamic */
+       if (peergroup_flag_check(peer, PEER_FLAG_DYNAMIC_CAPABILITY))
+               vty_out(vty, " neighbor %s capability dynamic\n", addr);
+
+       /* capability extended-nexthop */
+       if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_ENHE)) {
+               if (!peer->conf_if) {
+                       if (CHECK_FLAG(peer->flags_invert,
+                                      PEER_FLAG_CAPABILITY_ENHE))
+                               vty_out(vty,
+                                       " no neighbor %s capability extended-nexthop\n",
+                                       addr);
+                       else
+                               vty_out(vty,
+                                       " neighbor %s capability extended-nexthop\n",
+                                       addr);
+               }
+       }
+
+       /* dont-capability-negotiation */
+       if (peergroup_flag_check(peer, PEER_FLAG_DONT_CAPABILITY))
+               vty_out(vty, " neighbor %s dont-capability-negotiate\n", addr);
+
+       /* override-capability */
+       if (peergroup_flag_check(peer, PEER_FLAG_OVERRIDE_CAPABILITY))
+               vty_out(vty, " neighbor %s override-capability\n", addr);
+
+       /* strict-capability-match */
+       if (peergroup_flag_check(peer, PEER_FLAG_STRICT_CAP_MATCH))
+               vty_out(vty, " neighbor %s strict-capability-match\n", addr);
+
+       /* Sender side AS path loop detection. */
+       if (peer->as_path_loop_detection)
+               vty_out(vty, " neighbor %s sender-as-path-loop-detection\n",
+                       addr);
+
+       if (!CHECK_FLAG(peer->peer_gr_new_status_flag,
+                       PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT)) {
+
+               if (CHECK_FLAG(peer->peer_gr_new_status_flag,
+                              PEER_GRACEFUL_RESTART_NEW_STATE_HELPER)) {
+                       vty_out(vty,
+                               " neighbor %s graceful-restart-helper\n", addr);
+               } else if (CHECK_FLAG(
+                                  peer->peer_gr_new_status_flag,
+                                  PEER_GRACEFUL_RESTART_NEW_STATE_RESTART)) {
+                       vty_out(vty,
+                               " neighbor %s graceful-restart\n", addr);
+               } else if (
+                       (!(CHECK_FLAG(peer->peer_gr_new_status_flag,
+                                     PEER_GRACEFUL_RESTART_NEW_STATE_HELPER))
+                        && !(CHECK_FLAG(
+                                peer->peer_gr_new_status_flag,
+                                PEER_GRACEFUL_RESTART_NEW_STATE_RESTART)))) {
+                       vty_out(vty, " neighbor %s graceful-restart-disable\n",
+                               addr);
+               }
+       }
+}
+
+/* BGP peer configuration display function. */
+static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
+                                    struct peer *peer, afi_t afi, safi_t safi)
+{
+       struct peer *g_peer = NULL;
+       char *addr;
+       bool flag_scomm, flag_secomm, flag_slcomm;
+
+       /* Skip dynamic neighbors. */
+       if (peer_dynamic_neighbor(peer))
+               return;
+
+       if (peer->conf_if)
+               addr = peer->conf_if;
+       else
+               addr = peer->host;
+
+       /************************************
+        ****** Per AF to the neighbor ******
+        ************************************/
+       if (peer_group_active(peer)) {
+               g_peer = peer->group->conf;
+
+               /* If the peer-group is active but peer is not, print a 'no
+                * activate' */
+               if (g_peer->afc[afi][safi] && !peer->afc[afi][safi]) {
+                       vty_out(vty, "  no neighbor %s activate\n", addr);
+               }
+
+               /* If the peer-group is not active but peer is, print an
+                  'activate' */
+               else if (!g_peer->afc[afi][safi] && peer->afc[afi][safi]) {
+                       vty_out(vty, "  neighbor %s activate\n", addr);
+               }
+       } else {
+               if (peer->afc[afi][safi]) {
+                       if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
+                               if (bgp_flag_check(bgp,
+                                                  BGP_FLAG_NO_DEFAULT_IPV4)) {
+                                       vty_out(vty, "  neighbor %s activate\n",
+                                               addr);
+                               }
+                       } else
+                               vty_out(vty, "  neighbor %s activate\n", addr);
+               } else {
+                       if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
+                               if (!bgp_flag_check(bgp,
+                                                   BGP_FLAG_NO_DEFAULT_IPV4)) {
+                                       vty_out(vty,
+                                               "  no neighbor %s activate\n",
+                                               addr);
+                               }
+                       }
+               }
+       }
+
+       /* addpath TX knobs */
+       if (peergroup_af_addpath_check(peer, afi, safi)) {
+               switch (peer->addpath_type[afi][safi]) {
+               case BGP_ADDPATH_ALL:
+                       vty_out(vty, "  neighbor %s addpath-tx-all-paths\n",
+                               addr);
+                       break;
+               case BGP_ADDPATH_BEST_PER_AS:
+                       vty_out(vty,
+                               "  neighbor %s addpath-tx-bestpath-per-AS\n",
+                               addr);
+                       break;
+               case BGP_ADDPATH_MAX:
+               case BGP_ADDPATH_NONE:
+                       break;
+               }
+       }
+
+       /* ORF capability.  */
+       if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_ORF_PREFIX_SM)
+           || peergroup_af_flag_check(peer, afi, safi,
+                                      PEER_FLAG_ORF_PREFIX_RM)) {
+               vty_out(vty, "  neighbor %s capability orf prefix-list", addr);
+
+               if (peergroup_af_flag_check(peer, afi, safi,
+                                           PEER_FLAG_ORF_PREFIX_SM)
+                   && peergroup_af_flag_check(peer, afi, safi,
+                                              PEER_FLAG_ORF_PREFIX_RM))
+                       vty_out(vty, " both");
+               else if (peergroup_af_flag_check(peer, afi, safi,
+                                                PEER_FLAG_ORF_PREFIX_SM))
+                       vty_out(vty, " send");
+               else
+                       vty_out(vty, " receive");
+               vty_out(vty, "\n");
+       }
+
+       /* BGP flag dampening. */
+       if (CHECK_FLAG(bgp->af_flags[afi][safi],
+                      BGP_CONFIG_DAMPENING))
+               bgp_config_write_damp(vty, afi, safi);
+
+       /* Route reflector client. */
+       if (peergroup_af_flag_check(peer, afi, safi,
+                                   PEER_FLAG_REFLECTOR_CLIENT)) {
+               vty_out(vty, "  neighbor %s route-reflector-client\n", addr);
+       }
+
+       /* next-hop-self force */
+       if (peergroup_af_flag_check(peer, afi, safi,
+                                   PEER_FLAG_FORCE_NEXTHOP_SELF)) {
+               vty_out(vty, "  neighbor %s next-hop-self force\n", addr);
+       }
+
+       /* next-hop-self */
+       if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)) {
+               vty_out(vty, "  neighbor %s next-hop-self\n", addr);
+       }
+
+       /* remove-private-AS */
+       if (peergroup_af_flag_check(peer, afi, safi,
+                                   PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)) {
+               vty_out(vty, "  neighbor %s remove-private-AS all replace-AS\n",
+                       addr);
+       }
+
+       else if (peergroup_af_flag_check(peer, afi, safi,
+                                        PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)) {
+               vty_out(vty, "  neighbor %s remove-private-AS replace-AS\n",
+                       addr);
+       }
+
+       else if (peergroup_af_flag_check(peer, afi, safi,
+                                        PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
+               vty_out(vty, "  neighbor %s remove-private-AS all\n", addr);
+       }
+
+       else if (peergroup_af_flag_check(peer, afi, safi,
+                                        PEER_FLAG_REMOVE_PRIVATE_AS)) {
+               vty_out(vty, "  neighbor %s remove-private-AS\n", addr);
+       }
+
+       /* as-override */
+       if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
+               vty_out(vty, "  neighbor %s as-override\n", addr);
+       }
+
+       /* send-community print. */
+       flag_scomm = peergroup_af_flag_check(peer, afi, safi,
+                                            PEER_FLAG_SEND_COMMUNITY);
+       flag_secomm = peergroup_af_flag_check(peer, afi, safi,
+                                             PEER_FLAG_SEND_EXT_COMMUNITY);
+       flag_slcomm = peergroup_af_flag_check(peer, afi, safi,
+                                             PEER_FLAG_SEND_LARGE_COMMUNITY);
+
+       if (flag_scomm && flag_secomm && flag_slcomm) {
+               vty_out(vty, "  no neighbor %s send-community all\n", addr);
+       } else {
+               if (flag_scomm)
+                       vty_out(vty, "  no neighbor %s send-community\n", addr);
+               if (flag_secomm)
+                       vty_out(vty,
+                               "  no neighbor %s send-community extended\n",
+                               addr);
+
+               if (flag_slcomm)
+                       vty_out(vty, "  no neighbor %s send-community large\n",
+                               addr);
+       }
+
+       /* Default information */
+       if (peergroup_af_flag_check(peer, afi, safi,
+                                   PEER_FLAG_DEFAULT_ORIGINATE)) {
+               vty_out(vty, "  neighbor %s default-originate", addr);
+
+               if (peer->default_rmap[afi][safi].name)
+                       vty_out(vty, " route-map %s",
+                               peer->default_rmap[afi][safi].name);
+
+               vty_out(vty, "\n");
+       }
+
+       /* Soft reconfiguration inbound. */
+       if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_SOFT_RECONFIG)) {
+               vty_out(vty, "  neighbor %s soft-reconfiguration inbound\n",
+                       addr);
+       }
+
+       /* maximum-prefix. */
+       if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_MAX_PREFIX)) {
+               vty_out(vty, "  neighbor %s maximum-prefix %" PRIu32, addr,
+                       peer->pmax[afi][safi]);
+
+               if (peer->pmax_threshold[afi][safi]
+                   != MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
+                       vty_out(vty, " %u", peer->pmax_threshold[afi][safi]);
+               if (peer_af_flag_check(peer, afi, safi,
+                                      PEER_FLAG_MAX_PREFIX_WARNING))
+                       vty_out(vty, " warning-only");
+               if (peer->pmax_restart[afi][safi])
+                       vty_out(vty, " restart %u",
+                               peer->pmax_restart[afi][safi]);
+
+               vty_out(vty, "\n");
+       }
+
+       /* maximum-prefix-out */
+       if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_MAX_PREFIX_OUT))
+               vty_out(vty, "  neighbor %s maximum-prefix-out %" PRIu32 "\n",
+                       addr, peer->pmax_out[afi][safi]);
+
+       /* Route server client. */
+       if (peergroup_af_flag_check(peer, afi, safi,
+                                   PEER_FLAG_RSERVER_CLIENT)) {
+               vty_out(vty, "  neighbor %s route-server-client\n", addr);
+       }
+
+       /* Nexthop-local unchanged. */
+       if (peergroup_af_flag_check(peer, afi, safi,
+                                   PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)) {
+               vty_out(vty, "  neighbor %s nexthop-local unchanged\n", addr);
+       }
+
+       /* allowas-in <1-10> */
+       if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_ALLOWAS_IN)) {
+               if (peer_af_flag_check(peer, afi, safi,
+                                      PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
+                       vty_out(vty, "  neighbor %s allowas-in origin\n", addr);
+               } else if (peer->allowas_in[afi][safi] == 3) {
+                       vty_out(vty, "  neighbor %s allowas-in\n", addr);
+               } else {
+                       vty_out(vty, "  neighbor %s allowas-in %d\n", addr,
+                               peer->allowas_in[afi][safi]);
+               }
+       }
+
+       /* weight */
+       if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_WEIGHT))
+               vty_out(vty, "  neighbor %s weight %lu\n", addr,
+                       peer->weight[afi][safi]);
+
+       /* Filter. */
+       bgp_config_write_filter(vty, peer, afi, safi);
+
+       /* atribute-unchanged. */
+       if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED)
+           || (safi != SAFI_EVPN
+               && peer_af_flag_check(peer, afi, safi,
+                                     PEER_FLAG_NEXTHOP_UNCHANGED))
+           || peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) {
+
+               if (!peer_group_active(peer)
+                   || peergroup_af_flag_check(peer, afi, safi,
+                                              PEER_FLAG_AS_PATH_UNCHANGED)
+                   || peergroup_af_flag_check(peer, afi, safi,
+                                              PEER_FLAG_NEXTHOP_UNCHANGED)
+                   || peergroup_af_flag_check(peer, afi, safi,
+                                              PEER_FLAG_MED_UNCHANGED)) {
+
+                       vty_out(vty,
+                               "  neighbor %s attribute-unchanged%s%s%s\n",
+                               addr,
+                               peer_af_flag_check(peer, afi, safi,
+                                                  PEER_FLAG_AS_PATH_UNCHANGED)
+                                       ? " as-path"
+                                       : "",
+                               peer_af_flag_check(peer, afi, safi,
+                                                  PEER_FLAG_NEXTHOP_UNCHANGED)
+                                       ? " next-hop"
+                                       : "",
+                               peer_af_flag_check(peer, afi, safi,
+                                                  PEER_FLAG_MED_UNCHANGED)
+                                       ? " med"
+                                       : "");
+               }
+       }
+}
+
+/* Address family based peer configuration display.  */
+static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
+                                   safi_t safi)
+{
+       struct peer *peer;
+       struct peer_group *group;
+       struct listnode *node, *nnode;
+
+
+       vty_frame(vty, " !\n address-family ");
+       if (afi == AFI_IP) {
+               if (safi == SAFI_UNICAST)
+                       vty_frame(vty, "ipv4 unicast");
+               else if (safi == SAFI_LABELED_UNICAST)
+                       vty_frame(vty, "ipv4 labeled-unicast");
+               else if (safi == SAFI_MULTICAST)
+                       vty_frame(vty, "ipv4 multicast");
+               else if (safi == SAFI_MPLS_VPN)
+                       vty_frame(vty, "ipv4 vpn");
+               else if (safi == SAFI_ENCAP)
+                       vty_frame(vty, "ipv4 encap");
+               else if (safi == SAFI_FLOWSPEC)
+                       vty_frame(vty, "ipv4 flowspec");
+       } else if (afi == AFI_IP6) {
+               if (safi == SAFI_UNICAST)
+                       vty_frame(vty, "ipv6 unicast");
+               else if (safi == SAFI_LABELED_UNICAST)
+                       vty_frame(vty, "ipv6 labeled-unicast");
+               else if (safi == SAFI_MULTICAST)
+                       vty_frame(vty, "ipv6 multicast");
+               else if (safi == SAFI_MPLS_VPN)
+                       vty_frame(vty, "ipv6 vpn");
+               else if (safi == SAFI_ENCAP)
+                       vty_frame(vty, "ipv6 encap");
+               else if (safi == SAFI_FLOWSPEC)
+                       vty_frame(vty, "ipv6 flowspec");
+       } else if (afi == AFI_L2VPN) {
+               if (safi == SAFI_EVPN)
+                       vty_frame(vty, "l2vpn evpn");
+       }
+       vty_frame(vty, "\n");
+
+       bgp_config_write_distance(vty, bgp, afi, safi);
+
+       bgp_config_write_network(vty, bgp, afi, safi);
+
+       bgp_config_write_redistribute(vty, bgp, afi, safi);
+
+       for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
+               bgp_config_write_peer_af(vty, bgp, group->conf, afi, safi);
+
+       for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+               /* Skip dynamic neighbors. */
+               if (peer_dynamic_neighbor(peer))
+                       continue;
+
+               /* Do not display doppelganger peers */
+               if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+                       bgp_config_write_peer_af(vty, bgp, peer, afi, safi);
+       }
+
+       bgp_config_write_maxpaths(vty, bgp, afi, safi);
+       bgp_config_write_table_map(vty, bgp, afi, safi);
 
-void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp, afi_t afi,
-                                  safi_t safi)
-{
-       int i;
+       if (safi == SAFI_EVPN)
+               bgp_config_write_evpn_info(vty, bgp, afi, safi);
 
-       /* Unicast redistribution only.  */
-       if (safi != SAFI_UNICAST)
-               return;
+       if (safi == SAFI_FLOWSPEC)
+               bgp_fs_config_write_pbr(vty, bgp, afi, safi);
 
-       for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
-               /* Redistribute BGP does not make sense.  */
-               if (i != ZEBRA_ROUTE_BGP) {
-                       struct list *red_list;
-                       struct listnode *node;
-                       struct bgp_redist *red;
+       if (safi == SAFI_UNICAST) {
+               bgp_vpn_policy_config_write_afi(vty, bgp, afi);
+               if (CHECK_FLAG(bgp->af_flags[afi][safi],
+                              BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)) {
 
-                       red_list = bgp->redist[afi][i];
-                       if (!red_list)
-                               continue;
+                       vty_out(vty, "  export vpn\n");
+               }
+               if (CHECK_FLAG(bgp->af_flags[afi][safi],
+                              BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)) {
 
-                       for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
-                               /* "redistribute" configuration.  */
-                               vty_out(vty, "  redistribute %s",
-                                       zebra_route_string(i));
-                               if (red->instance)
-                                       vty_out(vty, " %d", red->instance);
-                               if (red->redist_metric_flag)
-                                       vty_out(vty, " metric %u",
-                                               red->redist_metric);
-                               if (red->rmap.name)
-                                       vty_out(vty, " route-map %s",
-                                               red->rmap.name);
-                               vty_out(vty, "\n");
-                       }
+                       vty_out(vty, "  import vpn\n");
+               }
+               if (CHECK_FLAG(bgp->af_flags[afi][safi],
+                              BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
+                       char *name;
+
+                       for (ALL_LIST_ELEMENTS_RO(
+                                    bgp->vpn_policy[afi].import_vrf, node,
+                                    name))
+                               vty_out(vty, "  import vrf %s\n", name);
                }
        }
+
+       vty_endframe(vty, " exit-address-family\n");
 }
 
-/* This is part of the address-family block (unicast only) */
-void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp,
-                                           afi_t afi)
+int bgp_config_write(struct vty *vty)
 {
-       int indent = 2;
+       struct bgp *bgp;
+       struct peer_group *group;
+       struct peer *peer;
+       struct listnode *node, *nnode;
+       struct listnode *mnode, *mnnode;
 
-       if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]) {
-               if (listcount(bgp->vpn_policy[afi].import_vrf))
-                       vty_out(vty, "%*simport vrf route-map %s\n", indent, "",
-                               bgp->vpn_policy[afi]
-                               .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]);
-               else
-                       vty_out(vty, "%*sroute-map vpn import %s\n", indent, "",
-                               bgp->vpn_policy[afi]
-                               .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]);
-       }
-       if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
-                      BGP_CONFIG_VRF_TO_VRF_IMPORT)
-           || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
-                         BGP_CONFIG_VRF_TO_VRF_EXPORT))
-               return;
+       if (bm->rmap_update_timer != RMAP_DEFAULT_UPDATE_TIMER)
+               vty_out(vty, "bgp route-map delay-timer %u\n",
+                       bm->rmap_update_timer);
 
-       if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
-               BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
+       /* BGP configuration. */
+       for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
 
-               vty_out(vty, "%*slabel vpn export %s\n", indent, "", "auto");
+               /* skip all auto created vrf as they dont have user config */
+               if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
+                       continue;
 
-       } else {
-               if (bgp->vpn_policy[afi].tovpn_label != MPLS_LABEL_NONE) {
-                       vty_out(vty, "%*slabel vpn export %u\n", indent, "",
-                               bgp->vpn_policy[afi].tovpn_label);
+               /* Router bgp ASN */
+               vty_out(vty, "router bgp %u", bgp->as);
+
+               if (bgp->name)
+                       vty_out(vty, " %s %s",
+                               (bgp->inst_type  == BGP_INSTANCE_TYPE_VIEW)
+                               ? "view" : "vrf", bgp->name);
+               vty_out(vty, "\n");
+
+               /* BGP fast-external-failover. */
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
+                       vty_out(vty, " no bgp fast-external-failover\n");
+
+               /* BGP router ID. */
+               if (bgp->router_id_static.s_addr != 0)
+                       vty_out(vty, " bgp router-id %s\n",
+                               inet_ntoa(bgp->router_id_static));
+
+               /* BGP log-neighbor-changes. */
+               if (!!bgp_flag_check(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)
+                   != SAVE_BGP_LOG_NEIGHBOR_CHANGES)
+                       vty_out(vty, " %sbgp log-neighbor-changes\n",
+                               bgp_flag_check(bgp,
+                                              BGP_FLAG_LOG_NEIGHBOR_CHANGES)
+                                       ? ""
+                                       : "no ");
+
+               /* BGP configuration. */
+               if (bgp_flag_check(bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
+                       vty_out(vty, " bgp always-compare-med\n");
+
+               /* RFC8212 default eBGP policy. */
+               if (bgp->ebgp_requires_policy
+                   == DEFAULT_EBGP_POLICY_ENABLED)
+                       vty_out(vty, " bgp ebgp-requires-policy\n");
+
+               /* draft-ietf-idr-deprecate-as-set-confed-set */
+               if (bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED)
+                       vty_out(vty, " bgp reject-as-sets\n");
+
+               /* BGP default ipv4-unicast. */
+               if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4))
+                       vty_out(vty, " no bgp default ipv4-unicast\n");
+
+               /* BGP default local-preference. */
+               if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF)
+                       vty_out(vty, " bgp default local-preference %u\n",
+                               bgp->default_local_pref);
+
+               /* BGP default show-hostname */
+               if (!!bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME)
+                   != SAVE_BGP_SHOW_HOSTNAME)
+                       vty_out(vty, " %sbgp default show-hostname\n",
+                               bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME)
+                                       ? ""
+                                       : "no ");
+
+               /* BGP default subgroup-pkt-queue-max. */
+               if (bgp->default_subgroup_pkt_queue_max
+                   != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX)
+                       vty_out(vty, " bgp default subgroup-pkt-queue-max %u\n",
+                               bgp->default_subgroup_pkt_queue_max);
+
+               /* BGP client-to-client reflection. */
+               if (bgp_flag_check(bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
+                       vty_out(vty, " no bgp client-to-client reflection\n");
+
+               /* BGP cluster ID. */
+               if (CHECK_FLAG(bgp->config, BGP_CONFIG_CLUSTER_ID))
+                       vty_out(vty, " bgp cluster-id %s\n",
+                               inet_ntoa(bgp->cluster_id));
+
+               /* Disable ebgp connected nexthop check */
+               if (bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
+                       vty_out(vty,
+                               " bgp disable-ebgp-connected-route-check\n");
+
+               /* Confederation identifier*/
+               if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
+                       vty_out(vty, " bgp confederation identifier %u\n",
+                               bgp->confed_id);
+
+               /* Confederation peer */
+               if (bgp->confed_peers_cnt > 0) {
+                       int i;
+
+                       vty_out(vty, " bgp confederation peers");
+
+                       for (i = 0; i < bgp->confed_peers_cnt; i++)
+                               vty_out(vty, " %u", bgp->confed_peers[i]);
+
+                       vty_out(vty, "\n");
                }
-       }
-       if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
-                      BGP_VPN_POLICY_TOVPN_RD_SET)) {
-               char buf[RD_ADDRSTRLEN];
-               vty_out(vty, "%*srd vpn export %s\n", indent, "",
-                       prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
-                                     sizeof(buf)));
-       }
-       if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
-                      BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
 
-               char buf[PREFIX_STRLEN];
-               if (inet_ntop(bgp->vpn_policy[afi].tovpn_nexthop.family,
-                             &bgp->vpn_policy[afi].tovpn_nexthop.u.prefix, buf,
-                             sizeof(buf))) {
+               /* BGP deterministic-med. */
+               if (!!bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)
+                   != SAVE_BGP_DETERMINISTIC_MED)
+                       vty_out(vty, " %sbgp deterministic-med\n",
+                               bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)
+                                       ? ""
+                                       : "no ");
+
+               /* BGP update-delay. */
+               bgp_config_write_update_delay(vty, bgp);
+
+               if (bgp->v_maxmed_onstartup
+                   != BGP_MAXMED_ONSTARTUP_UNCONFIGURED) {
+                       vty_out(vty, " bgp max-med on-startup %u",
+                               bgp->v_maxmed_onstartup);
+                       if (bgp->maxmed_onstartup_value
+                           != BGP_MAXMED_VALUE_DEFAULT)
+                               vty_out(vty, " %u",
+                                       bgp->maxmed_onstartup_value);
+                       vty_out(vty, "\n");
+               }
+               if (bgp->v_maxmed_admin != BGP_MAXMED_ADMIN_UNCONFIGURED) {
+                       vty_out(vty, " bgp max-med administrative");
+                       if (bgp->maxmed_admin_value != BGP_MAXMED_VALUE_DEFAULT)
+                               vty_out(vty, " %u", bgp->maxmed_admin_value);
+                       vty_out(vty, "\n");
+               }
 
-                       vty_out(vty, "%*snexthop vpn export %s\n",
-                               indent, "", buf);
+               /* write quanta */
+               bgp_config_write_wpkt_quanta(vty, bgp);
+               /* read quanta */
+               bgp_config_write_rpkt_quanta(vty, bgp);
+
+               /* coalesce time */
+               bgp_config_write_coalesce_time(vty, bgp);
+
+               /* BGP graceful-restart. */
+               if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
+                       vty_out(vty,
+                               " bgp graceful-restart stalepath-time %u\n",
+                               bgp->stalepath_time);
+
+               if (bgp->restart_time != BGP_DEFAULT_RESTART_TIME)
+                       vty_out(vty, " bgp graceful-restart restart-time %u\n",
+                               bgp->restart_time);
+
+               if (bgp->select_defer_time != BGP_DEFAULT_SELECT_DEFERRAL_TIME)
+                       vty_out(vty,
+                               " bgp graceful-restart select-defer-time %u\n",
+                               bgp->select_defer_time);
+
+               if (bgp_global_gr_mode_get(bgp) == GLOBAL_GR)
+                       vty_out(vty, " bgp graceful-restart\n");
+
+               if (bgp_global_gr_mode_get(bgp) == GLOBAL_DISABLE)
+                       vty_out(vty, " bgp graceful-restart-disable\n");
+
+               /* BGP graceful-shutdown */
+               if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
+                       vty_out(vty, " bgp graceful-shutdown\n");
+
+               /* BGP graceful-restart Preserve State F bit. */
+               if (bgp_flag_check(bgp, BGP_FLAG_GR_PRESERVE_FWD))
+                       vty_out(vty,
+                               " bgp graceful-restart preserve-fw-state\n");
+
+               /* Stale timer for RIB */
+               if (bgp->rib_stale_time != BGP_DEFAULT_RIB_STALE_TIME)
+                       vty_out(vty,
+                               " bgp graceful-restart rib-stale-time %u\n",
+                               bgp->rib_stale_time);
+
+               /* BGP bestpath method. */
+               if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_IGNORE))
+                       vty_out(vty, " bgp bestpath as-path ignore\n");
+               if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_CONFED))
+                       vty_out(vty, " bgp bestpath as-path confed\n");
+
+               if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
+                       if (bgp_flag_check(bgp,
+                                          BGP_FLAG_MULTIPATH_RELAX_AS_SET)) {
+                               vty_out(vty,
+                                       " bgp bestpath as-path multipath-relax as-set\n");
+                       } else {
+                               vty_out(vty,
+                                       " bgp bestpath as-path multipath-relax\n");
+                       }
                }
-       }
-       if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]
-           && bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]
-           && ecommunity_cmp(
-                      bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
-                      bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN])) {
 
-               char *b = ecommunity_ecom2str(
-                       bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN],
-                       ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET);
-               vty_out(vty, "%*srt vpn both %s\n", indent, "", b);
-               XFREE(MTYPE_ECOMMUNITY_STR, b);
-       } else {
-               if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]) {
-                       char *b = ecommunity_ecom2str(
-                               bgp->vpn_policy[afi]
-                                       .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
-                               ECOMMUNITY_FORMAT_ROUTE_MAP,
-                               ECOMMUNITY_ROUTE_TARGET);
-                       vty_out(vty, "%*srt vpn import %s\n", indent, "", b);
-                       XFREE(MTYPE_ECOMMUNITY_STR, b);
+               if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
+                       vty_out(vty,
+                               " bgp route-reflector allow-outbound-policy\n");
                }
-               if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]) {
-                       char *b = ecommunity_ecom2str(
-                               bgp->vpn_policy[afi]
-                                       .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
-                               ECOMMUNITY_FORMAT_ROUTE_MAP,
-                               ECOMMUNITY_ROUTE_TARGET);
-                       vty_out(vty, "%*srt vpn export %s\n", indent, "", b);
-                       XFREE(MTYPE_ECOMMUNITY_STR, b);
+               if (bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID))
+                       vty_out(vty, " bgp bestpath compare-routerid\n");
+               if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED)
+                   || bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) {
+                       vty_out(vty, " bgp bestpath med");
+                       if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED))
+                               vty_out(vty, " confed");
+                       if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST))
+                               vty_out(vty, " missing-as-worst");
+                       vty_out(vty, "\n");
                }
-       }
 
-       if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN])
-               vty_out(vty, "%*sroute-map vpn export %s\n", indent, "",
-                       bgp->vpn_policy[afi]
-                               .rmap_name[BGP_VPN_POLICY_DIR_TOVPN]);
+               /* BGP network import check. */
+               if (!!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
+                   != SAVE_BGP_IMPORT_CHECK)
+                       vty_out(vty, " %sbgp network import-check\n",
+                               bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
+                                       ? ""
+                                       : "no ");
+
+               /* BGP timers configuration. */
+               if (bgp->default_keepalive != SAVE_BGP_KEEPALIVE
+                   && bgp->default_holdtime != SAVE_BGP_HOLDTIME)
+                       vty_out(vty, " timers bgp %u %u\n",
+                               bgp->default_keepalive, bgp->default_holdtime);
+
+               /* peer-group */
+               for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
+                       bgp_config_write_peer_global(vty, bgp, group->conf);
+               }
 
-       if (bgp->vpn_policy[afi].import_redirect_rtlist) {
-               char *b = ecommunity_ecom2str(
-                                       bgp->vpn_policy[afi]
-                                       .import_redirect_rtlist,
-                                       ECOMMUNITY_FORMAT_ROUTE_MAP,
-                                       ECOMMUNITY_ROUTE_TARGET);
+               /* Normal neighbor configuration. */
+               for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+                       if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+                               bgp_config_write_peer_global(vty, bgp, peer);
+               }
 
-               vty_out(vty, "%*srt redirect import %s\n", indent, "", b);
-               XFREE(MTYPE_ECOMMUNITY_STR, b);
+               /* listen range and limit for dynamic BGP neighbors */
+               bgp_config_write_listen(vty, bgp);
+
+               /*
+                * BGP default autoshutdown neighbors
+                *
+                * This must be placed after any peer and peer-group
+                * configuration, to avoid setting all peers to shutdown after
+                * a daemon restart, which is undesired behavior. (see #2286)
+                */
+               if (bgp->autoshutdown)
+                       vty_out(vty, " bgp default shutdown\n");
+
+               /* IPv4 unicast configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST);
+
+               /* IPv4 multicast configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_IP, SAFI_MULTICAST);
+
+               /* IPv4 labeled-unicast configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_IP, SAFI_LABELED_UNICAST);
+
+               /* IPv4 VPN configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_IP, SAFI_MPLS_VPN);
+
+               /* ENCAPv4 configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_IP, SAFI_ENCAP);
+
+               /* FLOWSPEC v4 configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_IP, SAFI_FLOWSPEC);
+
+               /* IPv6 unicast configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_UNICAST);
+
+               /* IPv6 multicast configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_MULTICAST);
+
+               /* IPv6 labeled-unicast configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_IP6,
+                                       SAFI_LABELED_UNICAST);
+
+               /* IPv6 VPN configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_MPLS_VPN);
+
+               /* ENCAPv6 configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_ENCAP);
+
+               /* FLOWSPEC v6 configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_FLOWSPEC);
+
+               /* EVPN configuration.  */
+               bgp_config_write_family(vty, bgp, AFI_L2VPN, SAFI_EVPN);
+
+               hook_call(bgp_inst_config_write, bgp, vty);
+
+#if ENABLE_BGP_VNC
+               bgp_rfapi_cfg_write(vty, bgp);
+#endif
+
+               vty_out(vty, "!\n");
        }
+       return 0;
 }
 
 
@@ -13194,17 +15503,51 @@ void bgp_vty_init(void)
        install_element(BGP_NODE, &bgp_deterministic_med_cmd);
        install_element(BGP_NODE, &no_bgp_deterministic_med_cmd);
 
-       /* "bgp graceful-restart" commands */
-       install_element(BGP_NODE, &bgp_graceful_restart_cmd);
-       install_element(BGP_NODE, &no_bgp_graceful_restart_cmd);
+       /* "bgp graceful-restart" command */
+       install_element(BGP_NODE,
+                       &bgp_graceful_restart_cmd);
+       install_element(BGP_NODE,
+                       &no_bgp_graceful_restart_cmd);
+
+       /* "bgp graceful-restart-disable" command */
+       install_element(BGP_NODE,
+                       &bgp_graceful_restart_disable_cmd);
+       install_element(BGP_NODE,
+                       &no_bgp_graceful_restart_disable_cmd);
+
+       /* "neighbor a:b:c:d graceful-restart" command */
+       install_element(BGP_NODE,
+                       &bgp_neighbor_graceful_restart_set_cmd);
+       install_element(BGP_NODE,
+                       &no_bgp_neighbor_graceful_restart_set_cmd);
+
+       /* "neighbor a:b:c:d graceful-restart-disable" command */
+       install_element(BGP_NODE,
+                       &bgp_neighbor_graceful_restart_disable_set_cmd);
+       install_element(BGP_NODE,
+                       &no_bgp_neighbor_graceful_restart_disable_set_cmd);
+
+       /* "neighbor a:b:c:d graceful-restart-helper" command */
+       install_element(BGP_NODE,
+                       &bgp_neighbor_graceful_restart_helper_set_cmd);
+       install_element(BGP_NODE,
+                       &no_bgp_neighbor_graceful_restart_helper_set_cmd);
+
        install_element(BGP_NODE, &bgp_graceful_restart_stalepath_time_cmd);
        install_element(BGP_NODE, &no_bgp_graceful_restart_stalepath_time_cmd);
        install_element(BGP_NODE, &bgp_graceful_restart_restart_time_cmd);
        install_element(BGP_NODE, &no_bgp_graceful_restart_restart_time_cmd);
-
+       install_element(BGP_NODE, &bgp_graceful_restart_select_defer_time_cmd);
+       install_element(BGP_NODE,
+                       &no_bgp_graceful_restart_select_defer_time_cmd);
        install_element(BGP_NODE, &bgp_graceful_restart_preserve_fw_cmd);
        install_element(BGP_NODE, &no_bgp_graceful_restart_preserve_fw_cmd);
 
+       install_element(BGP_NODE, &bgp_graceful_restart_disable_eor_cmd);
+       install_element(BGP_NODE, &no_bgp_graceful_restart_disable_eor_cmd);
+       install_element(BGP_NODE, &bgp_graceful_restart_rib_stale_time_cmd);
+       install_element(BGP_NODE, &no_bgp_graceful_restart_rib_stale_time_cmd);
+
        /* "bgp graceful-shutdown" commands */
        install_element(BGP_NODE, &bgp_graceful_shutdown_cmd);
        install_element(BGP_NODE, &no_bgp_graceful_shutdown_cmd);
@@ -14030,6 +16373,26 @@ void bgp_vty_init(void)
        install_element(BGP_VPNV6_NODE, &neighbor_unsuppress_map_cmd);
        install_element(BGP_VPNV6_NODE, &no_neighbor_unsuppress_map_cmd);
 
+       /* neighbor maximum-prefix-out commands. */
+       install_element(BGP_NODE, &neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_NODE, &no_neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_IPV4_NODE, &neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_IPV4_NODE, &no_neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_IPV4M_NODE, &neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_IPV4L_NODE, &neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_IPV4L_NODE, &no_neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_IPV6_NODE, &neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_IPV6_NODE, &no_neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_IPV6M_NODE, &neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_IPV6M_NODE, &no_neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_IPV6L_NODE, &neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_IPV6L_NODE, &no_neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_VPNV4_NODE, &neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_VPNV6_NODE, &neighbor_maximum_prefix_out_cmd);
+       install_element(BGP_VPNV6_NODE, &no_neighbor_maximum_prefix_out_cmd);
+
        /* "neighbor maximum-prefix" commands. */
        install_element(BGP_NODE, &neighbor_maximum_prefix_hidden_cmd);
        install_element(BGP_NODE,
@@ -14179,6 +16542,9 @@ void bgp_vty_init(void)
        /* "show [ip] bgp neighbors" commands. */
        install_element(VIEW_NODE, &show_ip_bgp_neighbors_cmd);
 
+       install_element(VIEW_NODE,
+                       &show_ip_bgp_neighbors_graceful_restart_cmd);
+
        /* "show [ip] bgp peer-group" commands. */
        install_element(VIEW_NODE, &show_ip_bgp_peer_groups_cmd);
 
@@ -14340,21 +16706,29 @@ static void community_list_perror(struct vty *vty, int ret)
 /*community-list standard */
 DEFUN (community_list_standard,
        bgp_community_list_standard_cmd,
-       "bgp community-list <(1-99)|standard WORD> <deny|permit> AA:NN...",
+       "bgp community-list <(1-99)|standard WORD> [seq (1-4294967295)] <deny|permit> AA:NN...",
        BGP_STR
        COMMUNITY_LIST_STR
        "Community list number (standard)\n"
        "Add an standard community-list entry\n"
        "Community list name\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify community to reject\n"
        "Specify community to accept\n"
        COMMUNITY_VAL_STR)
 {
        char *cl_name_or_number = NULL;
+       char *seq = NULL;
        int direct = 0;
        int style = COMMUNITY_LIST_STANDARD;
        int idx = 0;
 
+       argv_find(argv, argc, "(1-4294967295)", &idx);
+       if (idx)
+               seq = argv[idx]->arg;
+
+       idx = 0;
        argv_find(argv, argc, "(1-99)", &idx);
        argv_find(argv, argc, "WORD", &idx);
        cl_name_or_number = argv[idx]->arg;
@@ -14363,8 +16737,8 @@ DEFUN (community_list_standard,
        argv_find(argv, argc, "AA:NN", &idx);
        char *str = argv_concat(argv, argc, idx);
 
-       int ret = community_list_set(bgp_clist, cl_name_or_number, str, direct,
-                                    style);
+       int ret = community_list_set(bgp_clist, cl_name_or_number, str, seq,
+                                    direct, style);
 
        XFREE(MTYPE_TMP, str);
 
@@ -14379,13 +16753,15 @@ DEFUN (community_list_standard,
 
 DEFUN (no_community_list_standard_all,
        no_bgp_community_list_standard_all_cmd,
-       "no bgp community-list <(1-99)|standard WORD> <deny|permit> AA:NN...",
+       "no bgp community-list <(1-99)|standard WORD> [seq (1-4294967295)] <deny|permit> AA:NN...",
        NO_STR
        BGP_STR
        COMMUNITY_LIST_STR
        "Community list number (standard)\n"
        "Add an standard community-list entry\n"
        "Community list name\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify community to reject\n"
        "Specify community to accept\n"
        COMMUNITY_VAL_STR)
@@ -14394,9 +16770,14 @@ DEFUN (no_community_list_standard_all,
        char *str = NULL;
        int direct = 0;
        int style = COMMUNITY_LIST_STANDARD;
-
+       char *seq = NULL;
        int idx = 0;
 
+       argv_find(argv, argc, "(1-4294967295)", &idx);
+       if (idx)
+               seq = argv[idx]->arg;
+
+       idx = 0;
        argv_find(argv, argc, "permit", &idx);
        argv_find(argv, argc, "deny", &idx);
 
@@ -14415,7 +16796,7 @@ DEFUN (no_community_list_standard_all,
        argv_find(argv, argc, "WORD", &idx);
        cl_name_or_number = argv[idx]->arg;
 
-       int ret = community_list_unset(bgp_clist, cl_name_or_number, str,
+       int ret = community_list_unset(bgp_clist, cl_name_or_number, str, seq,
                                       direct, style);
 
        XFREE(MTYPE_TMP, str);
@@ -14438,22 +16819,30 @@ ALIAS(no_community_list_standard_all, no_bgp_community_list_standard_all_list_cm
 /*community-list expanded */
 DEFUN (community_list_expanded_all,
        bgp_community_list_expanded_all_cmd,
-       "bgp community-list <(100-500)|expanded WORD> <deny|permit> AA:NN...",
+       "bgp community-list <(100-500)|expanded WORD> [seq (1-4294967295)] <deny|permit> AA:NN...",
        BGP_STR
        COMMUNITY_LIST_STR
        "Community list number (expanded)\n"
        "Add an expanded community-list entry\n"
        "Community list name\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify community to reject\n"
        "Specify community to accept\n"
        COMMUNITY_VAL_STR)
 {
        char *cl_name_or_number = NULL;
+       char *seq = NULL;
        int direct = 0;
        int style = COMMUNITY_LIST_EXPANDED;
-
        int idx = 0;
 
+       argv_find(argv, argc, "(1-4294967295)", &idx);
+       if (idx)
+               seq = argv[idx]->arg;
+
+       idx = 0;
+
        argv_find(argv, argc, "(100-500)", &idx);
        argv_find(argv, argc, "WORD", &idx);
        cl_name_or_number = argv[idx]->arg;
@@ -14462,8 +16851,8 @@ DEFUN (community_list_expanded_all,
        argv_find(argv, argc, "AA:NN", &idx);
        char *str = argv_concat(argv, argc, idx);
 
-       int ret = community_list_set(bgp_clist, cl_name_or_number, str, direct,
-                                    style);
+       int ret = community_list_set(bgp_clist, cl_name_or_number, str, seq,
+                                    direct, style);
 
        XFREE(MTYPE_TMP, str);
 
@@ -14478,24 +16867,31 @@ DEFUN (community_list_expanded_all,
 
 DEFUN (no_community_list_expanded_all,
        no_bgp_community_list_expanded_all_cmd,
-       "no bgp community-list <(100-500)|expanded WORD> <deny|permit> AA:NN...",
+       "no bgp community-list <(100-500)|expanded WORD> [seq (1-4294967295)] <deny|permit> AA:NN...",
        NO_STR
        BGP_STR
        COMMUNITY_LIST_STR
        "Community list number (expanded)\n"
        "Add an expanded community-list entry\n"
        "Community list name\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify community to reject\n"
        "Specify community to accept\n"
        COMMUNITY_VAL_STR)
 {
        char *cl_name_or_number = NULL;
+       char *seq = NULL;
        char *str = NULL;
        int direct = 0;
        int style = COMMUNITY_LIST_EXPANDED;
-
        int idx = 0;
 
+       argv_find(argv, argc, "(1-4294967295)", &idx);
+       if (idx)
+               seq = argv[idx]->arg;
+
+       idx = 0;
        argv_find(argv, argc, "permit", &idx);
        argv_find(argv, argc, "deny", &idx);
 
@@ -14514,7 +16910,7 @@ DEFUN (no_community_list_expanded_all,
        argv_find(argv, argc, "WORD", &idx);
        cl_name_or_number = argv[idx]->arg;
 
-       int ret = community_list_unset(bgp_clist, cl_name_or_number, str,
+       int ret = community_list_unset(bgp_clist, cl_name_or_number, str, seq,
                                       direct, style);
 
        XFREE(MTYPE_TMP, str);
@@ -14641,7 +17037,13 @@ static int lcommunity_list_set_vty(struct vty *vty, int argc,
        char *str;
        int idx = 0;
        char *cl_name;
+       char *seq = NULL;
+
+       argv_find(argv, argc, "(1-4294967295)", &idx);
+       if (idx)
+               seq = argv[idx]->arg;
 
+       idx = 0;
        direct = argv_find(argv, argc, "permit", &idx) ? COMMUNITY_PERMIT
                                                       : COMMUNITY_DENY;
 
@@ -14665,7 +17067,7 @@ static int lcommunity_list_set_vty(struct vty *vty, int argc,
        else
                str = NULL;
 
-       ret = lcommunity_list_set(bgp_clist, cl_name, str, direct, style);
+       ret = lcommunity_list_set(bgp_clist, cl_name, str, seq, direct, style);
 
        /* Free temporary community list string allocated by
           argv_concat().  */
@@ -14685,7 +17087,13 @@ static int lcommunity_list_unset_vty(struct vty *vty, int argc,
        int direct = 0;
        char *str = NULL;
        int idx = 0;
+       char *seq = NULL;
+
+       argv_find(argv, argc, "(1-4294967295)", &idx);
+       if (idx)
+               seq = argv[idx]->arg;
 
+       idx = 0;
        argv_find(argv, argc, "permit", &idx);
        argv_find(argv, argc, "deny", &idx);
 
@@ -14709,7 +17117,7 @@ static int lcommunity_list_unset_vty(struct vty *vty, int argc,
        argv_find(argv, argc, "WORD", &idx);
 
        /* Unset community list.  */
-       ret = lcommunity_list_unset(bgp_clist, argv[idx]->arg, str, direct,
+       ret = lcommunity_list_unset(bgp_clist, argv[idx]->arg, str, seq, direct,
                                    style);
 
        /* Free temporary community list string allocated by
@@ -14730,10 +17138,12 @@ static int lcommunity_list_unset_vty(struct vty *vty, int argc,
 
 DEFUN (lcommunity_list_standard,
        bgp_lcommunity_list_standard_cmd,
-       "bgp large-community-list (1-99) <deny|permit> AA:BB:CC...",
+       "bgp large-community-list (1-99) [seq (1-4294967295)] <deny|permit> AA:BB:CC...",
        BGP_STR
        LCOMMUNITY_LIST_STR
        "Large Community list number (standard)\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify large community to reject\n"
        "Specify large community to accept\n"
        LCOMMUNITY_VAL_STR)
@@ -14744,10 +17154,12 @@ DEFUN (lcommunity_list_standard,
 
 DEFUN (lcommunity_list_expanded,
        bgp_lcommunity_list_expanded_cmd,
-       "bgp large-community-list (100-500) <deny|permit> LINE...",
+       "bgp large-community-list (100-500) [seq (1-4294967295)] <deny|permit> LINE...",
        BGP_STR
        LCOMMUNITY_LIST_STR
        "Large Community list number (expanded)\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify large community to reject\n"
        "Specify large community to accept\n"
        "An ordered list as a regular-expression\n")
@@ -14758,11 +17170,13 @@ DEFUN (lcommunity_list_expanded,
 
 DEFUN (lcommunity_list_name_standard,
        bgp_lcommunity_list_name_standard_cmd,
-       "bgp large-community-list standard WORD <deny|permit> AA:BB:CC...",
+       "bgp large-community-list standard WORD [seq (1-4294967295)] <deny|permit> AA:BB:CC...",
        BGP_STR
        LCOMMUNITY_LIST_STR
        "Specify standard large-community-list\n"
        "Large Community list name\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify large community to reject\n"
        "Specify large community to accept\n"
        LCOMMUNITY_VAL_STR)
@@ -14773,11 +17187,13 @@ DEFUN (lcommunity_list_name_standard,
 
 DEFUN (lcommunity_list_name_expanded,
        bgp_lcommunity_list_name_expanded_cmd,
-       "bgp large-community-list expanded WORD <deny|permit> LINE...",
+       "bgp large-community-list expanded WORD [seq (1-4294967295)] <deny|permit> LINE...",
        BGP_STR
        LCOMMUNITY_LIST_STR
        "Specify expanded large-community-list\n"
        "Large Community list name\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify large community to reject\n"
        "Specify large community to accept\n"
        "An ordered list as a regular-expression\n")
@@ -14786,8 +17202,8 @@ DEFUN (lcommunity_list_name_expanded,
                                       LARGE_COMMUNITY_LIST_EXPANDED, 1);
 }
 
-DEFUN (no_lcommunity_list_standard_all,
-       no_bgp_lcommunity_list_standard_all_cmd,
+DEFUN (no_lcommunity_list_all,
+       no_bgp_lcommunity_list_all_cmd,
        "no bgp large-community-list <(1-99)|(100-500)|WORD>",
        NO_STR
        BGP_STR
@@ -14800,6 +17216,19 @@ DEFUN (no_lcommunity_list_standard_all,
                                         LARGE_COMMUNITY_LIST_STANDARD);
 }
 
+DEFUN (no_lcommunity_list_name_standard_all,
+       no_bgp_lcommunity_list_name_standard_all_cmd,
+       "no bgp large-community-list standard WORD",
+       NO_STR
+       BGP_STR
+       LCOMMUNITY_LIST_STR
+       "Specify standard large-community-list\n"
+       "Large Community list name\n")
+{
+       return lcommunity_list_unset_vty(vty, argc, argv,
+                                        LARGE_COMMUNITY_LIST_STANDARD);
+}
+
 DEFUN (no_lcommunity_list_name_expanded_all,
        no_bgp_lcommunity_list_name_expanded_all_cmd,
        "no bgp large-community-list expanded WORD",
@@ -14815,11 +17244,13 @@ DEFUN (no_lcommunity_list_name_expanded_all,
 
 DEFUN (no_lcommunity_list_standard,
        no_bgp_lcommunity_list_standard_cmd,
-       "no bgp large-community-list (1-99) <deny|permit> AA:AA:NN...",
+       "no bgp large-community-list (1-99) [seq (1-4294967295)] <deny|permit> AA:AA:NN...",
        NO_STR
        BGP_STR
        LCOMMUNITY_LIST_STR
        "Large Community list number (standard)\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify large community to reject\n"
        "Specify large community to accept\n"
        LCOMMUNITY_VAL_STR)
@@ -14830,11 +17261,13 @@ DEFUN (no_lcommunity_list_standard,
 
 DEFUN (no_lcommunity_list_expanded,
        no_bgp_lcommunity_list_expanded_cmd,
-       "no bgp large-community-list (100-500) <deny|permit> LINE...",
+       "no bgp large-community-list (100-500) [seq (1-4294967295)] <deny|permit> LINE...",
        NO_STR
        BGP_STR
        LCOMMUNITY_LIST_STR
        "Large Community list number (expanded)\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify large community to reject\n"
        "Specify large community to accept\n"
        "An ordered list as a regular-expression\n")
@@ -14845,12 +17278,14 @@ DEFUN (no_lcommunity_list_expanded,
 
 DEFUN (no_lcommunity_list_name_standard,
        no_bgp_lcommunity_list_name_standard_cmd,
-       "no bgp large-community-list standard WORD <deny|permit> AA:AA:NN...",
+       "no bgp large-community-list standard WORD [seq (1-4294967295)] <deny|permit> AA:AA:NN...",
        NO_STR
        BGP_STR
        LCOMMUNITY_LIST_STR
        "Specify standard large-community-list\n"
        "Large Community list name\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify large community to reject\n"
        "Specify large community to accept\n"
        LCOMMUNITY_VAL_STR)
@@ -14861,12 +17296,14 @@ DEFUN (no_lcommunity_list_name_standard,
 
 DEFUN (no_lcommunity_list_name_expanded,
        no_bgp_lcommunity_list_name_expanded_cmd,
-       "no bgp large-community-list expanded WORD <deny|permit> LINE...",
+       "no bgp large-community-list expanded WORD [seq (1-4294967295)] <deny|permit> LINE...",
        NO_STR
        BGP_STR
        LCOMMUNITY_LIST_STR
        "Specify expanded large-community-list\n"
        "Large community list name\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify large community to reject\n"
        "Specify large community to accept\n"
        "An ordered list as a regular-expression\n")
@@ -14961,12 +17398,14 @@ DEFUN (show_lcommunity_list_arg,
 
 DEFUN (extcommunity_list_standard,
        bgp_extcommunity_list_standard_cmd,
-       "bgp extcommunity-list <(1-99)|standard WORD> <deny|permit> AA:NN...",
+       "bgp extcommunity-list <(1-99)|standard WORD> [seq (1-4294967295)] <deny|permit> AA:NN...",
        BGP_STR
        EXTCOMMUNITY_LIST_STR
        "Extended Community list number (standard)\n"
        "Specify standard extcommunity-list\n"
        "Community list name\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify community to reject\n"
        "Specify community to accept\n"
        EXTCOMMUNITY_VAL_STR)
@@ -14974,18 +17413,24 @@ DEFUN (extcommunity_list_standard,
        int style = EXTCOMMUNITY_LIST_STANDARD;
        int direct = 0;
        char *cl_number_or_name = NULL;
+       char *seq = NULL;
 
        int idx = 0;
 
        argv_find(argv, argc, "(1-99)", &idx);
        argv_find(argv, argc, "WORD", &idx);
        cl_number_or_name = argv[idx]->arg;
+
+       argv_find(argv, argc, "(1-4294967295)", &idx);
+       if (idx)
+               seq = argv[idx]->arg;
+
        direct = argv_find(argv, argc, "permit", &idx) ? COMMUNITY_PERMIT
                                                       : COMMUNITY_DENY;
        argv_find(argv, argc, "AA:NN", &idx);
        char *str = argv_concat(argv, argc, idx);
 
-       int ret = extcommunity_list_set(bgp_clist, cl_number_or_name, str,
+       int ret = extcommunity_list_set(bgp_clist, cl_number_or_name, str, seq,
                                        direct, style);
 
        XFREE(MTYPE_TMP, str);
@@ -15000,12 +17445,14 @@ DEFUN (extcommunity_list_standard,
 
 DEFUN (extcommunity_list_name_expanded,
        bgp_extcommunity_list_name_expanded_cmd,
-       "bgp extcommunity-list <(100-500)|expanded WORD> <deny|permit> LINE...",
+       "bgp extcommunity-list <(100-500)|expanded WORD> [seq (1-4294967295)] <deny|permit> LINE...",
        BGP_STR
        EXTCOMMUNITY_LIST_STR
        "Extended Community list number (expanded)\n"
        "Specify expanded extcommunity-list\n"
        "Extended Community list name\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify community to reject\n"
        "Specify community to accept\n"
        "An ordered list as a regular-expression\n")
@@ -15013,17 +17460,23 @@ DEFUN (extcommunity_list_name_expanded,
        int style = EXTCOMMUNITY_LIST_EXPANDED;
        int direct = 0;
        char *cl_number_or_name = NULL;
+       char *seq = NULL;
        int idx = 0;
 
        argv_find(argv, argc, "(100-500)", &idx);
        argv_find(argv, argc, "WORD", &idx);
        cl_number_or_name = argv[idx]->arg;
+
+       argv_find(argv, argc, "(1-4294967295)", &idx);
+       if (idx)
+               seq = argv[idx]->arg;
+
        direct = argv_find(argv, argc, "permit", &idx) ? COMMUNITY_PERMIT
                                                       : COMMUNITY_DENY;
        argv_find(argv, argc, "LINE", &idx);
        char *str = argv_concat(argv, argc, idx);
 
-       int ret = extcommunity_list_set(bgp_clist, cl_number_or_name, str,
+       int ret = extcommunity_list_set(bgp_clist, cl_number_or_name, str, seq,
                                        direct, style);
 
        XFREE(MTYPE_TMP, str);
@@ -15038,13 +17491,15 @@ DEFUN (extcommunity_list_name_expanded,
 
 DEFUN (no_extcommunity_list_standard_all,
        no_bgp_extcommunity_list_standard_all_cmd,
-       "no bgp extcommunity-list <(1-99)|standard WORD> <deny|permit> AA:NN...",
+       "no bgp extcommunity-list <(1-99)|standard WORD> [seq (1-4294967295)] <deny|permit> AA:NN...",
        NO_STR
        BGP_STR
        EXTCOMMUNITY_LIST_STR
        "Extended Community list number (standard)\n"
        "Specify standard extcommunity-list\n"
        "Community list name\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify community to reject\n"
        "Specify community to accept\n"
        EXTCOMMUNITY_VAL_STR)
@@ -15053,11 +17508,16 @@ DEFUN (no_extcommunity_list_standard_all,
        int direct = 0;
        char *cl_number_or_name = NULL;
        char *str = NULL;
+       char *seq = NULL;
        int idx = 0;
 
+       argv_find(argv, argc, "(1-4294967295)", &idx);
+       if (idx)
+               seq = argv[idx]->arg;
+
+       idx = 0;
        argv_find(argv, argc, "permit", &idx);
        argv_find(argv, argc, "deny", &idx);
-
        if (idx) {
                direct = argv_find(argv, argc, "permit", &idx)
                                 ? COMMUNITY_PERMIT
@@ -15074,7 +17534,7 @@ DEFUN (no_extcommunity_list_standard_all,
        cl_number_or_name = argv[idx]->arg;
 
        int ret = extcommunity_list_unset(bgp_clist, cl_number_or_name, str,
-                                         direct, style);
+                                         seq, direct, style);
 
        XFREE(MTYPE_TMP, str);
 
@@ -15096,13 +17556,15 @@ ALIAS(no_extcommunity_list_standard_all,
 
 DEFUN (no_extcommunity_list_expanded_all,
        no_bgp_extcommunity_list_expanded_all_cmd,
-       "no bgp extcommunity-list <(100-500)|expanded WORD> <deny|permit> LINE...",
+       "no bgp extcommunity-list <(100-500)|expanded WORD> [seq (1-4294967295)] <deny|permit> LINE...",
        NO_STR
        BGP_STR
        EXTCOMMUNITY_LIST_STR
        "Extended Community list number (expanded)\n"
        "Specify expanded extcommunity-list\n"
        "Extended Community list name\n"
+       "Sequence number of an entry\n"
+       "Sequence number\n"
        "Specify community to reject\n"
        "Specify community to accept\n"
        "An ordered list as a regular-expression\n")
@@ -15111,8 +17573,14 @@ DEFUN (no_extcommunity_list_expanded_all,
        int direct = 0;
        char *cl_number_or_name = NULL;
        char *str = NULL;
+       char *seq = NULL;
        int idx = 0;
 
+       argv_find(argv, argc, "(1-4294967295)", &idx);
+       if (idx)
+               seq = argv[idx]->arg;
+
+       idx = 0;
        argv_find(argv, argc, "permit", &idx);
        argv_find(argv, argc, "deny", &idx);
 
@@ -15132,7 +17600,7 @@ DEFUN (no_extcommunity_list_expanded_all,
        cl_number_or_name = argv[idx]->arg;
 
        int ret = extcommunity_list_unset(bgp_clist, cl_number_or_name, str,
-                                         direct, style);
+                                         seq, direct, style);
 
        XFREE(MTYPE_TMP, str);
 
@@ -15243,18 +17711,22 @@ static int community_list_config_write(struct vty *vty)
 
        for (list = cm->num.head; list; list = list->next)
                for (entry = list->head; entry; entry = entry->next) {
-                       vty_out(vty, "bgp community-list %s %s %s\n", list->name,
+                       vty_out(vty,
+                               "bgp community-list %s seq %" PRId64 " %s %s\n",
+                               list->name, entry->seq,
                                community_direct_str(entry->direct),
                                community_list_config_str(entry));
                        write++;
                }
        for (list = cm->str.head; list; list = list->next)
                for (entry = list->head; entry; entry = entry->next) {
-                       vty_out(vty, "bgp community-list %s %s %s %s\n",
+                       vty_out(vty,
+                               "bgp community-list %s %s seq %" PRId64 " %s %s\n",
                                entry->style == COMMUNITY_LIST_STANDARD
                                        ? "standard"
                                        : "expanded",
-                               list->name, community_direct_str(entry->direct),
+                               list->name, entry->seq,
+                               community_direct_str(entry->direct),
                                community_list_config_str(entry));
                        write++;
                }
@@ -15264,18 +17736,23 @@ static int community_list_config_write(struct vty *vty)
 
        for (list = cm->num.head; list; list = list->next)
                for (entry = list->head; entry; entry = entry->next) {
-                       vty_out(vty, "bgp extcommunity-list %s %s %s\n",
-                               list->name, community_direct_str(entry->direct),
+                       vty_out(vty,
+                               "bgp extcommunity-list %s seq %" PRId64 " %s %s\n",
+                               list->name, entry->seq,
+                               community_direct_str(entry->direct),
                                community_list_config_str(entry));
                        write++;
                }
        for (list = cm->str.head; list; list = list->next)
                for (entry = list->head; entry; entry = entry->next) {
-                       vty_out(vty, "bgp extcommunity-list %s %s %s %s\n",
+                       vty_out(vty,
+                               "bgp extcommunity-list %s %s seq %" PRId64
+                               " %s %s\n",
                                entry->style == EXTCOMMUNITY_LIST_STANDARD
                                        ? "standard"
                                        : "expanded",
-                               list->name, community_direct_str(entry->direct),
+                               list->name, entry->seq,
+                               community_direct_str(entry->direct),
                                community_list_config_str(entry));
                        write++;
                }
@@ -15287,18 +17764,24 @@ static int community_list_config_write(struct vty *vty)
 
        for (list = cm->num.head; list; list = list->next)
                for (entry = list->head; entry; entry = entry->next) {
-                       vty_out(vty, "bgp large-community-list %s %s %s\n",
-                               list->name, community_direct_str(entry->direct),
+                       vty_out(vty,
+                               "bgp large-community-list %s seq %" PRId64
+                               " %s %s\n",
+                               list->name, entry->seq,
+                               community_direct_str(entry->direct),
                                community_list_config_str(entry));
                        write++;
                }
        for (list = cm->str.head; list; list = list->next)
                for (entry = list->head; entry; entry = entry->next) {
-                       vty_out(vty, "bgp large-community-list %s %s %s %s\n",
+                       vty_out(vty,
+                               "bgp large-community-list %s %s seq %" PRId64
+                               " %s %s\n",
+
                                entry->style == LARGE_COMMUNITY_LIST_STANDARD
                                        ? "standard"
                                        : "expanded",
-                               list->name, community_direct_str(entry->direct),
+                               list->name, entry->seq, community_direct_str(entry->direct),
                                community_list_config_str(entry));
                        write++;
                }
@@ -15341,7 +17824,9 @@ static void community_list_vty(void)
        install_element(CONFIG_NODE, &bgp_lcommunity_list_expanded_cmd);
        install_element(CONFIG_NODE, &bgp_lcommunity_list_name_standard_cmd);
        install_element(CONFIG_NODE, &bgp_lcommunity_list_name_expanded_cmd);
-       install_element(CONFIG_NODE, &no_bgp_lcommunity_list_standard_all_cmd);
+       install_element(CONFIG_NODE, &no_bgp_lcommunity_list_all_cmd);
+       install_element(CONFIG_NODE,
+                       &no_bgp_lcommunity_list_name_standard_all_cmd);
        install_element(CONFIG_NODE,
                        &no_bgp_lcommunity_list_name_expanded_all_cmd);
        install_element(CONFIG_NODE, &no_bgp_lcommunity_list_standard_cmd);