mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-16 10:38:05 +00:00
Merge pull request #11183 from opensourcerouting/feature/handle_bgp_gr_notification
bgpd: Activate Graceful-Restart when receiving CEASE/HOLDTIME notifications
This commit is contained in:
commit
18028bdb9b
@ -1961,6 +1961,15 @@ static int bgp_fsm_holdtime_expire(struct peer *peer)
|
|||||||
if (bgp_debug_neighbor_events(peer))
|
if (bgp_debug_neighbor_events(peer))
|
||||||
zlog_debug("%s [FSM] Hold timer expire", peer->host);
|
zlog_debug("%s [FSM] Hold timer expire", peer->host);
|
||||||
|
|
||||||
|
/* RFC8538 updates RFC 4724 by defining an extension that permits
|
||||||
|
* the Graceful Restart procedures to be performed when the BGP
|
||||||
|
* speaker receives a BGP NOTIFICATION message or the Hold Time expires.
|
||||||
|
*/
|
||||||
|
if (peer_established(peer) &&
|
||||||
|
bgp_has_graceful_restart_notification(peer))
|
||||||
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE))
|
||||||
|
SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
|
||||||
|
|
||||||
return bgp_stop_with_notify(peer, BGP_NOTIFY_HOLD_ERR, 0);
|
return bgp_stop_with_notify(peer, BGP_NOTIFY_HOLD_ERR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,6 +748,13 @@ struct bgp_notify bgp_notify_decapsulate_hard_reset(struct bgp_notify *notify)
|
|||||||
return bn;
|
return bn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if Graceful-Restart N-bit is exchanged */
|
||||||
|
bool bgp_has_graceful_restart_notification(struct peer *peer)
|
||||||
|
{
|
||||||
|
return CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV) &&
|
||||||
|
CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_ADV);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if to send BGP CEASE Notification/Hard Reset?
|
* Check if to send BGP CEASE Notification/Hard Reset?
|
||||||
*/
|
*/
|
||||||
@ -757,8 +764,7 @@ bool bgp_notify_send_hard_reset(struct peer *peer, uint8_t code,
|
|||||||
/* When the "N" bit has been exchanged, a Hard Reset message is used to
|
/* When the "N" bit has been exchanged, a Hard Reset message is used to
|
||||||
* indicate to the peer that the session is to be fully terminated.
|
* indicate to the peer that the session is to be fully terminated.
|
||||||
*/
|
*/
|
||||||
if (!CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV) ||
|
if (!bgp_has_graceful_restart_notification(peer))
|
||||||
!CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_ADV))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -797,8 +803,7 @@ bool bgp_notify_received_hard_reset(struct peer *peer, uint8_t code,
|
|||||||
/* When the "N" bit has been exchanged, a Hard Reset message is used to
|
/* When the "N" bit has been exchanged, a Hard Reset message is used to
|
||||||
* indicate to the peer that the session is to be fully terminated.
|
* indicate to the peer that the session is to be fully terminated.
|
||||||
*/
|
*/
|
||||||
if (!CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV) ||
|
if (!bgp_has_graceful_restart_notification(peer))
|
||||||
!CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_ADV))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (code == BGP_NOTIFY_CEASE && subcode == BGP_NOTIFY_CEASE_HARD_RESET)
|
if (code == BGP_NOTIFY_CEASE && subcode == BGP_NOTIFY_CEASE_HARD_RESET)
|
||||||
@ -2094,6 +2099,13 @@ static int bgp_notify_receive(struct peer *peer, bgp_size_t size)
|
|||||||
inner.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM)
|
inner.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM)
|
||||||
UNSET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
|
UNSET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
|
||||||
|
|
||||||
|
/* If Graceful-Restart N-bit (Notification) is exchanged,
|
||||||
|
* and it's not a Hard Reset, let's retain the routes.
|
||||||
|
*/
|
||||||
|
if (bgp_has_graceful_restart_notification(peer) && !hard_reset &&
|
||||||
|
CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE))
|
||||||
|
SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
|
||||||
|
|
||||||
bgp_peer_gr_flags_update(peer);
|
bgp_peer_gr_flags_update(peer);
|
||||||
BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
|
BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
|
||||||
peer->bgp->peer);
|
peer->bgp->peer);
|
||||||
|
@ -88,6 +88,7 @@ extern void bgp_send_delayed_eor(struct bgp *bgp);
|
|||||||
void bgp_packet_process_error(struct thread *thread);
|
void bgp_packet_process_error(struct thread *thread);
|
||||||
extern struct bgp_notify
|
extern struct bgp_notify
|
||||||
bgp_notify_decapsulate_hard_reset(struct bgp_notify *notify);
|
bgp_notify_decapsulate_hard_reset(struct bgp_notify *notify);
|
||||||
|
extern bool bgp_has_graceful_restart_notification(struct peer *peer);
|
||||||
extern bool bgp_notify_send_hard_reset(struct peer *peer, uint8_t code,
|
extern bool bgp_notify_send_hard_reset(struct peer *peer, uint8_t code,
|
||||||
uint8_t subcode);
|
uint8_t subcode);
|
||||||
extern bool bgp_notify_received_hard_reset(struct peer *peer, uint8_t code,
|
extern bool bgp_notify_received_hard_reset(struct peer *peer, uint8_t code,
|
||||||
|
@ -375,6 +375,8 @@ BGP
|
|||||||
:t:`Default External BGP (EBGP) Route Propagation Behavior without Policies. J. Mauch, J. Snijders, G. Hankins. July 2017`
|
:t:`Default External BGP (EBGP) Route Propagation Behavior without Policies. J. Mauch, J. Snijders, G. Hankins. July 2017`
|
||||||
- :rfc:`8277`
|
- :rfc:`8277`
|
||||||
:t:`Using BGP to Bind MPLS Labels to Address Prefixes. E. Rosen. October 2017`
|
:t:`Using BGP to Bind MPLS Labels to Address Prefixes. E. Rosen. October 2017`
|
||||||
|
- :rfc:`8538`
|
||||||
|
:t:`Notification Message Support for BGP Graceful Restart. K. Patel, R. Fernando, J. Scudder, J. Haas. March 2019`
|
||||||
- :rfc:`8654`
|
- :rfc:`8654`
|
||||||
:t:`Extended Message Support for BGP. R. Bush, K. Patel, D. Ward. October 2019`
|
:t:`Extended Message Support for BGP. R. Bush, K. Patel, D. Ward. October 2019`
|
||||||
- :rfc:`9003`
|
- :rfc:`9003`
|
||||||
|
Loading…
Reference in New Issue
Block a user