]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_vty.c
bgpd: Replace bgp_flag_* to [UN]SET/CHECK_FLAG macros
[mirror_frr.git] / bgpd / bgp_vty.c
index 9dc6549d9c40c8df295bd0dccc37f733d5cdbf5e..e55548f713bcf240e22976245dfd8c71076dcf78 100644 (file)
@@ -105,9 +105,36 @@ 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) {
@@ -395,13 +422,13 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
                               DFLT_BGP_CONNECT_RETRY);
 
                if (DFLT_BGP_IMPORT_CHECK)
-                       bgp_flag_set(*bgp, BGP_FLAG_IMPORT_CHECK);
+                       SET_FLAG((*bgp)->flags, BGP_FLAG_IMPORT_CHECK);
                if (DFLT_BGP_SHOW_HOSTNAME)
-                       bgp_flag_set(*bgp, BGP_FLAG_SHOW_HOSTNAME);
+                       SET_FLAG((*bgp)->flags, BGP_FLAG_SHOW_HOSTNAME);
                if (DFLT_BGP_LOG_NEIGHBOR_CHANGES)
-                       bgp_flag_set(*bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+                       SET_FLAG((*bgp)->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
                if (DFLT_BGP_DETERMINISTIC_MED)
-                       bgp_flag_set(*bgp, BGP_FLAG_DETERMINISTIC_MED);
+                       SET_FLAG((*bgp)->flags, BGP_FLAG_DETERMINISTIC_MED);
 
                ret = BGP_SUCCESS;
        }
@@ -690,7 +717,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) {
@@ -785,7 +821,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. */
        /*
@@ -795,6 +832,12 @@ 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);
 
@@ -802,6 +845,14 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                                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. */
                if (stype == BGP_CLEAR_SOFT_NONE)
                        bgp->update_delay_over = 0;
@@ -836,6 +887,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 */
@@ -881,6 +935,11 @@ 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)
@@ -889,6 +948,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",
@@ -905,6 +972,11 @@ 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)
@@ -913,6 +985,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",
@@ -1912,7 +1992,7 @@ DEFUN (bgp_client_to_client_reflection,
        "reflection of routes allowed\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT);
        bgp_clear_star_soft_out(vty, bgp->name);
 
        return CMD_SUCCESS;
@@ -1927,7 +2007,7 @@ DEFUN (no_bgp_client_to_client_reflection,
        "reflection of routes allowed\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT);
+       SET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT);
        bgp_clear_star_soft_out(vty, bgp->name);
 
        return CMD_SUCCESS;
@@ -1941,7 +2021,7 @@ DEFUN (bgp_always_compare_med,
        "Allow comparing MED from different neighbors\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_ALWAYS_COMPARE_MED);
+       SET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED);
        bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
@@ -1955,7 +2035,7 @@ DEFUN (no_bgp_always_compare_med,
        "Allow comparing MED from different neighbors\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_ALWAYS_COMPARE_MED);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED);
        bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
@@ -2043,8 +2123,8 @@ DEFUN (bgp_deterministic_med,
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
 
-       if (!bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)) {
-               bgp_flag_set(bgp, BGP_FLAG_DETERMINISTIC_MED);
+       if (!CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
+               SET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED);
                bgp_recalculate_all_bestpaths(bgp);
        }
 
@@ -2065,7 +2145,7 @@ DEFUN (no_bgp_deterministic_med,
        struct peer *peer;
        struct listnode *node, *nnode;
 
-       if (bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)) {
+       if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
                bestpath_per_as_used = 0;
 
                for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
@@ -2085,7 +2165,7 @@ DEFUN (no_bgp_deterministic_med,
                                "bgp deterministic-med cannot be disabled while addpath-tx-bestpath-per-AS is in use\n");
                        return CMD_WARNING_CONFIG_FAILED;
                } else {
-                       bgp_flag_unset(bgp, BGP_FLAG_DETERMINISTIC_MED);
+                       UNSET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED);
                        bgp_recalculate_all_bestpaths(bgp);
                }
        }
