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
2528func (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