From 9c8b20a2ef4b29dd94fcd35e7e16541dabef2330 Mon Sep 17 00:00:00 2001 From: Patrick Hemmer Date: Sun, 13 May 2018 02:33:33 -0400 Subject: fix graceful-restart when not all peers are restarting This fixes an issue where GoBGP would incorrectly defer sending routes to a peer on a graceful restart. RFC4724 states: > Once the session between the Restarting Speaker and the Receiving > Speaker is re-established, the Restarting Speaker will receive and > process BGP messages from its peers. However, it MUST defer route > selection for an address family until it either (a) receives the > End-of-RIB marker from all its peers (excluding the ones with the > "Restart State" bit set in the received capability and excluding the > ones that do not advertise the graceful restart capability) or (b) > the Selection_Deferral_Timer referred to below has expired. The scenario that this fixes is where you have 3 (or more) peers, and 2 of the peers ("A" and "B") perform a graceful restart at the same time, but the 3rd ("C") does not. If after restart peer C sends EOR to peer A before peer B reaches BGP_FSM_ESTABLISHED with peer A, it defers the route selection. However once peer B does reach BGP_FSM_ESTABLISHED, peer A still wouldn't send any updates to peer C until the deferral expired. This commit changes the behavior so that upon restart, once the peer receives EOR from all non-restarting peers and reaches BGP_FSM_ESTABLISHED for all restarting peers, the routes are sent to all peers. --- server/fsm.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'server/fsm.go') diff --git a/server/fsm.go b/server/fsm.go index db3efe1f..d655f768 100644 --- a/server/fsm.go +++ b/server/fsm.go @@ -1163,8 +1163,10 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) { "Topic": "Peer", "Key": fsm.pConf.State.NeighborAddress, "State": fsm.state.String(), - }).Debug("peer is restarting, skipping sync process") - fsm.pConf.GracefulRestart.State.LocalRestarting = false + }).Debug("peer has restarted, skipping wait for EOR") + for i := range fsm.pConf.AfiSafis { + fsm.pConf.AfiSafis[i].MpGracefulRestart.State.EndOfRibReceived = true + } } if fsm.pConf.GracefulRestart.Config.NotificationEnabled && cap.Flags&0x04 > 0 { fsm.pConf.GracefulRestart.State.NotificationEnabled = true -- cgit v1.2.3