diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2016-01-23 20:45:15 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-02-10 22:15:04 -0800 |
commit | 16b40fd1526ea662bde7e49a0c6c8301bd0b7c82 (patch) | |
tree | ce0cc497d9c971365a87c2b1a3e77032c747e4fc | |
parent | 607d56ad264363c1ebf44a81eb2ab19c2f3da40a (diff) |
fsm: support negotiation of graceful restart capability
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
-rw-r--r-- | server/fsm.go | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/server/fsm.go b/server/fsm.go index e180b375..aa0d7d4e 100644 --- a/server/fsm.go +++ b/server/fsm.go @@ -742,6 +742,40 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) { } fsm.pConf.Timers.State.KeepaliveInterval = keepalive + gr, ok := fsm.capMap[bgp.BGP_CAP_GRACEFUL_RESTART] + if fsm.pConf.GracefulRestart.Config.Enabled && ok { + state := &fsm.pConf.GracefulRestart.State + state.Enabled = true + cap := gr[len(gr)-1].(*bgp.CapGracefulRestart) + state.PeerRestartTime = uint16(cap.Time) + + for _, t := range cap.Tuples { + n := bgp.AddressFamilyNameMap[bgp.AfiSafiToRouteFamily(t.AFI, t.SAFI)] + for i, a := range fsm.pConf.AfiSafis { + if string(a.AfiSafiName) == n { + fsm.pConf.AfiSafis[i].MpGracefulRestart.State.Enabled = true + fsm.pConf.AfiSafis[i].MpGracefulRestart.State.Received = true + break + } + } + } + + // RFC 4724 4.1 + // To re-establish the session with its peer, the Restarting Speaker + // MUST set the "Restart State" bit in the Graceful Restart Capability + // of the OPEN message. + if fsm.pConf.GracefulRestart.State.PeerRestarting && cap.Flags != 0x08 { + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": fsm.pConf.Config.NeighborAddress, + "State": fsm.state, + }).Warn("restart flag is not set") + // send notification? + h.conn.Close() + return bgp.BGP_FSM_IDLE, FSM_INVALID_MSG + } + } + msg := bgp.NewBGPKeepAliveMessage() b, _ := msg.Serialize() fsm.conn.Write(b) |