Skip to content

Commit 855dbd4

Browse files
committed
Implement ListSessions of BGP API
flaps + routes imported in the stats are still missing.
1 parent 11ab0ef commit 855dbd4

File tree

3 files changed

+413
-1
lines changed

3 files changed

+413
-1
lines changed

protocols/bgp/metrics/bgp_peer_metrics.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package metrics
22

33
import (
4+
"fmt"
45
"time"
56

67
bnet "github.com/bio-routing/bio-rd/net"
8+
"github.com/bio-routing/bio-rd/protocols/bgp/api"
79
)
810

911
const (
@@ -48,3 +50,25 @@ type BGPPeerMetrics struct {
4850
// AddressFamilies provides metrics on AFI/SAFI level
4951
AddressFamilies []*BGPAddressFamilyMetrics
5052
}
53+
54+
// GetStateAsProto returns the state of this peer to be used by the BGP API
55+
func (m *BGPPeerMetrics) GetStateAsProto() api.Session_State {
56+
switch m.State {
57+
case StateDown:
58+
return api.Session_Active // substitution
59+
case StateIdle:
60+
return api.Session_Idle
61+
case StateConnect:
62+
return api.Session_Connect
63+
case StateActive:
64+
return api.Session_Active
65+
case StateOpenSent:
66+
return api.Session_OpenSent
67+
case StateOpenConfirm:
68+
return api.Session_OpenConfirmed
69+
case StateEstablished:
70+
return api.Session_Established
71+
default:
72+
panic(fmt.Sprintf("Unknown state: %v", m.State))
73+
}
74+
}

protocols/bgp/server/bgp_api.go

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"fmt"
66

77
"github.com/bio-routing/bio-rd/protocols/bgp/api"
8+
"github.com/bio-routing/bio-rd/protocols/bgp/metrics"
89
"github.com/bio-routing/bio-rd/route"
10+
"github.com/pkg/errors"
911

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

27+
// ListSessions lists all sessions the BGP server currently has
2528
func (s *BGPAPIServer) ListSessions(ctx context.Context, in *api.ListSessionsRequest) (*api.ListSessionsResponse, error) {
26-
return nil, fmt.Errorf("Not implemented yet")
29+
bgpMetrics, err := s.srv.Metrics()
30+
if err != nil {
31+
return nil, errors.Wrap(err, "Could not get peer metrics")
32+
}
33+
34+
sessions := make([]*api.Session, 0)
35+
for _, peerIP := range s.srv.GetPeers() {
36+
peer := s.srv.GetPeerConfig(peerIP)
37+
// find metrics for peer
38+
var peerMetrics *metrics.BGPPeerMetrics
39+
for _, peerMetricsEntry := range bgpMetrics.Peers {
40+
if *peerMetricsEntry.IP == *peer.PeerAddress {
41+
peerMetrics = peerMetricsEntry
42+
break
43+
}
44+
}
45+
if peerMetrics == nil {
46+
return nil, fmt.Errorf("Could not find metrics for neighbor %s", peer.PeerAddress)
47+
}
48+
49+
if in.Filter != nil {
50+
if in.Filter.NeighborIp != nil {
51+
filterNeighbor := bnet.IPFromProtoIP(in.Filter.NeighborIp)
52+
if *filterNeighbor != *peerIP {
53+
continue
54+
}
55+
}
56+
if in.Filter.VrfName != "" {
57+
if in.Filter.VrfName != peerMetrics.VRF {
58+
continue
59+
}
60+
}
61+
}
62+
63+
estSince := peerMetrics.Since.Unix()
64+
if estSince < 0 {
65+
// time not set, peer probably not up
66+
estSince = 0
67+
}
68+
var routesReceived, routesSent uint64
69+
for _, afiPeerMetrics := range peerMetrics.AddressFamilies {
70+
routesReceived += afiPeerMetrics.RoutesReceived
71+
routesSent += afiPeerMetrics.RoutesSent
72+
}
73+
74+
session := &api.Session{
75+
LocalAddress: peer.LocalAddress.ToProto(),
76+
NeighborAddress: peer.PeerAddress.ToProto(),
77+
LocalAsn: peer.LocalAS,
78+
PeerAsn: peer.PeerAS,
79+
Status: peerMetrics.GetStateAsProto(),
80+
Stats: &api.SessionStats{
81+
MessagesIn: peerMetrics.UpdatesReceived,
82+
MessagesOut: peerMetrics.UpdatesSent,
83+
RoutesReceived: routesReceived,
84+
RoutesExported: routesSent,
85+
},
86+
EstablishedSince: uint64(estSince),
87+
Description: peer.Description,
88+
VrfName: peerMetrics.VRF,
89+
}
90+
sessions = append(sessions, session)
91+
}
92+
93+
resp := &api.ListSessionsResponse{
94+
Sessions: sessions,
95+
}
96+
return resp, nil
2797
}
2898

2999
// DumpRIBIn dumps the RIB in of a peer for a given AFI/SAFI

0 commit comments

Comments
 (0)