Skip to content

Commit 4b68712

Browse files
author
Vijayalaxmi Basavaraj
committed
bgpd:send EOR during GR only when fib install comeplete for suppress fib enabled
Currently during GR, EOR is sent to neighbor prematurely for suppress fib enabled case. below fix has be implemented. keep a counter to track the routes installed in FIB.Increamnet counter when bgp send route install to zebra, decreamnet counter when fib install ack to received from zebra in bgp.when this count reaches zero and route deferred count is 0 ad gr route syn pending is set, then do further processing of sending EOR and zebra gr update complete. This will send EOR as soon as last route fib install ack is received. Testing: before: 2020:2025/08/19 21:23:53.786402 BGP: [ZP3RE-J4Q8C] send End-of-RIB for IPv4 Unicast to swp1s1.3 2021:2025/08/19 21:23:53.786412 BGP: [ZP3RE-J4Q8C] send End-of-RIB for IPv6 Unicast to swp1s0.3 2022:2025/08/19 21:23:53.786415 BGP: [ZP3RE-J4Q8C] send End-of-RIB for IPv4 Unicast to swp1s0.3 2511:2025/08/19 21:23:54.162310 BGP: [TN0HX-6G1RR] u1:s5 send UPDATE w/ attr: , origin ?, mp_nexthop ::(::), path 64900 56000 2512:2025/08/19 21:23:54.162314 BGP: [H06SA-0JAPR] u1:s5 send MP_REACH for afi/safi IPv4/unicast 2513:2025/08/19 21:23:54.162316 BGP: [HVRWP-5R9NQ] u1:s5 send UPDATE 91.0.0.49/32 IPv4 unicast after: 4270:2025/08/22 17:41:41.631993 BGP: [HVRWP-5R9NQ] u2:s2 send UPDATE 2003:1::/125 IPv6 unicast 4271:2025/08/22 17:41:41.631998 BGP: [HVRWP-5R9NQ] u2:s2 send UPDATE 2003:7:2::/125 IPv6 unicast 4272:2025/08/22 17:41:41.632003 BGP: [WEV7K-2GAQ5] u2:s2 send UPDATE len 116 (max message len: 65535) numpfx 2 4273:2025/08/22 17:41:41.632008 BGP: [JJ5V1-EZ0XX] u2:s2 swp1s1 send UPDATE w/ mp_nexthops 2003:0:1::1, fe80::1e34:daff:febe:4169 4274:2025/08/22 17:41:41.632041 BGP: [ZP3RE-J4Q8C] send End-of-RIB for IPv4 Unicast to swp1s1 4275:2025/08/22 17:41:41.632054 BGP: [ZP3RE-J4Q8C] send End-of-RIB for IPv6 Unicast to swp1s1 Signed-off-by: Vijayalaxmi Basavaraj <[email protected]>
1 parent aeb7e61 commit 4b68712

File tree

17 files changed

+3222
-33
lines changed

17 files changed

+3222
-33
lines changed

bgpd/bgp_fsm.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ static void bgp_connect_timer(struct event *event);
8484
static void bgp_holdtime_timer(struct event *event);
8585
static void bgp_delayopen_timer(struct event *event);
8686

87+
/* BGP GR functions. */
88+
static bool bgp_gr_check_all_eors(struct bgp *bgp, afi_t afi, safi_t safi);
89+
8790
/* Register peer with NHT */
8891
int bgp_peer_reg_with_nht(struct peer *peer)
8992
{
@@ -857,6 +860,16 @@ static void bgp_graceful_deferral_timer_expire(struct event *thread)
857860
bgp->gr_info[afi][safi].select_defer_over = true;
858861
XFREE(MTYPE_TMP, info);
859862

863+
/* Check if graceful restart deferral completion is needed */
864+
if (BGP_SUPPRESS_FIB_ENABLED(bgp) && bgp_gr_check_all_eors(bgp, afi, safi) &&
865+
!bgp->gr_info[afi][safi].gr_deferred && bgp->gr_route_sync_pending) {
866+
if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
867+
zlog_debug("%s: Triggering GR deferral completion from timer expiry for %s",
868+
bgp->name_pretty, get_afi_safi_str(afi, safi, false));
869+
bgp_process_gr_deferral_complete(bgp, afi, safi);
870+
return;
871+
}
872+
860873
/* Best path selection */
861874
bgp_do_deferred_path_selection(bgp, afi, safi);
862875
}
@@ -1278,12 +1291,14 @@ void bgp_gr_check_path_select(struct bgp *bgp, afi_t afi, safi_t safi)
12781291

