From f852eb98339fb3aacc52195bf5331c7b158557cc Mon Sep 17 00:00:00 2001 From: Prerana-GB Date: Fri, 6 Aug 2021 15:17:04 +0000 Subject: [PATCH] bgpd: BGP knob to teardown session immediately when peer is unreachable When BGP is notified by RIB that peer address is unreachable then BGP session must be brought down immediately and not wait for the hold-timer expiry. Today single-hop EBGP already behaves this way but need to change for iBGP and multi-hop EBGP sessions. Signed-off-by: Prerana G.B , Pushpasis Sarkar --- bgpd/bgp_fsm.c | 3 ++- bgpd/bgp_vty.c | 29 +++++++++++++++++++++++++++++ bgpd/bgpd.c | 2 +- bgpd/bgpd.h | 2 ++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index b62a42a4f6..0f2926d060 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -2196,7 +2196,8 @@ void bgp_fsm_nht_update(struct peer *peer, bool has_valid_nexthops) case OpenConfirm: case Established: if (!has_valid_nexthops - && (peer->gtsm_hops == BGP_GTSM_HOPS_CONNECTED)) + && (peer->gtsm_hops == BGP_GTSM_HOPS_CONNECTED + || peer->bgp->fast_convergence)) BGP_EVENT_ADD(peer, TCP_fatal_error); case Clearing: case Deleted: diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 63b2fbd4e6..ebd6e92d9b 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -4158,6 +4158,28 @@ DEFUN (neighbor_remote_as, return peer_remote_as_vty(vty, argv[idx_peer]->arg, argv[idx_remote_as]->arg); } +/* Enable fast convergence of bgp sessions. If this is enabled, bgp + * sessions do not wait for hold timer expiry to bring down the sessions + * when nexthop becomes unreachable + */ +DEFUN(bgp_fast_convergence, bgp_fast_convergence_cmd, "bgp fast-convergence", + BGP_STR "Fast convergence for bgp sessions\n") +{ + VTY_DECLVAR_CONTEXT(bgp, bgp); + bgp->fast_convergence = true; + + return CMD_SUCCESS; +} + +DEFUN(no_bgp_fast_convergence, no_bgp_fast_convergence_cmd, + "no bgp fast-convergence", + NO_STR BGP_STR "Fast convergence for bgp sessions\n") +{ + VTY_DECLVAR_CONTEXT(bgp, bgp); + bgp->fast_convergence = false; + + return CMD_SUCCESS; +} static int peer_conf_interface_get(struct vty *vty, const char *conf_if, int v6only, @@ -17147,6 +17169,9 @@ int bgp_config_write(struct vty *vty) if (CHECK_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN)) vty_out(vty, " bgp shutdown\n"); + if (bgp->fast_convergence) + vty_out(vty, " bgp fast-convergence\n"); + if (bgp->srv6_enabled) { vty_frame(vty, " !\n segment-routing srv6\n"); if (strlen(bgp->srv6_locator_name)) @@ -17410,6 +17435,10 @@ void bgp_vty_init(void) install_element(CONFIG_NODE, &bgp_set_route_map_delay_timer_cmd); install_element(CONFIG_NODE, &no_bgp_set_route_map_delay_timer_cmd); + /* bgp fast-convergence command */ + install_element(BGP_NODE, &bgp_fast_convergence_cmd); + install_element(BGP_NODE, &no_bgp_fast_convergence_cmd); + /* global bgp update-delay command */ install_element(CONFIG_NODE, &bgp_global_update_delay_cmd); install_element(CONFIG_NODE, &no_bgp_global_update_delay_cmd); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 591fc1214c..1c558cc550 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3165,7 +3165,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->reject_as_sets = false; bgp->condition_check_period = DEFAULT_CONDITIONAL_ROUTES_POLL_TIME; bgp_addpath_init_bgp_data(&bgp->tx_addpath); - + bgp->fast_convergence = false; bgp->as = *as; #ifdef ENABLE_BGP_VNC diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 867062a88b..ed7642f315 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -746,6 +746,8 @@ struct bgp { /* Process Queue for handling routes */ struct work_queue *process_queue; + bool fast_convergence; + /* BGP Conditional advertisement */ uint32_t condition_check_period; uint32_t condition_filter_count;