@@ -2093,37 +2173,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;
@@ -2135,12 +2246,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;
@@ -2151,14 +2262,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)
+               SET_FLAG(bgp->flags, BGP_FLAG_SELECT_DEFER_DISABLE);
+       else
+               UNSET_FLAG(bgp->flags, 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);
 
@@ -2167,42 +2300,408 @@ 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;
+       UNSET_FLAG(bgp->flags, 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);
+       SET_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD);
        return CMD_SUCCESS;
 }
 
 DEFUN (no_bgp_graceful_restart_preserve_fw,
-       no_bgp_graceful_restart_preserve_fw_cmd,
-       "no bgp graceful-restart preserve-fw-state",
+       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);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD);
+       return CMD_SUCCESS;
+}
+
+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);
+
+       ret = bgp_gr_update_all(bgp, GLOBAL_DISABLE_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_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_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_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] no_bgp_graceful_restart_disable_cmd : START ");
+
+       int ret = BGP_GR_FAILURE;
+
+       ret = bgp_gr_update_all(bgp, NO_GLOBAL_DISABLE_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_disable_cmd : END ");
+       vty_out(vty,
+               "Graceful restart configuration changed, reset all peers to take effect\n");
+
+       return bgp_vty_return(vty, ret);
+}
+
+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
+      )
+{
+       int idx_peer = 1;
+       struct peer *peer;
+       int ret = BGP_GR_FAILURE;
+
+       VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] bgp_neighbor_graceful_restart_set_cmd : START ");
+
+       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_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] 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_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
+      )
+{
+       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_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 (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
+      )
+{
+       int idx_peer = 1;
+       struct peer *peer;
+       int ret = BGP_GR_FAILURE;
+
+       VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] bgp_neighbor_graceful_restart_helper_set_cmd : START ");
+
+       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_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] 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_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
+      )
+{
+       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);
+}
+
+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
+      )
+{
+       int idx_peer = 1;
+       struct peer *peer;
+       int ret = BGP_GR_FAILURE;
+
+       VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
+
+       if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+               zlog_debug(
+                       "[BGP_GR] bgp_neighbor_graceful_restart_disable_set_cmd : START ");
+
+       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_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
+      )
+{
+       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_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);
+}
+
+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);
+       SET_FLAG(bgp->flags, BGP_FLAG_GR_DISABLE_EOR);
+
+       return CMD_SUCCESS;
+}
+
+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);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_GR_DISABLE_EOR);
+
+       return CMD_SUCCESS;
+}
+
+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"
+       "Graceful restart configuration parameters\n"
+       "Specify the stale route removal timer in rib\n"
+       "Delay value (seconds)\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       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_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"
-       "Graceful restart capability parameters\n"
-       "Unsets F-bit indication that fib is preserved while doing Graceful Restart\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_GR_PRESERVE_FWD);
+
+       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;
 }
 
