summaryrefslogtreecommitdiffhomepage
path: root/server/server.go
diff options
context:
space:
mode:
authorWataru Ishida <ishida.wataru@lab.ntt.co.jp>2016-10-09 07:18:13 -0700
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-10-09 07:18:13 -0700
commit614746ca1159fe421047df04c5af6f07c38b2e65 (patch)
tree77e93a40ec38318a96ab3a195fb1baa68372acd2 /server/server.go
parent6b6f6974fcea37dc006f90dbd2f8d65495048725 (diff)
*: support long lived graceful restart
Signed-off-by: Wataru Ishida <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'server/server.go')
-rw-r--r--server/server.go79
1 files changed, 69 insertions, 10 deletions
diff --git a/server/server.go b/server/server.go
index 1d36720b..f92b8be8 100644
--- a/server/server.go
+++ b/server/server.go
@@ -628,13 +628,72 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
peer.DropAll(drop)
server.dropPeerAllRoutes(peer, drop)
} else if peer.fsm.pConf.GracefulRestart.State.PeerRestarting && nextState == bgp.BGP_FSM_IDLE {
- // RFC 4724 4.2
- // If the session does not get re-established within the "Restart Time"
- // that the peer advertised previously, the Receiving Speaker MUST
- // delete all the stale routes from the peer that it is retaining.
- peer.fsm.pConf.GracefulRestart.State.PeerRestarting = false
- peer.DropAll(peer.configuredRFlist())
- server.dropPeerAllRoutes(peer, peer.configuredRFlist())
+ if peer.fsm.pConf.GracefulRestart.State.LongLivedEnabled {
+ llgr, no_llgr := peer.llgrFamilies()
+
+ peer.DropAll(no_llgr)
+ server.dropPeerAllRoutes(peer, no_llgr)
+
+ // attach LLGR_STALE community to paths in peer's adj-rib-in
+ // paths with NO_LLGR are deleted
+ pathList := peer.markLLGRStale(llgr)
+
+ // calculate again
+ // wheh path with LLGR_STALE chosen as best,
+ // peer which doesn't support LLGR will drop the path
+ // if it is in adj-rib-out, do withdrawal
+ server.propagateUpdate(peer, pathList)
+
+ for _, f := range llgr {
+ endCh := make(chan struct{})
+ peer.llgrEndChs = append(peer.llgrEndChs, endCh)
+ go func(family bgp.RouteFamily, endCh chan struct{}) {
+ t := peer.llgrRestartTime(family)
+ timer := time.NewTimer(time.Second * time.Duration(t))
+
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": peer.ID(),
+ "Family": family,
+ }).Debugf("start LLGR restart timer (%d sec) for %s", t, family)
+
+ select {
+ case <-timer.C:
+ ch := make(chan struct{})
+ defer func() { <-ch }()
+ server.mgmtCh <- func() {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": peer.ID(),
+ "Family": family,
+ }).Debugf("LLGR restart timer (%d sec) for %s expired", t, family)
+ defer close(ch)
+ peer.DropAll([]bgp.RouteFamily{family})
+ server.dropPeerAllRoutes(peer, []bgp.RouteFamily{family})
+
+ // when all llgr restart timer expired, stop PeerRestarting
+ if peer.llgrRestartTimerExpired(family) {
+ peer.stopPeerRestarting()
+ }
+ }
+ case <-endCh:
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": peer.ID(),
+ "Family": family,
+ }).Debugf("stop LLGR restart timer (%d sec) for %s", t, family)
+ }
+ }(f, endCh)
+ }
+ } else {
+ // RFC 4724 4.2
+ // If the session does not get re-established within the "Restart Time"
+ // that the peer advertised previously, the Receiving Speaker MUST
+ // delete all the stale routes from the peer that it is retaining.
+ peer.fsm.pConf.GracefulRestart.State.PeerRestarting = false
+ peer.DropAll(peer.configuredRFlist())
+ server.dropPeerAllRoutes(peer, peer.configuredRFlist())
+ }
}
peer.outgoing.Close()
@@ -651,8 +710,7 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
server.mgmtCh <- func() {
defer close(ch)
-
- server.softResetOut(peer.fsm.pConf.Config.NeighborAddress, bgp.RouteFamily(0), true)
+ server.softResetOut(peer.fsm.pConf.Config.NeighborAddress, family, true)
}
}
}
@@ -832,7 +890,7 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
}
if peer.fsm.pConf.GracefulRestart.State.PeerRestarting {
if peer.recvedAllEOR() {
- peer.fsm.pConf.GracefulRestart.State.PeerRestarting = false
+ peer.stopPeerRestarting()
pathList := peer.adjRibIn.DropStale(peer.configuredRFlist())
log.WithFields(log.Fields{
"Topic": "Peer",
@@ -1613,6 +1671,7 @@ func (server *BgpServer) deleteNeighbor(c *config.Neighbor, code, subcode uint8)
}).Infof("Delete a peer configuration for:%s", addr)
n.fsm.sendNotification(code, subcode, nil, "")
+ n.stopPeerRestarting()
go func(addr string) {
t1 := time.AfterFunc(time.Minute*5, func() {