summaryrefslogtreecommitdiffhomepage
path: root/server/fsm.go
diff options
context:
space:
mode:
authorWataru Ishida <ishida.wataru@lab.ntt.co.jp>2016-10-09 07:15:08 -0700
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-10-09 07:15:08 -0700
commit6b6f6974fcea37dc006f90dbd2f8d65495048725 (patch)
tree5dc899df38c1ab7e410ce13440a43a35b98a0810 /server/fsm.go
parentc3d8784efc24816e30c3ba68cad8f9a8d9d00b28 (diff)
*: Notification support for BGP GR
implement draft-ietf-idr-bgp-gr-notification-07 Signed-off-by: Wataru Ishida <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'server/fsm.go')
-rw-r--r--server/fsm.go18
1 files changed, 13 insertions, 5 deletions
diff --git a/server/fsm.go b/server/fsm.go
index 5ac3e6a2..d86a5ff1 100644
--- a/server/fsm.go
+++ b/server/fsm.go
@@ -47,6 +47,7 @@ const (
FSM_NEW_CONNECTION = "new-connection"
FSM_OPEN_MSG_RECEIVED = "open-msg-received"
FSM_OPEN_MSG_NEGOTIATED = "open-msg-negotiated"
+ FSM_HARD_RESET = "hard-reset"
)
type FsmMsgType int
@@ -544,7 +545,8 @@ func capabilitiesFromConfig(pConf *config.Neighbor) []bgp.ParameterCapabilityInt
}
}
time := c.RestartTime
- caps = append(caps, bgp.NewCapGracefulRestart(restarting, time, tuples))
+ notification := c.NotificationEnabled
+ caps = append(caps, bgp.NewCapGracefulRestart(restarting, notification, time, tuples))
}
return caps
}
@@ -693,8 +695,11 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
"Subcode": body.ErrorSubcode,
"Data": body.Data,
}).Warn("received notification")
-
- sendToErrorCh(FsmStateReason(fmt.Sprintf("%s %s", FSM_NOTIFICATION_RECV, bgp.NewNotificationErrorCode(body.ErrorCode, body.ErrorSubcode).String())))
+ if body.ErrorCode == bgp.BGP_ERROR_CEASE && body.ErrorSubcode == bgp.BGP_ERROR_SUB_HARD_RESET {
+ sendToErrorCh(FSM_HARD_RESET)
+ } else {
+ sendToErrorCh(FsmStateReason(fmt.Sprintf("%s %s", FSM_NOTIFICATION_RECV, bgp.NewNotificationErrorCode(body.ErrorCode, body.ErrorSubcode).String())))
+ }
return nil, nil
}
}
@@ -847,7 +852,7 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
// 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 {
+ if fsm.pConf.GracefulRestart.State.PeerRestarting && cap.Flags&0x08 == 0 {
log.WithFields(log.Fields{
"Topic": "Peer",
"Key": fsm.pConf.Config.NeighborAddress,
@@ -857,6 +862,9 @@ func (h *FSMHandler) opensent() (bgp.FSMState, FsmStateReason) {
h.conn.Close()
return bgp.BGP_FSM_IDLE, FSM_INVALID_MSG
}
+ if fsm.pConf.GracefulRestart.Config.NotificationEnabled && cap.Flags&0x04 > 0 {
+ fsm.pConf.GracefulRestart.State.NotificationEnabled = true
+ }
}
msg := bgp.NewBGPKeepAliveMessage()
@@ -1170,7 +1178,7 @@ func (h *FSMHandler) established() (bgp.FSMState, FsmStateReason) {
case err := <-h.errorCh:
h.conn.Close()
h.t.Kill(nil)
- if s := fsm.pConf.GracefulRestart.State; s.Enabled && (err == FSM_READ_FAILED || err == FSM_WRITE_FAILED) {
+ if s := fsm.pConf.GracefulRestart.State; s.Enabled && ((s.NotificationEnabled && err != FSM_HARD_RESET) || err == FSM_READ_FAILED || err == FSM_WRITE_FAILED) {
err = FSM_GRACEFUL_RESTART
log.WithFields(log.Fields{
"Topic": "Peer",