From bf2986de6b8deae587ffa1e8f9d62890c00f58f2 Mon Sep 17 00:00:00 2001 From: bisdhdh Date: Tue, 22 Oct 2019 22:29:23 +0530 Subject: [PATCH] bgpd : Adding changes for Selection Deferral Time. * Selection Deferral Timer for Graceful Retsart. * Added CLI commands and data structures for deferral timer configuration and processing. Signed-off-by: Biswajit Sadhu --- bgpd/bgp_vty.c | 55 +++++++++++++++++++++++++++++++++++++++++++++----- bgpd/bgpd.c | 27 +++++++++++++++++++++++++ bgpd/bgpd.h | 17 +++++++++++++--- 3 files changed, 91 insertions(+), 8 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index fa61332e9736..1896f8f14734 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -2109,6 +2109,28 @@ DEFUN (bgp_graceful_restart_restart_time, return CMD_SUCCESS; } +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 time to defer the BGP route selection after restart\n" + "Delay value (seconds, 0 - disable)\n") +{ + VTY_DECLVAR_CONTEXT(bgp, bgp); + int idx_number = 3; + uint32_t defer_time; + + defer_time = strtoul(argv[idx_number]->arg, NULL, 10); + bgp->select_defer_time = defer_time; + if (defer_time == 0) + bgp_flag_set(bgp, BGP_FLAG_SELECT_DEFER_DISABLE); + else + bgp_flag_unset(bgp, BGP_FLAG_SELECT_DEFER_DISABLE); + + return CMD_SUCCESS; +} + DEFUN (no_bgp_graceful_restart_stalepath_time, no_bgp_graceful_restart_stalepath_time_cmd, "no bgp graceful-restart stalepath-time [(1-4095)]", @@ -2139,6 +2161,22 @@ DEFUN (no_bgp_graceful_restart_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 defer the BGP route selection after restart\n" + "Delay value (seconds)\n") +{ + VTY_DECLVAR_CONTEXT(bgp, bgp); + + bgp->select_defer_time = BGP_DEFAULT_SELECT_DEFERRAL_TIME; + bgp_flag_unset(bgp, BGP_FLAG_SELECT_DEFER_DISABLE); + return CMD_SUCCESS; +} + DEFUN (bgp_graceful_restart_preserve_fw, bgp_graceful_restart_preserve_fw_cmd, "bgp graceful-restart preserve-fw-state", @@ -14090,11 +14128,18 @@ void bgp_vty_init(void) 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_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); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index dbb092ad4f39..47cfbffa76bc 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3067,6 +3067,12 @@ static struct bgp *bgp_create(as_t *as, const char *name, multipath_num, 0); bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_IBGP, multipath_num, 0); + /* Initialize graceful restart info */ + bgp->gr_info[afi][safi].eor_required = 0; + bgp->gr_info[afi][safi].eor_received = 0; + bgp->gr_info[afi][safi].t_select_deferral = NULL; + bgp->gr_info[afi][safi].t_route_select = NULL; + bgp->gr_info[afi][safi].route_list = list_new(); } bgp->v_update_delay = BGP_UPDATE_DELAY_DEF; @@ -3077,6 +3083,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE; bgp->restart_time = BGP_DEFAULT_RESTART_TIME; bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME; + bgp->select_defer_time = BGP_DEFAULT_SELECT_DEFERRAL_TIME; bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT; bgp->dynamic_neighbors_count = 0; bgp->ebgp_requires_policy = DEFAULT_EBGP_POLICY_DISABLED; @@ -3413,7 +3420,9 @@ int bgp_delete(struct bgp *bgp) struct listnode *node, *next; struct vrf *vrf; afi_t afi; + safi_t safi; int i; + struct graceful_restart_info *gr_info; assert(bgp); @@ -3427,6 +3436,19 @@ int bgp_delete(struct bgp *bgp) /* Set flag indicating bgp instance delete in progress */ bgp_flag_set(bgp, BGP_FLAG_DELETE_IN_PROGRESS); + /* Delete the graceful restart info */ + FOREACH_AFI_SAFI (afi, safi) { + gr_info = &bgp->gr_info[afi][safi]; + if (gr_info) { + BGP_TIMER_OFF(gr_info->t_select_deferral); + gr_info->t_select_deferral = NULL; + BGP_TIMER_OFF(gr_info->t_route_select); + gr_info->t_route_select = NULL; + if (gr_info->route_list) + list_delete(&gr_info->route_list); + } + } + if (BGP_DEBUG(zebra, ZEBRA)) { if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) zlog_debug("Deleting Default VRF"); @@ -7830,6 +7852,11 @@ int bgp_config_write(struct vty *vty) vty_out(vty, " bgp graceful-restart restart-time %u\n", bgp->restart_time); + if (bgp->select_defer_time != BGP_DEFAULT_SELECT_DEFERRAL_TIME) + vty_out(vty, + " bgp graceful-restart select-defer-time %u\n", + bgp->select_defer_time); + if (bgp_global_gr_mode_get(bgp) == GLOBAL_GR) vty_out(vty, " bgp graceful-restart\n"); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 41927fc184de..5ca25ad165dd 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -253,7 +253,6 @@ struct graceful_restart_info { struct thread *t_route_select; }; - enum global_mode { GLOBAL_HELPER = 0, /* This is the default mode */ GLOBAL_GR, @@ -410,7 +409,7 @@ struct bgp { #define BGP_FLAG_GR_PRESERVE_FWD (1 << 20) #define BGP_FLAG_GRACEFUL_SHUTDOWN (1 << 21) #define BGP_FLAG_DELETE_IN_PROGRESS (1 << 22) - +#define BGP_FLAG_SELECT_DEFER_DISABLE (1 << 23) enum global_mode GLOBAL_GR_FSM[GLOBAL_MODE][EVENT_CMD]; enum global_mode global_gr_present_state; @@ -510,7 +509,8 @@ struct bgp { uint32_t stalepath_time; uint32_t select_defer_time; struct graceful_restart_info gr_info[AFI_MAX][SAFI_MAX]; - +#define BGP_ROUTE_SELECT_DELAY 1 +#define BGP_MAX_BEST_ROUTE_SELECT 10000 /* Maximum-paths configuration */ struct bgp_maxpaths_cfg { uint16_t maxpaths_ebgp; @@ -630,6 +630,13 @@ DECLARE_HOOK(bgp_inst_config_write, (struct bgp *bgp, struct vty *vty), (bgp, vty)) +/* Thread callback information */ +struct afi_safi_info { + afi_t afi; + safi_t safi; + struct bgp *bgp; +}; + #define BGP_ROUTE_ADV_HOLD(bgp) (bgp->main_peers_update_hold) #define IS_BGP_INST_KNOWN_TO_ZEBRA(bgp) \ @@ -637,6 +644,9 @@ DECLARE_HOOK(bgp_inst_config_write, || (bgp->inst_type == BGP_INSTANCE_TYPE_VRF \ && bgp->vrf_id != VRF_UNKNOWN)) +#define BGP_SELECT_DEFER_DISABLE(bgp) \ + (bgp_flag_check(bgp, BGP_FLAG_SELECT_DEFER_DISABLE)) + /* BGP peer-group support. */ struct peer_group { /* Name of the peer-group. */ @@ -1540,6 +1550,7 @@ struct bgp_nlri { /* BGP graceful restart */ #define BGP_DEFAULT_RESTART_TIME 120 #define BGP_DEFAULT_STALEPATH_TIME 360 +#define BGP_DEFAULT_SELECT_DEFERRAL_TIME 360 /* BGP uptime string length. */ #define BGP_UPTIME_LEN 25