mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 16:20:08 +00:00
bgpd: Implement BGP-wide configuration for graceful shutdown
Add support for a BGP-wide setting to enter and exit graceful shutdown. This will apply to all BGP peers across all BGP instances. Per-instance configuration is disallowed if the BGP-wide setting is in effect. Signed-off-by: Vivek Venkatraman <vivek@nvidia.com>
This commit is contained in:
parent
637e5ba492
commit
05bd726cfe
113
bgpd/bgp_vty.c
113
bgpd/bgp_vty.c
@ -2805,6 +2805,69 @@ DEFUN (no_bgp_graceful_restart_rib_stale_time,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void bgp_initiate_graceful_shut_unshut(struct vty *vty,
|
||||||
|
struct bgp *bgp)
|
||||||
|
{
|
||||||
|
bgp_static_redo_import_check(bgp);
|
||||||
|
bgp_redistribute_redo(bgp);
|
||||||
|
bgp_clear_star_soft_out(vty, bgp->name);
|
||||||
|
bgp_clear_star_soft_in(vty, bgp->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bgp_global_graceful_shutdown_config_vty(struct vty *vty)
|
||||||
|
{
|
||||||
|
struct listnode *node, *nnode;
|
||||||
|
struct bgp *bgp;
|
||||||
|
bool vrf_cfg = false;
|
||||||
|
|
||||||
|
if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN))
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
|
/* See if graceful-shutdown is set per-vrf and warn user to delete */
|
||||||
|
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
|
||||||
|
if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
|
||||||
|
vty_out(vty,
|
||||||
|
"%% graceful-shutdown configuration found in vrf %s\n",
|
||||||
|
bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ?
|
||||||
|
VRF_DEFAULT_NAME : bgp->name);
|
||||||
|
vrf_cfg = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vrf_cfg) {
|
||||||
|
vty_out(vty,
|
||||||
|
"%%Failed: global graceful-shutdown not permitted\n");
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set flag globally */
|
||||||
|
SET_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN);
|
||||||
|
|
||||||
|
/* Initiate processing for all BGP instances. */
|
||||||
|
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
|
||||||
|
bgp_initiate_graceful_shut_unshut(vty, bgp);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bgp_global_graceful_shutdown_deconfig_vty(struct vty *vty)
|
||||||
|
{
|
||||||
|
struct listnode *node, *nnode;
|
||||||
|
struct bgp *bgp;
|
||||||
|
|
||||||
|
if (!CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN))
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
|
/* Unset flag globally */
|
||||||
|
UNSET_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN);
|
||||||
|
|
||||||
|
/* Initiate processing for all BGP instances. */
|
||||||
|
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
|
||||||
|
bgp_initiate_graceful_shut_unshut(vty, bgp);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* "bgp graceful-shutdown" configuration */
|
/* "bgp graceful-shutdown" configuration */
|
||||||
DEFUN (bgp_graceful_shutdown,
|
DEFUN (bgp_graceful_shutdown,
|
||||||
bgp_graceful_shutdown_cmd,
|
bgp_graceful_shutdown_cmd,
|
||||||
@ -2812,14 +2875,21 @@ DEFUN (bgp_graceful_shutdown,
|
|||||||
BGP_STR
|
BGP_STR
|
||||||
"Graceful shutdown parameters\n")
|
"Graceful shutdown parameters\n")
|
||||||
{
|
{
|
||||||
|
if (vty->node == CONFIG_NODE)
|
||||||
|
return bgp_global_graceful_shutdown_config_vty(vty);
|
||||||
|
|
||||||
VTY_DECLVAR_CONTEXT(bgp, bgp);
|
VTY_DECLVAR_CONTEXT(bgp, bgp);
|
||||||
|
|
||||||
|
/* if configured globally, per-instance config is not allowed */
|
||||||
|
if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) {
|
||||||
|
vty_out(vty,
|
||||||
|
"%%Failed: per-vrf graceful-shutdown config not permitted with global graceful-shutdown\n");
|
||||||
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if (!CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
|
if (!CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
|
||||||
SET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN);
|
SET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN);
|
||||||
bgp_static_redo_import_check(bgp);
|
bgp_initiate_graceful_shut_unshut(vty, bgp);
|
||||||
bgp_redistribute_redo(bgp);
|
|
||||||
bgp_clear_star_soft_out(vty, bgp->name);
|
|
||||||
bgp_clear_star_soft_in(vty, bgp->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -2832,14 +2902,21 @@ DEFUN (no_bgp_graceful_shutdown,
|
|||||||
BGP_STR
|
BGP_STR
|
||||||
"Graceful shutdown parameters\n")
|
"Graceful shutdown parameters\n")
|
||||||
{
|
{
|
||||||
|
if (vty->node == CONFIG_NODE)
|
||||||
|
return bgp_global_graceful_shutdown_deconfig_vty(vty);
|
||||||
|
|
||||||
VTY_DECLVAR_CONTEXT(bgp, bgp);
|
VTY_DECLVAR_CONTEXT(bgp, bgp);
|
||||||
|
|
||||||
|
/* If configured globally, cannot remove from one bgp instance */
|
||||||
|
if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) {
|
||||||
|
vty_out(vty,
|
||||||
|
"%%Failed: bgp graceful-shutdown configured globally. Delete per-vrf not permitted\n");
|
||||||
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
|
if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
|
||||||
UNSET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN);
|
UNSET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN);
|
||||||
bgp_static_redo_import_check(bgp);
|
bgp_initiate_graceful_shut_unshut(vty, bgp);
|
||||||
bgp_redistribute_redo(bgp);
|
|
||||||
bgp_clear_star_soft_out(vty, bgp->name);
|
|
||||||
bgp_clear_star_soft_in(vty, bgp->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -6386,7 +6463,6 @@ DEFUN (no_bgp_set_route_map_delay_timer,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* neighbor interface */
|
/* neighbor interface */
|
||||||
static int peer_interface_vty(struct vty *vty, const char *ip_str,
|
static int peer_interface_vty(struct vty *vty, const char *ip_str,
|
||||||
const char *str)
|
const char *str)
|
||||||
@ -15528,6 +15604,9 @@ int bgp_config_write(struct vty *vty)
|
|||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN))
|
||||||
|
vty_out(vty, "bgp graceful-shutdown\n");
|
||||||
|
|
||||||
/* BGP configuration. */
|
/* BGP configuration. */
|
||||||
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
|
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
|
||||||
|
|
||||||
@ -15679,6 +15758,14 @@ int bgp_config_write(struct vty *vty)
|
|||||||
/* coalesce time */
|
/* coalesce time */
|
||||||
bgp_config_write_coalesce_time(vty, bgp);
|
bgp_config_write_coalesce_time(vty, bgp);
|
||||||
|
|
||||||
|
/* BGP per-instance graceful-shutdown */
|
||||||
|
/* BGP-wide settings and per-instance settings are mutually
|
||||||
|
* exclusive.
|
||||||
|
*/
|
||||||
|
if (!CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN))
|
||||||
|
if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN))
|
||||||
|
vty_out(vty, " bgp graceful-shutdown\n");
|
||||||
|
|
||||||
/* BGP graceful-restart. */
|
/* BGP graceful-restart. */
|
||||||
if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
|
if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
@ -15700,10 +15787,6 @@ int bgp_config_write(struct vty *vty)
|
|||||||
if (bgp_global_gr_mode_get(bgp) == GLOBAL_DISABLE)
|
if (bgp_global_gr_mode_get(bgp) == GLOBAL_DISABLE)
|
||||||
vty_out(vty, " bgp graceful-restart-disable\n");
|
vty_out(vty, " bgp graceful-restart-disable\n");
|
||||||
|
|
||||||
/* BGP 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. */
|
/* BGP graceful-restart Preserve State F bit. */
|
||||||
if (CHECK_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD))
|
if (CHECK_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD))
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
@ -16046,6 +16129,10 @@ void bgp_vty_init(void)
|
|||||||
install_element(CONFIG_NODE, &bgp_global_update_delay_cmd);
|
install_element(CONFIG_NODE, &bgp_global_update_delay_cmd);
|
||||||
install_element(CONFIG_NODE, &no_bgp_global_update_delay_cmd);
|
install_element(CONFIG_NODE, &no_bgp_global_update_delay_cmd);
|
||||||
|
|
||||||
|
/* global bgp graceful-shutdown command */
|
||||||
|
install_element(CONFIG_NODE, &bgp_graceful_shutdown_cmd);
|
||||||
|
install_element(CONFIG_NODE, &no_bgp_graceful_shutdown_cmd);
|
||||||
|
|
||||||
/* Dummy commands (Currently not supported) */
|
/* Dummy commands (Currently not supported) */
|
||||||
install_element(BGP_NODE, &no_synchronization_cmd);
|
install_element(BGP_NODE, &no_synchronization_cmd);
|
||||||
install_element(BGP_NODE, &no_auto_summary_cmd);
|
install_element(BGP_NODE, &no_auto_summary_cmd);
|
||||||
|
@ -173,6 +173,9 @@ struct bgp_master {
|
|||||||
uint16_t v_update_delay;
|
uint16_t v_update_delay;
|
||||||
uint16_t v_establish_wait;
|
uint16_t v_establish_wait;
|
||||||
|
|
||||||
|
uint32_t flags;
|
||||||
|
#define BM_FLAG_GRACEFUL_SHUTDOWN (1 << 0)
|
||||||
|
|
||||||
bool terminating; /* global flag that sigint terminate seen */
|
bool terminating; /* global flag that sigint terminate seen */
|
||||||
QOBJ_FIELDS
|
QOBJ_FIELDS
|
||||||
};
|
};
|
||||||
@ -2159,7 +2162,9 @@ static inline void bgp_vrf_unlink(struct bgp *bgp, struct vrf *vrf)
|
|||||||
|
|
||||||
static inline bool bgp_in_graceful_shutdown(struct bgp *bgp)
|
static inline bool bgp_in_graceful_shutdown(struct bgp *bgp)
|
||||||
{
|
{
|
||||||
return !!CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN);
|
/* True if either set for this instance or globally */
|
||||||
|
return (!!CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN) ||
|
||||||
|
!!CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void bgp_unset_redist_vrf_bitmaps(struct bgp *, vrf_id_t);
|
extern void bgp_unset_redist_vrf_bitmaps(struct bgp *, vrf_id_t);
|
||||||
|
@ -2732,6 +2732,32 @@ The following are available in the ``router bgp`` mode:
|
|||||||
at a time in a loop. This setting controls how many iterations the loop runs
|
at a time in a loop. This setting controls how many iterations the loop runs
|
||||||
for. As with write-quanta, it is best to leave this setting on the default.
|
for. As with write-quanta, it is best to leave this setting on the default.
|
||||||
|
|
||||||
|
The following command is available in ``config`` mode as well as in the
|
||||||
|
``router bgp`` mode:
|
||||||
|
|
||||||
|
.. index:: bgp graceful-shutdown
|
||||||
|
.. clicmd:: bgp graceful-shutdown
|
||||||
|
|
||||||
|
The purpose of this command is to initiate BGP Graceful Shutdown which
|
||||||
|
is described in :rfc:`8326`. The use case for this is to minimize or
|
||||||
|
eliminate the amount of traffic loss in a network when a planned
|
||||||
|
maintenance activity such as software upgrade or hardware replacement
|
||||||
|
is to be performed on a router. The feature works by re-announcing
|
||||||
|
routes to eBGP peers with the GRACEFUL_SHUTDOWN community included.
|
||||||
|
Peers are then expected to treat such paths with the lowest preference.
|
||||||
|
This happens automatically on a receiver running FRR; with other
|
||||||
|
routing protocol stacks, an inbound policy may have to be configured.
|
||||||
|
In FRR, triggering graceful shutdown also results in announcing a
|
||||||
|
LOCAL_PREF of 0 to iBGP peers.
|
||||||
|
|
||||||
|
Graceful shutdown can be configured per BGP instance or globally for
|
||||||
|
all of BGP. These two options are mutually exclusive. The no form of
|
||||||
|
the command causes graceful shutdown to be stopped, and routes will
|
||||||
|
be re-announced without the GRACEFUL_SHUTDOWN community and/or with
|
||||||
|
the usual LOCAL_PREF value. Note that if this option is saved to
|
||||||
|
the startup configuration, graceful shutdown will remain in effect
|
||||||
|
across restarts of *bgpd* and will need to be explicitly disabled.
|
||||||
|
|
||||||
.. _bgp-displaying-bgp-information:
|
.. _bgp-displaying-bgp-information:
|
||||||
|
|
||||||
Displaying BGP Information
|
Displaying BGP Information
|
||||||
|
Loading…
Reference in New Issue
Block a user