@@ -2215,8 +2714,8 @@ DEFUN (bgp_graceful_shutdown,
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
 
-       if (!bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
-               bgp_flag_set(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN);
+       if (!CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
+               SET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN);
                bgp_static_redo_import_check(bgp);
                bgp_redistribute_redo(bgp);
                bgp_clear_star_soft_out(vty, bgp->name);
@@ -2235,8 +2734,8 @@ DEFUN (no_bgp_graceful_shutdown,
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
 
-       if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
-               bgp_flag_unset(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN);
+       if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
+               UNSET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN);
                bgp_static_redo_import_check(bgp);
                bgp_redistribute_redo(bgp);
                bgp_clear_star_soft_out(vty, bgp->name);
@@ -2254,7 +2753,7 @@ DEFUN (bgp_fast_external_failover,
        "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);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER);
        return CMD_SUCCESS;
 }
 
@@ -2266,7 +2765,7 @@ DEFUN (no_bgp_fast_external_failover,
        "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);
+       SET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER);
        return CMD_SUCCESS;
 }
 
@@ -2279,7 +2778,7 @@ DEFUN (bgp_bestpath_compare_router_id,
        "Compare router-id for identical EBGP paths\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_COMPARE_ROUTER_ID);
+       SET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID);
        bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
@@ -2294,7 +2793,7 @@ DEFUN (no_bgp_bestpath_compare_router_id,
        "Compare router-id for identical EBGP paths\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_COMPARE_ROUTER_ID);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID);
        bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
@@ -2310,7 +2809,7 @@ DEFUN (bgp_bestpath_aspath_ignore,
        "Ignore as-path length in selecting a route\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_ASPATH_IGNORE);
+       SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE);
        bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
@@ -2326,7 +2825,7 @@ DEFUN (no_bgp_bestpath_aspath_ignore,
        "Ignore as-path length in selecting a route\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_ASPATH_IGNORE);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE);
        bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
@@ -2342,7 +2841,7 @@ DEFUN (bgp_bestpath_aspath_confed,
        "Compare path lengths including confederation sets & sequences in selecting a route\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_ASPATH_CONFED);
+       SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED);
        bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
@@ -2358,7 +2857,7 @@ DEFUN (no_bgp_bestpath_aspath_confed,
        "Compare path lengths including confederation sets & sequences in selecting a route\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_ASPATH_CONFED);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED);
        bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
@@ -2377,14 +2876,14 @@ DEFUN (bgp_bestpath_aspath_multipath_relax,
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx = 0;
-       bgp_flag_set(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
+       SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
 
        /* 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);
+               SET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
        else
-               bgp_flag_unset(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
+               UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
 
        bgp_recalculate_all_bestpaths(bgp);
 
@@ -2403,8 +2902,8 @@ DEFUN (no_bgp_bestpath_aspath_multipath_relax,
        "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);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
        bgp_recalculate_all_bestpaths(bgp);
 
        return CMD_SUCCESS;
@@ -2418,7 +2917,7 @@ DEFUN (bgp_log_neighbor_changes,
        "Log neighbor up/down and reset reason\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+       SET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
        return CMD_SUCCESS;
 }
 
@@ -2430,7 +2929,7 @@ DEFUN (no_bgp_log_neighbor_changes,
        "Log neighbor up/down and reset reason\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
        return CMD_SUCCESS;
 }
 
@@ -2450,10 +2949,10 @@ DEFUN (bgp_bestpath_med,
 
        int idx = 0;
        if (argv_find(argv, argc, "confed", &idx))
-               bgp_flag_set(bgp, BGP_FLAG_MED_CONFED);
+               SET_FLAG(bgp->flags, 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);
+               SET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST);
 
        bgp_recalculate_all_bestpaths(bgp);
 
@@ -2476,10 +2975,10 @@ DEFUN (no_bgp_bestpath_med,
 
        int idx = 0;
        if (argv_find(argv, argc, "confed", &idx))
-               bgp_flag_unset(bgp, BGP_FLAG_MED_CONFED);
+               UNSET_FLAG(bgp->flags, 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);
+               UNSET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST);
 
        bgp_recalculate_all_bestpaths(bgp);
 
@@ -2496,7 +2995,7 @@ DEFUN (no_bgp_default_ipv4_unicast,
        "Activate ipv4-unicast for a peer by default\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_NO_DEFAULT_IPV4);
+       SET_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4);
        return CMD_SUCCESS;
 }
 
@@ -2508,7 +3007,7 @@ DEFUN (bgp_default_ipv4_unicast,
        "Activate ipv4-unicast for a peer by default\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_NO_DEFAULT_IPV4);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4);
        return CMD_SUCCESS;
 }
 
@@ -2521,7 +3020,7 @@ DEFUN (bgp_default_show_hostname,
        "Show hostname in certain command outputs\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_SHOW_HOSTNAME);
+       SET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME);
        return CMD_SUCCESS;
 }
 
@@ -2534,7 +3033,7 @@ DEFUN (no_bgp_default_show_hostname,
        "Show hostname in certain command outputs\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_SHOW_HOSTNAME);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME);
        return CMD_SUCCESS;
 }
 
@@ -2547,8 +3046,8 @@ DEFUN (bgp_network_import_check,
        "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);
+       if (!CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)) {
+               SET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
                bgp_static_redo_import_check(bgp);
        }
 
@@ -2571,8 +3070,8 @@ DEFUN (no_bgp_network_import_check,
        "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);
+       if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)) {
+               UNSET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
                bgp_static_redo_import_check(bgp);
        }
 
@@ -2659,8 +3158,8 @@ DEFUN (bgp_rr_allow_outbound_policy,
 {
        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);
+       if (!CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
+               SET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
                update_group_announce_rrclients(bgp);
                bgp_clear_star_soft_out(vty, bgp->name);
        }
@@ -2678,8 +3177,8 @@ DEFUN (no_bgp_rr_allow_outbound_policy,
 {
        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);
+       if (CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
+               UNSET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
                update_group_announce_rrclients(bgp);
                bgp_clear_star_soft_out(vty, bgp->name);
        }
@@ -2906,7 +3405,7 @@ DEFUN (bgp_disable_connected_route_check,
        "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);
+       SET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
        bgp_clear_star_soft_in(vty, bgp->name);
 
        return CMD_SUCCESS;
@@ -2920,7 +3419,7 @@ DEFUN (no_bgp_disable_connected_route_check,
        "Disable checking if nexthop is connected on ebgp sessions\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
+       UNSET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
        bgp_clear_star_soft_in(vty, bgp->name);
 
        return CMD_SUCCESS;
@@ -3059,7 +3558,7 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if,
                        ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type,
                                             afi, safi);
        } else {
-               if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4)
+               if (CHECK_FLAG(bgp->flags, 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);
@@ -8014,14 +8513,14 @@ static void bgp_show_bestpath_json(struct bgp *bgp, json_object *json)
 {
        json_object *bestpath = json_object_new_object();
 
-       if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_IGNORE))
+       if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE))
                json_object_string_add(bestpath, "asPath", "ignore");
 
-       if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_CONFED))
+       if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED))
                json_object_string_add(bestpath, "asPath", "confed");
 
-       if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
-               if (bgp_flag_check(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET))
+       if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET))
                        json_object_string_add(bestpath, "multiPathRelax",
                                               "as-set");
                else
@@ -8030,13 +8529,13 @@ static void bgp_show_bestpath_json(struct bgp *bgp, json_object *json)
        } else
                json_object_string_add(bestpath, "multiPathRelax", "false");
 
-       if (bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID))
+       if (CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID))
                json_object_string_add(bestpath, "compareRouterId", "true");
-       if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED)
-           || bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) {
-               if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED))
+       if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED)
+           || CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST)) {
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED))
                        json_object_string_add(bestpath, "med", "confed");
-               if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST))
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
                        json_object_string_add(bestpath, "med",
                                               "missing-as-worst");
                else
@@ -8159,7 +8658,7 @@ static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp,
                dn_flag[1] = '\0';
                dn_flag[0] = peer_dynamic_neighbor(peer) ? '*' : '\0';
                if (peer->hostname
-                   && bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME))
+                   && CHECK_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME))
                        len = vty_out(vty, "%s%s(%s)", dn_flag,
                                      peer->hostname, peer->host);
                else
@@ -8242,8 +8741,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
                                        dn_flag[0] = '*';
 
                                if (peer->hostname
-                                   && bgp_flag_check(bgp,
-                                                     BGP_FLAG_SHOW_HOSTNAME))
+                                   && CHECK_FLAG(bgp->flags,
+                                                 BGP_FLAG_SHOW_HOSTNAME))
                                        sprintf(neighbor_buf, "%s%s(%s) ",
                                                dn_flag, peer->hostname,
                                                peer->host);
@@ -8604,9 +9103,11 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
                                }
 
                                if (peer->hostname
-                                   && bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME))
+                                   && CHECK_FLAG(bgp->flags,
+                                                 BGP_FLAG_SHOW_HOSTNAME))
                                        len = vty_out(vty, "%s%s(%s)", dn_flag,
-                                                     peer->hostname, peer->host);
+                                                     peer->hostname,
+                                                     peer->host);
                                else
                                        len = vty_out(vty, "%s%s", dn_flag, peer->host);
 
@@ -8882,8 +9383,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,
@@ -8948,12 +9447,398 @@ static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p,
        }
 }
 
-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)
+static void bgp_show_neighnor_graceful_restart_rbit(struct vty *vty,
+                                                   struct peer *p,
+                                                   bool use_json,
+                                                   json_object *json)
 {
-       struct bgp_filter *filter;
-       struct peer_af *paf;
+       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));
+               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)
+{
+       struct bgp_filter *filter;
+       struct peer_af *paf;
        char orf_pfx_name[BUFSIZ];
        int orf_pfx_count;
        json_object *json_af = NULL;
@@ -9262,7 +10147,8 @@ 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 {
@@ -10701,14 +11587,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;
@@ -10720,7 +11604,8 @@ 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)) {
@@ -10745,12 +11630,12 @@ 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);
 
+
                        if (p->t_gr_restart)
                                json_object_int_add(json_grace,
                                                    "gracefulRestartTimerMsecs",
@@ -10765,12 +11650,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],
@@ -10778,9 +11667,9 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                                vty_out(vty, "%s%s",
                                                        eor_send_af_count ? ", "
                                                                          : "",
-                                                       get_afi_safi_str(afi,
-                                                                        safi,
-                                                                        false));
+                                                       get_afi_safi_str(
+                                                               afi, safi,
+                                                               false));
                                                eor_send_af_count++;
                                        }
                                }
@@ -10814,8 +11703,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();
@@ -11229,6 +12121,82 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_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;
+       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;
+
+               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,
@@ -11334,6 +12302,42 @@ 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,
@@ -11471,6 +12475,50 @@ 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,
@@ -11609,8 +12657,66 @@ 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",
@@ -13437,6 +14543,29 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
        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. */
@@ -13476,8 +14605,8 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
        } else {
                if (peer->afc[afi][safi]) {
                        if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
-                               if (bgp_flag_check(bgp,
-                                                  BGP_FLAG_NO_DEFAULT_IPV4)) {
+                               if (CHECK_FLAG(bgp->flags,
+                                              BGP_FLAG_NO_DEFAULT_IPV4)) {
                                        vty_out(vty, "  neighbor %s activate\n",
                                                addr);
                                }
@@ -13485,8 +14614,8 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
                                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)) {
+                               if (!CHECK_FLAG(bgp->flags,
+                                               BGP_FLAG_NO_DEFAULT_IPV4)) {
                                        vty_out(vty,
                                                "  no neighbor %s activate\n",
                                                addr);
@@ -13847,16 +14976,16 @@ int bgp_config_write(struct vty *vty)
                                inet_ntoa(bgp->router_id_static));
 
                /* BGP log-neighbor-changes. */
-               if (!!bgp_flag_check(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)
+               if (!!CHECK_FLAG(bgp->flags, 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)
+                               CHECK_FLAG(bgp->flags,
+                                          BGP_FLAG_LOG_NEIGHBOR_CHANGES)
                                        ? ""
                                        : "no ");
 
                /* BGP configuration. */
-               if (bgp_flag_check(bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED))
                        vty_out(vty, " bgp always-compare-med\n");
 
                /* RFC8212 default eBGP policy. */
@@ -13869,7 +14998,7 @@ int bgp_config_write(struct vty *vty)
                        vty_out(vty, " bgp reject-as-sets\n");
 
                /* BGP default ipv4-unicast. */
-               if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4))
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4))
                        vty_out(vty, " no bgp default ipv4-unicast\n");
 
                /* BGP default local-preference. */
@@ -13878,10 +15007,10 @@ int bgp_config_write(struct vty *vty)
                                bgp->default_local_pref);
 
                /* BGP default show-hostname */
-               if (!!bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME)
+               if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME)
                    != SAVE_BGP_SHOW_HOSTNAME)
                        vty_out(vty, " %sbgp default show-hostname\n",
-                               bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME)
+                               CHECK_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME)
                                        ? ""
                                        : "no ");
 