12791292
if (bgp_gr_check_all_eors(bgp, afi, safi)) {
12801293
gr_info = &(bgp->gr_info[afi][safi]);
1281-
if (gr_info->t_select_deferral) {
1282-
void *info = EVENT_ARG(gr_info->t_select_deferral);
1294+
if (!BGP_SUPPRESS_FIB_ENABLED(bgp)) {
1295+
if (gr_info->t_select_deferral) {
1296+
void *info = EVENT_ARG(gr_info->t_select_deferral);
12831297

1284-
XFREE(MTYPE_TMP, info);
1298+
XFREE(MTYPE_TMP, info);
1299+
}
1300+
event_cancel(&gr_info->t_select_deferral);
12851301
}
1286-
event_cancel(&gr_info->t_select_deferral);
12871302
gr_info->select_defer_over = true;
12881303
bgp_do_deferred_path_selection(bgp, afi, safi);
12891304
}

bgpd/bgp_route.c

Lines changed: 99 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3928,6 +3928,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
39283928
* Ensure that on uninstall that the INSTALL_PENDING
39293929
* is no longer set
39303930
*/
3931+
bgp_dest_decrement_gr_fib_install_count(dest);
39313932
UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
39323933
}
39333934

@@ -3996,6 +3997,100 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
39963997
return;
39973998
}
39983999

