summaryrefslogtreecommitdiffhomepage
path: root/server/fsm.go
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2016-01-01 02:49:05 +0900
committerISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2016-01-04 16:46:28 +0900
commitce1d27ba8c49856c2e67c65f076caf48dbb6765e (patch)
tree3e97ec845190758c73c0da080300a36a4cb17feb /server/fsm.go
parentaa3b0436d20a1d9ed16fee34b323ea6e73ba0c85 (diff)
server: handle open message only in fsm
we don't need to spread this handling to peer.go and server.go Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'server/fsm.go')
-rw-r--r--server/fsm.go53
1 files changed, 45 insertions, 8 deletions
diff --git a/server/fsm.go b/server/fsm.go
index 16267c17..1a5943d2 100644
--- a/server/fsm.go
+++ b/server/fsm.go
@@ -85,6 +85,7 @@ type FSM struct {
getActiveCh chan struct{}
h *FSMHandler
rfMap map[bgp.RouteFamily]bool
+ capMap map[bgp.BGPCapabilityCode][]bgp.ParameterCapabilityInterface
confedCheck bool
peerInfo *table.PeerInfo
policy *table.RoutingPolicy
@@ -154,6 +155,7 @@ func NewFSM(gConf *config.Global, pConf *config.Neighbor, policy *table.RoutingP
adminStateCh: make(chan AdminState, 1),
getActiveCh: make(chan struct{}),
rfMap: make(map[bgp.RouteFamily]bool),
+ capMap: make(map[bgp.BGPCapabilityCode][]bgp.ParameterCapabilityInterface),
confedCheck: !config.IsConfederationMember(gConf, pConf) && config.IsEBGPPeer(gConf, pConf),
peerInfo: table.NewPeerInfo(gConf, pConf),
policy: policy,
@@ -551,6 +553,35 @@ func (h *FSMHandler) recvMessage() error {
return nil
}
+func open2Cap(open *bgp.BGPOpen, n *config.Neighbor) (map[bgp.BGPCapabilityCode][]bgp.ParameterCapabilityInterface, map[bgp.RouteFamily]bool) {
+ capMap := make(map[bgp.BGPCapabilityCode][]bgp.ParameterCapabilityInterface)
+ rfMap := config.CreateRfMap(n)
+ r := make(map[bgp.RouteFamily]bool)
+ for _, p := range open.OptParams {
+ if paramCap, y := p.(*bgp.OptionParameterCapability); y {
+ for _, c := range paramCap.Capability {
+ m, ok := capMap[c.Code()]
+ if !ok {
+ m = make([]bgp.ParameterCapabilityInterface, 0, 1)
+ }
+ capMap[c.Code()] = append(m, c)
+
+ if c.Code() == bgp.BGP_CAP_MULTIPROTOCOL {
+ m := c.(*bgp.CapMultiProtocol)
+ r[m.CapValue] = true
+ }
+ }
+ }
+ }
+
+ for rf, _ := range rfMap {
+ if _, y := r[rf]; !y {
+ delete(rfMap, rf)
+ }
+ }
+ return capMap, rfMap
+}
+
func (h *FSMHandler) opensent() bgp.FSMState {
fsm := h.fsm
m := buildopen(fsm.gConf, fsm.pConf)
@@ -596,15 +627,21 @@ func (h *FSMHandler) opensent() bgp.FSMState {
return bgp.BGP_FSM_IDLE
}
fsm.peerInfo.ID = body.ID
- _, fsm.rfMap = open2Cap(body, fsm.pConf)
-
- e := &FsmMsg{
- MsgType: FSM_MSG_BGP_MESSAGE,
- MsgSrc: fsm.pConf.Config.NeighborAddress,
- MsgDst: fsm.pConf.Transport.Config.LocalAddress,
- MsgData: m,
+ fsm.capMap, fsm.rfMap = open2Cap(body, fsm.pConf)
+
+ // calculate HoldTime
+ // RFC 4271 P.13
+ // a BGP speaker MUST calculate the value of the Hold Timer
+ // by using the smaller of its configured Hold Time and the Hold Time
+ // received in the OPEN message.
+ holdTime := float64(body.HoldTime)
+ myHoldTime := fsm.pConf.Timers.Config.HoldTime
+ if holdTime > myHoldTime {
+ fsm.negotiatedHoldTime = myHoldTime
+ } else {
+ fsm.negotiatedHoldTime = holdTime
}
- h.incoming <- e
+
msg := bgp.NewBGPKeepAliveMessage()
b, _ := msg.Serialize()
fsm.conn.Write(b)