diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/fsm.go | 6 | ||||
-rw-r--r-- | server/server.go | 46 |
2 files changed, 40 insertions, 12 deletions
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 diff --git a/server/server.go b/server/server.go index df0306b4..87348a72 100644 --- a/server/server.go +++ b/server/server.go @@ -1156,16 +1156,42 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) { } else { // RFC 4724 4.1 // 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) ...snip... - // or (b) the Selection_Deferral_Timer referred to below has expired. - deferral := peer.fsm.pConf.GracefulRestart.Config.DeferralTime - log.WithFields(log.Fields{ - "Topic": "Peer", - "Key": peer.ID(), - }).Debugf("Now syncing, suppress sending updates. start deferral timer(%d)", deferral) - time.AfterFunc(time.Second*time.Duration(deferral), deferralExpiredFunc(bgp.RouteFamily(0))) + // Speaker is re-established, ...snip... 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. + allEnd := func() bool { + for _, p := range server.neighborMap { + if !p.recvedAllEOR() { + return false + } + } + return true + }() + if allEnd { + for _, p := range server.neighborMap { + p.fsm.pConf.GracefulRestart.State.LocalRestarting = false + if !p.isGracefulRestartEnabled() { + continue + } + paths, _ := server.getBestFromLocal(p, p.configuredRFlist()) + if len(paths) > 0 { + sendFsmOutgoingMsg(p, paths, nil, false) + } + } + log.WithFields(log.Fields{ + "Topic": "Server", + }).Info("sync finished") + } else { + deferral := peer.fsm.pConf.GracefulRestart.Config.DeferralTime + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": peer.ID(), + }).Debugf("Now syncing, suppress sending updates. start deferral timer(%d)", deferral) + time.AfterFunc(time.Second*time.Duration(deferral), deferralExpiredFunc(bgp.RouteFamily(0))) + } } } else { if server.shutdown && nextState == bgp.BGP_FSM_IDLE { |