summaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-01-18 16:04:13 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-01-18 16:04:13 +0900
commitec278710f10c2cae7d6b3e393aa957edfd536181 (patch)
treecb8e6ec6c38ceab014d98d3ab95f159bc9d10411 /server
parenta9e55d3bd75fd5dd633fee1ff2c9d45d6d6447ee (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>
Diffstat (limited to 'server')
-rw-r--r--server/fsm.go19
-rw-r--r--server/peer.go1
-rw-r--r--server/server.go4
3 files changed, 21 insertions, 3 deletions
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)