diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 90695219a7..cc18808373 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -360,6 +360,31 @@ int bgp_nlri_parse(struct peer *peer, struct attr *attr, return BGP_NLRI_PARSE_ERROR; } + +/* + * Check if route-refresh request from peer is pending (received before EoR), + * and process it now. + */ +static void bgp_process_pending_refresh(struct peer *peer, afi_t afi, + safi_t safi) +{ + if (CHECK_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_REFRESH_PENDING)) { + UNSET_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_REFRESH_PENDING); + bgp_route_refresh_send(peer, afi, safi, 0, 0, 0, + BGP_ROUTE_REFRESH_BORR); + if (bgp_debug_neighbor_events(peer)) + zlog_debug( + "%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)", + peer, afi2str(afi), safi2str(safi)); + + SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_BORR_SEND); + UNSET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_EORR_SEND); + bgp_announce_route(peer, afi, safi, true); + } +} + /* * Checks a variety of conditions to determine whether the peer needs to be * rescheduled for packet generation again, and does so if necessary. @@ -558,6 +583,9 @@ void bgp_generate_updgrp_packets(struct thread *thread) BGP_UPDATE_EOR_PKT( peer, afi, safi, s); + bgp_process_pending_refresh( + peer, afi, + safi); } } } @@ -2564,6 +2592,9 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) "%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR", peer, afi2str(afi), safi2str(safi)); + /* Can't send BoRR now, postpone after EoR */ + SET_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_REFRESH_PENDING); return BGP_PACKET_NOOP; } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 28883c9e7c..f6162f33e4 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1456,6 +1456,7 @@ struct peer { #define PEER_STATUS_EORR_RECEIVED (1U << 10) /* EoRR received from peer */ /* LLGR aware peer */ #define PEER_STATUS_LLGR_WAIT (1U << 11) +#define PEER_STATUS_REFRESH_PENDING (1U << 12) /* refresh request from peer */ /* Configured timer values. */ _Atomic uint32_t holdtime;