Skip to content

Commit

Permalink
Implement ListSessions of BGP API
Browse files Browse the repository at this point in the history
flaps + routes imported in the stats are still missing.
  • Loading branch information
sebageek committed May 26, 2020
1 parent 11ab0ef commit 855dbd4
Show file tree
Hide file tree
Showing 3 changed files with 413 additions and 1 deletion.
24 changes: 24 additions & 0 deletions protocols/bgp/metrics/bgp_peer_metrics.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package metrics

import (
"fmt"
"time"

bnet "github.com/bio-routing/bio-rd/net"
"github.com/bio-routing/bio-rd/protocols/bgp/api"
)

const (
Expand Down Expand Up @@ -48,3 +50,25 @@ type BGPPeerMetrics struct {
// AddressFamilies provides metrics on AFI/SAFI level
AddressFamilies []*BGPAddressFamilyMetrics
}

// GetStateAsProto returns the state of this peer to be used by the BGP API
func (m *BGPPeerMetrics) GetStateAsProto() api.Session_State {
switch m.State {
case StateDown:
return api.Session_Active // substitution
case StateIdle:
return api.Session_Idle
case StateConnect:
return api.Session_Connect
case StateActive:
return api.Session_Active
case StateOpenSent:
return api.Session_OpenSent
case StateOpenConfirm:
return api.Session_OpenConfirmed
case StateEstablished:
return api.Session_Established
default:
panic(fmt.Sprintf("Unknown state: %v", m.State))
}
}
72 changes: 71 additions & 1 deletion protocols/bgp/server/bgp_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (
"fmt"

"github.com/bio-routing/bio-rd/protocols/bgp/api"
"github.com/bio-routing/bio-rd/protocols/bgp/metrics"
"github.com/bio-routing/bio-rd/route"
"github.com/pkg/errors"

bnet "github.com/bio-routing/bio-rd/net"
routeapi "github.com/bio-routing/bio-rd/route/api"
Expand All @@ -22,8 +24,76 @@ func NewBGPAPIServer(s BGPServer) *BGPAPIServer {
}
}

// ListSessions lists all sessions the BGP server currently has
func (s *BGPAPIServer) ListSessions(ctx context.Context, in *api.ListSessionsRequest) (*api.ListSessionsResponse, error) {
return nil, fmt.Errorf("Not implemented yet")
bgpMetrics, err := s.srv.Metrics()
if err != nil {
return nil, errors.Wrap(err, "Could not get peer metrics")
}

sessions := make([]*api.Session, 0)
for _, peerIP := range s.srv.GetPeers() {
peer := s.srv.GetPeerConfig(peerIP)
// find metrics for peer
var peerMetrics *metrics.BGPPeerMetrics
for _, peerMetricsEntry := range bgpMetrics.Peers {
if *peerMetricsEntry.IP == *peer.PeerAddress {
peerMetrics = peerMetricsEntry
break
}
}
if peerMetrics == nil {
return nil, fmt.Errorf("Could not find metrics for neighbor %s", peer.PeerAddress)
}

if in.Filter != nil {
if in.Filter.NeighborIp != nil {
filterNeighbor := bnet.IPFromProtoIP(in.Filter.NeighborIp)
if *filterNeighbor != *peerIP {
continue
}
}
if in.Filter.VrfName != "" {
if in.Filter.VrfName != peerMetrics.VRF {
continue
}
}
}

estSince := peerMetrics.Since.Unix()
if estSince < 0 {
// time not set, peer probably not up
estSince = 0
}
var routesReceived, routesSent uint64
for _, afiPeerMetrics := range peerMetrics.AddressFamilies {
routesReceived += afiPeerMetrics.RoutesReceived
routesSent += afiPeerMetrics.RoutesSent
}

session := &api.Session{
LocalAddress: peer.LocalAddress.ToProto(),
NeighborAddress: peer.PeerAddress.ToProto(),
LocalAsn: peer.LocalAS,
PeerAsn: peer.PeerAS,
Status: peerMetrics.GetStateAsProto(),
Stats: &api.SessionStats{
MessagesIn: peerMetrics.UpdatesReceived,
MessagesOut: peerMetrics.UpdatesSent,
RoutesReceived: routesReceived,
RoutesExported: routesSent,
},
EstablishedSince: uint64(estSince),
Description: peer.Description,
VrfName: peerMetrics.VRF,
}
sessions = append(sessions, session)
}

resp := &api.ListSessionsResponse{
Sessions: sessions,
}
return resp, nil
}

// DumpRIBIn dumps the RIB in of a peer for a given AFI/SAFI
Expand Down
Loading

0 comments on commit 855dbd4

Please sign in to comment.