summaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/fsm.go18
-rw-r--r--server/fsm_test.go2
2 files changed, 14 insertions, 6 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",
diff --git a/server/fsm_test.go b/server/fsm_test.go
index f973fb76..5e31c67a 100644
--- a/server/fsm_test.go
+++ b/server/fsm_test.go
@@ -311,7 +311,7 @@ func open() *bgp.BGPMessage {
[]bgp.ParameterCapabilityInterface{bgp.NewCapMultiProtocol(bgp.RF_IPv4_UC)})
g := &bgp.CapGracefulRestartTuple{4, 2, 3}
p3 := bgp.NewOptionParameterCapability(
- []bgp.ParameterCapabilityInterface{bgp.NewCapGracefulRestart(true, 100,
+ []bgp.ParameterCapabilityInterface{bgp.NewCapGracefulRestart(true, true, 100,
[]*bgp.CapGracefulRestartTuple{g})})
p4 := bgp.NewOptionParameterCapability(
[]bgp.ParameterCapabilityInterface{bgp.NewCapFourOctetASNumber(100000)})