@@ -13892,7 +15021,7 @@ int bgp_config_write(struct vty *vty)
                                bgp->default_subgroup_pkt_queue_max);
 
                /* BGP client-to-client reflection. */
-               if (bgp_flag_check(bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT))
                        vty_out(vty, " no bgp client-to-client reflection\n");
 
                /* BGP cluster ID. */
@@ -13901,7 +15030,7 @@ int bgp_config_write(struct vty *vty)
                                inet_ntoa(bgp->cluster_id));
 
                /* Disable ebgp connected nexthop check */
-               if (bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
                        vty_out(vty,
                                " bgp disable-ebgp-connected-route-check\n");
 
@@ -13923,10 +15052,11 @@ int bgp_config_write(struct vty *vty)
                }
 
                /* BGP deterministic-med. */
-               if (!!bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)
+               if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
                    != SAVE_BGP_DETERMINISTIC_MED)
                        vty_out(vty, " %sbgp deterministic-med\n",
-                               bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)
+                               CHECK_FLAG(bgp->flags,
+                                          BGP_FLAG_DETERMINISTIC_MED)
                                        ? ""
                                        : "no ");
 
@@ -13963,30 +15093,46 @@ int bgp_config_write(struct vty *vty)
                        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_flag_check(bgp, BGP_FLAG_GRACEFUL_RESTART))
