func (h *FSMHandler) loop() error { fsm := h.fsm ch := make(chan bgp.FSMState) oldState := fsm.state f := func() error { nextState := bgp.FSMState(-1) var reason FsmStateReason switch fsm.state { case bgp.BGP_FSM_IDLE: nextState, reason = h.idle() // case bgp.BGP_FSM_CONNECT: // nextState = h.connect() case bgp.BGP_FSM_ACTIVE: nextState, reason = h.active() case bgp.BGP_FSM_OPENSENT: nextState, reason = h.opensent() case bgp.BGP_FSM_OPENCONFIRM: nextState, reason = h.openconfirm() case bgp.BGP_FSM_ESTABLISHED: nextState, reason = h.established() } fsm.reason = reason ch <- nextState return nil } h.t.Go(f) nextState := <-ch if nextState == bgp.BGP_FSM_ESTABLISHED && oldState == bgp.BGP_FSM_OPENCONFIRM { log.WithFields(log.Fields{ "Topic": "Peer", "Key": fsm.pConf.Config.NeighborAddress, "State": fsm.state.String(), }).Info("Peer Up") } if oldState == bgp.BGP_FSM_ESTABLISHED { // The main goroutine sent the notificaiton due to // deconfiguration or something. reason := fsm.reason if fsm.h.sentNotification != "" { reason = FsmStateReason(fmt.Sprintf("%s %s", FSM_NOTIFICATION_SENT, fsm.h.sentNotification)) } log.WithFields(log.Fields{ "Topic": "Peer", "Key": fsm.pConf.Config.NeighborAddress, "State": fsm.state.String(), "Reason": reason, }).Info("Peer Down") } e := time.AfterFunc(time.Second*120, func() { log.WithFields(log.Fields{"Topic": "Peer"}).Fatalf("failed to free the fsm.h.t for %s %s %s", fsm.pConf.Config.NeighborAddress, oldState, nextState) }) h.t.Wait() e.Stop() // under zero means that tomb.Dying() if nextState >= bgp.BGP_FSM_IDLE { e := &FsmMsg{ MsgType: FSM_MSG_STATE_CHANGE, MsgSrc: fsm.pConf.Config.NeighborAddress, MsgData: nextState, Version: h.fsm.version, } h.stateCh <- e } return nil }
func (s *Server) GetNeighbor(ctx context.Context, arg *GetNeighborRequest) (*GetNeighborResponse, error) { toApi := func(pconf *config.Neighbor) *Peer { prefixLimits := make([]*PrefixLimit, 0, len(pconf.AfiSafis)) for _, family := range pconf.AfiSafis { if c := family.PrefixLimit.Config; c.MaxPrefixes > 0 { k, _ := bgp.GetRouteFamily(string(family.Config.AfiSafiName)) prefixLimits = append(prefixLimits, &PrefixLimit{ Family: uint32(k), MaxPrefixes: c.MaxPrefixes, ShutdownThresholdPct: uint32(c.ShutdownThresholdPct), }) } } timer := pconf.Timers s := pconf.State localAddress := pconf.Transport.Config.LocalAddress if pconf.Transport.State.LocalAddress != "" { localAddress = pconf.Transport.State.LocalAddress } return &Peer{ Conf: &PeerConf{ NeighborAddress: pconf.Config.NeighborAddress, Id: s.RemoteRouterId, PeerAs: pconf.Config.PeerAs, LocalAs: pconf.Config.LocalAs, PeerType: uint32(pconf.Config.PeerType.ToInt()), AuthPassword: pconf.Config.AuthPassword, RemovePrivateAs: uint32(pconf.Config.RemovePrivateAs.ToInt()), RouteFlapDamping: pconf.Config.RouteFlapDamping, SendCommunity: uint32(pconf.Config.SendCommunity.ToInt()), Description: pconf.Config.Description, PeerGroup: pconf.Config.PeerGroup, RemoteCap: s.Capabilities.RemoteList, LocalCap: s.Capabilities.LocalList, PrefixLimits: prefixLimits, LocalAddress: localAddress, NeighborInterface: pconf.Config.NeighborInterface, }, Info: &PeerState{ BgpState: bgp.FSMState(s.SessionState.ToInt()).String(), AdminState: s.AdminState, Messages: &Messages{ Received: &Message{ NOTIFICATION: s.Messages.Received.Notification, UPDATE: s.Messages.Received.Update, OPEN: s.Messages.Received.Open, KEEPALIVE: s.Messages.Received.Keepalive, REFRESH: s.Messages.Received.Refresh, DISCARDED: s.Messages.Received.Discarded, TOTAL: s.Messages.Received.Total, }, Sent: &Message{ NOTIFICATION: s.Messages.Sent.Notification, UPDATE: s.Messages.Sent.Update, OPEN: s.Messages.Sent.Open, KEEPALIVE: s.Messages.Sent.Keepalive, REFRESH: s.Messages.Sent.Refresh, DISCARDED: s.Messages.Sent.Discarded, TOTAL: s.Messages.Sent.Total, }, }, Received: s.AdjTable.Received, Accepted: s.AdjTable.Accepted, Advertised: s.AdjTable.Advertised, }, Timers: &Timers{ Config: &TimersConfig{ ConnectRetry: uint64(timer.Config.ConnectRetry), HoldTime: uint64(timer.Config.HoldTime), KeepaliveInterval: uint64(timer.Config.KeepaliveInterval), }, State: &TimersState{ KeepaliveInterval: uint64(timer.State.KeepaliveInterval), NegotiatedHoldTime: uint64(timer.State.NegotiatedHoldTime), Uptime: uint64(timer.State.Uptime), Downtime: uint64(timer.State.Downtime), }, }, RouteReflector: &RouteReflector{ RouteReflectorClient: pconf.RouteReflector.Config.RouteReflectorClient, RouteReflectorClusterId: string(pconf.RouteReflector.Config.RouteReflectorClusterId), }, RouteServer: &RouteServer{ RouteServerClient: pconf.RouteServer.Config.RouteServerClient, }, } } p := []*Peer{} for _, e := range s.bgpServer.GetNeighbor() { p = append(p, toApi(e)) } return &GetNeighborResponse{Peers: p}, nil }