mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 01:14:48 +00:00
bgpd: Handle route-refresh request received before EoR
See the BGP message sequence: R1 R2 | updates | |------------------>| | | | refresh request | x<------------------| | | | updates cont. | |------------------>| | | | end-of-rib | |------------------>| | | When R1 and R2 establish BGP session, R1 begins to send initial updates. If R2 sends a route-refresh request before EoR, it's silently ignored by R1, and routes received earlier have no chance to be processed again. RFC7313 says, "for a BGP speaker that supports the BGP Graceful Restart, it MUST NOT send a BoRR for an <AFI, SAFI> to a neighbor before it sends the EoR for the <AFI, SAFI> to the neighbor." But it doesn't forbid route-refresh request to be sent before receiving EoR. To handle this scenario, postpone response to refresh request until EoR is sent. Signed-off-by: Xiao Liang <shaw.leon@gmail.com>
This commit is contained in:
parent
a05ae6c440
commit
a783cc05f0
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user