From cfd47646b35b07da30218597ed21d4ee7e5985ea Mon Sep 17 00:00:00 2001 From: bisdhdh Date: Wed, 23 Oct 2019 23:15:57 +0530 Subject: [PATCH] bgpd: Adding changes for Selection Deferral Timer config cmd and DS. * Added config commands and data structures for deferral timer configuration and processing. Cmd : bgp graceful-restart select-defer-time (0-3600) Cmd : no bgp graceful-restart select-defertime (0-3600) Signed-off-by: Biswajit Sadhu Signed-off-by: Soman K S --- bgpd/bgp_vty.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++-- bgpd/bgpd.c | 22 +++++++++++++++ bgpd/bgpd.h | 16 +++++++++-- 3 files changed, 109 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 1038e79b33..2ccc9cfda9 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -2214,6 +2214,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)]", @@ -2244,6 +2266,23 @@ 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", @@ -14379,6 +14418,27 @@ 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. */ @@ -14905,12 +14965,22 @@ 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)) vty_out(vty, " bgp graceful-shutdown\n"); @@ -15322,7 +15392,8 @@ void bgp_vty_init(void) 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 1a89fbec5d..fae91655ab 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3017,6 +3017,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; @@ -3026,6 +3032,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp_timers_unset(bgp); 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; @@ -3351,7 +3358,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); @@ -3365,6 +3374,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"); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 57b01af9ac..d1b154f929 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -407,7 +407,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; @@ -508,7 +508,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; @@ -635,6 +636,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) \ @@ -642,6 +650,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. */ @@ -1553,6 +1564,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 -- 2.39.5