diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-01-18 16:04:13 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-01-18 16:04:13 +0900 |
commit | ec278710f10c2cae7d6b3e393aa957edfd536181 (patch) | |
tree | cb8e6ec6c38ceab014d98d3ab95f159bc9d10411 | |
parent | a9e55d3bd75fd5dd633fee1ff2c9d45d6d6447ee (diff) |
server: support idlehold time after reset
After resetting a peer, the peer will remain idle for idlehold time
(by default 30 seconds). It can be configured via
IdleHoldTImeAfterReset.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | config/bgp_configs.go | 2 | ||||
-rw-r--r-- | config/default.go | 6 | ||||
-rw-r--r-- | server/fsm.go | 19 | ||||
-rw-r--r-- | server/peer.go | 1 | ||||
-rw-r--r-- | server/server.go | 4 |
5 files changed, 28 insertions, 4 deletions
diff --git a/config/bgp_configs.go b/config/bgp_configs.go index c994faac..f33fe727 100644 --- a/config/bgp_configs.go +++ b/config/bgp_configs.go @@ -472,6 +472,8 @@ type TimersType struct { // original -> bgp:send-update-delay //send-update-delay's original type is decimal64 SendUpdateDelay float64 + + IdleHoldTImeAfterReset float64 } //struct for container bgp-af-common-state diff --git a/config/default.go b/config/default.go index 1b9b59c5..f4a2e301 100644 --- a/config/default.go +++ b/config/default.go @@ -1,7 +1,8 @@ package config const ( - DEFAULT_HOLDTIME = 90 + DEFAULT_HOLDTIME = 90 + DEFAULT_IDLE_HOLDTIME_AFTER_RESET = 30 ) func setTimersTypeDefault(timersT *TimersType) { @@ -11,6 +12,9 @@ func setTimersTypeDefault(timersT *TimersType) { if timersT.KeepaliveInterval == 0 { timersT.KeepaliveInterval = timersT.HoldTime / 3 } + if timersT.IdleHoldTImeAfterReset == 0 { + timersT.IdleHoldTImeAfterReset = float64(DEFAULT_IDLE_HOLDTIME_AFTER_RESET) + } } func SetNeighborTypeDefault(neighborT *NeighborType) { diff --git a/server/fsm.go b/server/fsm.go index af6718ca..5c93fce6 100644 --- a/server/fsm.go +++ b/server/fsm.go @@ -44,6 +44,7 @@ type FSM struct { state bgp.FSMState passiveConn *net.TCPConn passiveConnCh chan *net.TCPConn + idleHoldTime float64 } func (fsm *FSM) bgpMessageStateUpdate(MessageType uint8, isIn bool) { @@ -139,13 +140,27 @@ func (h *FSMHandler) Stop() error { func (h *FSMHandler) idle() bgp.FSMState { fsm := h.fsm - // TODO: support idle hold timer if fsm.keepaliveTicker != nil { fsm.keepaliveTicker.Stop() fsm.keepaliveTicker = nil } - return bgp.BGP_FSM_ACTIVE + + idleHoldTimer := time.NewTimer(time.Second * time.Duration(fsm.idleHoldTime)) + for { + select { + case <-h.t.Dying(): + return 0 + case <-idleHoldTimer.C: + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": fsm.peerConfig.NeighborAddress, + "Duration": fsm.idleHoldTime, + }).Debug("IdleHoldTimer expired") + fsm.idleHoldTime = 0 + return bgp.BGP_FSM_ACTIVE + } + } } func (h *FSMHandler) active() bgp.FSMState { diff --git a/server/peer.go b/server/peer.go index 79209983..c86aabb5 100644 --- a/server/peer.go +++ b/server/peer.go @@ -178,6 +178,7 @@ func (peer *Peer) handleREST(restReq *api.RestRequest) { case api.REQ_NEIGHBOR_SHUTDOWN: peer.outgoing <- bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN, nil) case api.REQ_NEIGHBOR_RESET: + peer.fsm.idleHoldTime = peer.peerConfig.Timers.IdleHoldTImeAfterReset peer.outgoing <- bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_RESET, nil) case api.REQ_NEIGHBOR_SOFT_RESET: case api.REQ_NEIGHBOR_SOFT_RESET_IN: diff --git a/server/server.go b/server/server.go index cbd67732..5823859a 100644 --- a/server/server.go +++ b/server/server.go @@ -106,7 +106,9 @@ func (server *BgpServer) Serve() { server.bgpConfig.Global = <-server.globalTypeCh listenerMap := make(map[string]*net.TCPListener) - acceptCh := make(chan *net.TCPConn) + // workaround: we should close an accepted connection + // immediately if we are not in the state we continue? + acceptCh := make(chan *net.TCPConn, 4) l4, err1 := listenAndAccept("tcp4", server.listenPort, acceptCh) listenerMap["tcp4"] = l4 l6, err2 := listenAndAccept("tcp6", server.listenPort, acceptCh) |