+
+               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))
+               if (CHECK_FLAG(bgp->flags, 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))
+               if (CHECK_FLAG(bgp->flags, 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))
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE))
                        vty_out(vty, " bgp bestpath as-path ignore\n");
-               if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_CONFED))
+               if (CHECK_FLAG(bgp->flags, 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)) {
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
+                       if (CHECK_FLAG(bgp->flags,
+                                      BGP_FLAG_MULTIPATH_RELAX_AS_SET)) {
                                vty_out(vty,
                                        " bgp bestpath as-path multipath-relax as-set\n");
                        } else {
@@ -13995,27 +15141,28 @@ int bgp_config_write(struct vty *vty)
                        }
                }
 
-               if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
                        vty_out(vty,
                                " bgp route-reflector allow-outbound-policy\n");
                }
-               if (bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID))
+               if (CHECK_FLAG(bgp->flags, 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)) {
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED)
+                   || CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST)) {
                        vty_out(vty, " bgp bestpath med");
-                       if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED))
+                       if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED))
                                vty_out(vty, " confed");
-                       if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST))
+                       if (CHECK_FLAG(bgp->flags,
+                                      BGP_FLAG_MED_MISSING_AS_WORST))
                                vty_out(vty, " missing-as-worst");
                        vty_out(vty, "\n");
                }
 
                /* BGP network import check. */