4000+
void bgp_process_gr_deferral_complete(struct bgp *bgp, afi_t afi, safi_t safi)
4001+
{
4002+
bool route_sync_pending = false;
4003+
4004+
bgp_send_delayed_eor(bgp);
4005+
/* Send route processing complete message to RIB */
4006+
bgp_zebra_update(bgp, afi, safi, ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
4007+
bgp->gr_info[afi][safi].route_sync = true;
4008+
4009+
/* If this instance is all done, check for GR completion overall */
4010+
FOREACH_AFI_SAFI_NSF (afi, safi) {
4011+
if (bgp->gr_info[afi][safi].af_enabled && !bgp->gr_info[afi][safi].route_sync) {
4012+
route_sync_pending = true;
4013+
break;
4014+
}
4015+
}
4016+
4017+
if (!route_sync_pending) {
4018+
bgp->gr_route_sync_pending = false;
4019+
bgp_update_gr_completion();
4020+
}
4021+
}
4022+
4023+
/* This function increments gr_route_fib_install_cnt if needed based on BGP_NODE_FIB_INSTALL_PENDING flag */
4024+
void bgp_dest_increment_gr_fib_install_count(struct bgp_dest *dest)
4025+
{
4026+
struct bgp_table *table = NULL;
4027+
struct bgp *bgp = NULL;
4028+
afi_t afi = 0;
4029+
safi_t safi = 0;
4030+
4031+
table = bgp_dest_table(dest);
4032+
if (!table)
4033+
return;
4034+
4035+
bgp = table->bgp;
4036+
afi = table->afi;
4037+
safi = table->safi;
4038+
4039+
if (BGP_SUPPRESS_FIB_ENABLED(bgp) && bgp->gr_route_sync_pending &&
4040+
!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING)) {
4041+
bgp->gr_info[afi][safi].gr_route_fib_install_cnt++;
4042+
if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
4043+
zlog_debug("%s: GR route FIB install count incremented to %u for %s (prefix: %pBD)",
4044+
bgp->name_pretty,
4045+
bgp->gr_info[afi][safi].gr_route_fib_install_cnt,
4046+
get_afi_safi_str(afi, safi, false), dest);
4047+
}
4048+
}
4049+
4050+
/* This function decrements gr_route_fib_install_cnt if needed based on BGP_NODE_FIB_INSTALL_PENDING flag */
4051+
void bgp_dest_decrement_gr_fib_install_count(struct bgp_dest *dest)
4052+
{
4053+
struct bgp_table *table = NULL;
4054+
struct bgp *bgp = NULL;
4055+
afi_t afi = 0;
4056+
safi_t safi = 0;
4057+
4058+
table = bgp_dest_table(dest);
4059+
if (!table)
4060+
return;
4061+
4062+
bgp = table->bgp;
4063+
afi = table->afi;
4064+
safi = table->safi;
4065+
4066+
if (BGP_SUPPRESS_FIB_ENABLED(bgp) && bgp->gr_route_sync_pending &&
4067+
CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING) &&
4068+
bgp->gr_info[afi][safi].gr_route_fib_install_cnt > 0) {
4069+
bgp->gr_info[afi][safi].gr_route_fib_install_cnt--;
4070+
if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
4071+
zlog_debug("%s: GR route FIB install count decremented to %u for %s (prefix: %pBD)",
4072+
bgp->name_pretty,
4073+
bgp->gr_info[afi][safi].gr_route_fib_install_cnt,
4074+
get_afi_safi_str(afi, safi, false), dest);
4075+
}
4076+
4077+
/* Check if graceful restart deferral completion is needed */
4078+
if (!bgp->gr_info[afi][safi].gr_deferred &&
4079+
!bgp->gr_info[afi][safi].gr_route_fib_install_cnt && bgp->gr_route_sync_pending) {
4080+
struct graceful_restart_info *gr_info = &(bgp->gr_info[afi][safi]);
4081+
4082+
if (gr_info->t_select_deferral) {
4083+
void *info = EVENT_ARG(gr_info->t_select_deferral);
4084+
XFREE(MTYPE_TMP, info);
4085+
}
4086+
event_cancel(&gr_info->t_select_deferral);
4087+
if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
4088+
zlog_debug("%s: Triggering GR deferral completion from FIB notification for %s",
4089+
bgp->name_pretty, get_afi_safi_str(afi, safi, false));
4090+
bgp_process_gr_deferral_complete(bgp, afi, safi);
4091+
}
4092+
}
4093+
39994094
/* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
40004095
void bgp_do_deferred_path_selection(struct bgp *bgp, afi_t afi, safi_t safi)
40014096
{
@@ -4040,28 +4135,10 @@ void bgp_do_deferred_path_selection(struct bgp *bgp, afi_t afi, safi_t safi)
40404135

40414136
/* Send EOR message when all routes are processed */
40424137
if (!bgp->gr_info[afi][safi].gr_deferred) {
4043-
bool route_sync_pending = false;
4044-
4045-
bgp_send_delayed_eor(bgp);
4046-
/* Send route processing complete message to RIB */
4047-
bgp_zebra_update(bgp, afi, safi,
4048-
ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
4049-
bgp->gr_info[afi][safi].route_sync = true;
4050-
4051-
/*
4052-
* If this instance is all done,
4053-
* check for GR completion overall
4054-
*/
4055-
FOREACH_AFI_SAFI (afi, safi) {
4056-
if (bgp->gr_info[afi][safi].af_enabled &&
4057-
!bgp->gr_info[afi][safi].route_sync) {
4058-
route_sync_pending = true;
4059-
break;
4060-
}
4061-
}
4062-
if (!route_sync_pending) {
4063-
bgp->gr_route_sync_pending = false;
4064-
bgp_update_gr_completion();
4138+
/* t_select_deferral will be NULL when either gr_route_fib_install_cnt is 0
4139+
* or deferral timer for fib install expires */
4140+
if (!BGP_SUPPRESS_FIB_ENABLED(bgp) || !bgp->gr_info[afi][safi].t_select_deferral) {
4141+
bgp_process_gr_deferral_complete(bgp, afi, safi);
40654142
}
40664143
return;
40674144
}

bgpd/bgp_route.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,9 @@ extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t
975975
enum bgp_show_type type, void *output_arg,
976976
uint16_t show_flags);
977977
extern void bgp_do_deferred_path_selection(struct bgp *bgp, afi_t afi, safi_t safi);
978+
extern void bgp_dest_increment_gr_fib_install_count(struct bgp_dest *dest);
979+
extern void bgp_dest_decrement_gr_fib_install_count(struct bgp_dest *dest);
980+
extern void bgp_process_gr_deferral_complete(struct bgp *bgp, afi_t afi, safi_t safi);
978981
extern bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
979982
uint8_t type, uint8_t stype,
980983
struct attr *attr, struct bgp_dest *dest);

