Skip to content

Commit 4770c95

Browse files
committed
Add method to get BMP Neighbors as API Session objects
This method can be used to expose a BGPServer-like API with a BMP server as backend.
1 parent ff689d7 commit 4770c95

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

protocols/bgp/server/bmp_router.go

+43
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
log "github.com/sirupsen/logrus"
1313

1414
bnet "github.com/bio-routing/bio-rd/net"
15+
"github.com/bio-routing/bio-rd/protocols/bgp/api"
1516
"github.com/bio-routing/bio-rd/protocols/bgp/packet"
1617
bmppkt "github.com/bio-routing/bio-rd/protocols/bmp/packet"
1718
"github.com/bio-routing/bio-rd/routingtable"
@@ -128,6 +129,48 @@ func (r *Router) serve(con net.Conn) {
128129
}
129130
}
130131

132+
// GetNeighborSessions returns all neighbors as API session objects
133+
func (r *Router) GetNeighborSessions() []*api.Session {
134+
sessions := make([]*api.Session, 0)
135+
136+
for _, neigh := range r.neighborManager.list() {
137+
estSince := neigh.fsm.establishedTime.Unix()
138+
if estSince < 0 {
139+
estSince = 0
140+
}
141+
142+
// for now get this from adjRibIn/adjRibOut, can be replaced when we
143+
// bmp gets its own bgpSrv or Router gets the bmpMetricsService
144+
var routesReceived, routesSent uint64
145+
for _, afi := range []uint16{packet.IPv4AFI, packet.IPv6AFI} {
146+
ribIn, err1 := r.GetNeighborRIBIn(neigh.fsm.peer.addr, afi, packet.UnicastSAFI)
147+
if err1 == nil {
148+
routesReceived += uint64(ribIn.RouteCount())
149+
}
150+
151+
// adjRIBOut might not work properly with BMP, keeping it here for when it will
152+
ribOut, err2 := r.GetNeighborRIBOut(neigh.fsm.peer.addr, afi, packet.UnicastSAFI)
153+
if err2 == nil {
154+
routesSent += uint64(ribOut.RouteCount())
155+
}
156+
}
157+
session := &api.Session{
158+
LocalAddress: neigh.fsm.peer.localAddr.ToProto(),
159+
NeighborAddress: neigh.fsm.peer.addr.ToProto(),
160+
LocalAsn: neigh.localAS,
161+
PeerAsn: neigh.peerAS,
162+
Status: stateToProto(neigh.fsm.state),
163+
Stats: &api.SessionStats{
164+
RoutesReceived: routesReceived,
165+
RoutesExported: routesSent,
166+
},
167+
EstablishedSince: uint64(estSince),
168+
}
169+
sessions = append(sessions, session)
170+
}
171+
return sessions
172+
}
173+
131174
func (r *Router) processMsg(msg []byte) {
132175
bmpMsg, err := bmppkt.Decode(msg)
133176
if err != nil {

protocols/bgp/server/fsm.go

+22
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"time"
1010

1111
"github.com/bio-routing/bio-rd/net/tcp"
12+
"github.com/bio-routing/bio-rd/protocols/bgp/api"
1213
"github.com/bio-routing/bio-rd/protocols/bgp/packet"
1314
"github.com/bio-routing/bio-rd/routingtable/filter"
1415
"github.com/pkg/errors"
@@ -239,6 +240,27 @@ func stateName(s state) string {
239240
}
240241
}
241242

243+
func stateToProto(s state) api.Session_State {
244+
switch s.(type) {
245+
case *idleState:
246+
return api.Session_Idle
247+
case *connectState:
248+
return api.Session_Connect
249+
case *activeState:
250+
return api.Session_Active
251+
case *openSentState:
252+
return api.Session_OpenSent
253+
case *openConfirmState:
254+
return api.Session_OpenConfirmed
255+
case *establishedState:
256+
return api.Session_Established
257+
case *ceaseState:
258+
return api.Session_Active // substitution
259+
default:
260+
panic(fmt.Sprintf("Unknown state: %v", s))
261+
}
262+
}
263+
242264
func (fsm *FSM) cease() {
243265
fsm.eventCh <- Cease
244266
}

0 commit comments

Comments
 (0)