-               if (!!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
+               if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
                    != SAVE_BGP_IMPORT_CHECK)
                        vty_out(vty, " %sbgp network import-check\n",
-                               bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
+                               CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
                                        ? ""
                                        : "no ");
 
@@ -14346,17 +15493,45 @@ 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 */
+       /* "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);
@@ -15351,6 +16526,8 @@ 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);
 
@@ -15512,21 +16689,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;
@@ -15535,8 +16720,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);
 
@@ -15551,13 +16736,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)
@@ -15566,9 +16753,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);
 
@@ -15587,7 +16779,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);
@@ -15610,22 +16802,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;
@@ -15634,8 +16834,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);
 
@@ -15650,24 +16850,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);
 
@@ -15686,7 +16893,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);
@@ -15813,7 +17020,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;
 
@@ -15837,7 +17050,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().  */
@@ -15857,7 +17070,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);
 
@@ -15881,7 +17100,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
@@ -15902,10 +17121,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)
@@ -15916,10 +17137,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")
@@ -15930,11 +17153,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)
@@ -15945,11 +17170,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")
@@ -15958,8 +17185,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
@@ -15972,6 +17199,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",
@@ -15987,11 +17227,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)
@@ -16002,11 +17244,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")
@@ -16017,12 +17261,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)
@@ -16033,12 +17279,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")
@@ -16133,12 +17381,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)
@@ -16146,18 +17396,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);
@@ -16172,12 +17428,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")
@@ -16185,17 +17443,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);
@@ -16210,13 +17474,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)
@@ -16225,11 +17491,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
@@ -16246,7 +17517,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);
 
@@ -16268,13 +17539,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")
@@ -16283,8 +17556,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);
 
@@ -16304,7 +17583,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);
 
@@ -16415,18 +17694,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++;
                }
@@ -16436,18 +17719,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++;
                }
@@ -16459,18 +17747,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++;
                }
@@ -16513,7 +17807,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);