bgpd/bgp_zebra.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,18 +1912,21 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info,
19121912
if (install) {
19131913
if (BGP_SUPPRESS_FIB_ENABLED(bgp)) {
19141914
/*
1915-
* If the dest has already been installed at some point
1916-
* in time, we know that it is safe to immediately send
1917-
* the route to peers since they have a path toward us
1918-
* As such let's just let normal mechanisms fly
1919-
*/
1920-
if (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED))
1915+
* If the dest has already been installed at some point
1916+
* in time, we know that it is safe to immediately send
1917+
* the route to peers since they have a path toward us
1918+
* As such let's just let normal mechanisms fly
1919+
*/
1920+
if (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)) {
1921+
bgp_dest_increment_gr_fib_install_count(dest);
19211922
SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
1923+
}
19221924
}
19231925

19241926
if (bgp->main_zebra_update_hold && !is_evpn)
19251927
return;
19261928
} else {
1929+
bgp_dest_decrement_gr_fib_install_count(dest);
19271930
UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
19281931
}
19291932

@@ -2908,6 +2911,7 @@ static int bgp_zebra_route_notify_owner(int command, struct zclient *zclient,
29082911
case ZAPI_ROUTE_INSTALLED:
29092912
new_select = NULL;
29102913
/* Clear the flags so that route can be processed */
2914+
bgp_dest_decrement_gr_fib_install_count(dest);
29112915
UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
29122916
SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
29132917
if (BGP_DEBUG(zebra, ZEBRA))
@@ -2944,6 +2948,7 @@ static int bgp_zebra_route_notify_owner(int command, struct zclient *zclient,
29442948
if (BGP_DEBUG(zebra, ZEBRA))
29452949
zlog_debug("route: %pBD Failed to Install into Fib",
29462950
dest);
2951+
bgp_dest_decrement_gr_fib_install_count(dest);
29472952
UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
29482953
UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
29492954
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
@@ -2959,6 +2964,7 @@ static int bgp_zebra_route_notify_owner(int command, struct zclient *zclient,
29592964
zlog_debug("route: %pBD removed due to better admin won",
29602965
dest);
29612966
new_select = NULL;
2967+
bgp_dest_decrement_gr_fib_install_count(dest);
29622968
UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
29632969
UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
29642970
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {

bgpd/bgpd.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,8 @@ enum bgp_instance_type {
322322

323323
#define BGP_SEND_EOR(bgp, afi, safi) \
324324
(!CHECK_FLAG(bgp->flags, BGP_FLAG_GR_DISABLE_EOR) && \
325-
(!bgp_in_graceful_restart() || bgp->gr_info[afi][safi].select_defer_over))
325+
(!bgp_in_graceful_restart() || bgp->gr_info[afi][safi].select_defer_over) && \
326+
(!BGP_SUPPRESS_FIB_ENABLED(bgp) || !bgp->gr_info[afi][safi].t_select_deferral))
326327

327328
/* BGP GR Global ds */
328329

@@ -335,6 +336,8 @@ struct graceful_restart_info {
335336
struct event *t_select_deferral;
336337
/* Routes Deferred */
337338
uint32_t gr_deferred;
339+
/* Routes waiting for FIB install */
340+
uint32_t gr_route_fib_install_cnt;
338341
/* Best route select */
339342
struct event *t_route_select;
340343
/* AFI, SAFI enabled */

0 commit comments

Comments
 (0)