We now actually get data into alice from gobgp

This commit is contained in:
Emil Palm 2019-01-10 11:37:17 +01:00
parent f999999718
commit 6edd0ce93b
5 changed files with 176 additions and 38 deletions

View File

@ -602,6 +602,7 @@ func getSources(config *ini.File) ([]*SourceConfig, error) {
}
backendConfig.MapTo(&c)
config.Birdwatcher = c
case SOURCE_GOBGP:
c := gobgp.Config{
Id: config.Id,

View File

@ -0,0 +1,125 @@
package gobgp;
import (
"github.com/alice-lg/alice-lg/backend/sources/gobgp/apiutil"
"github.com/osrg/gobgp/pkg/packet/bgp"
aliceapi "github.com/alice-lg/alice-lg/backend/api"
api "github.com/osrg/gobgp/api"
"log"
"fmt"
"context"
"time"
"io"
)
func (gobgp *GoBGP) GetRoutes(neighborId string) (*aliceapi.RoutesResponse) {
rr := aliceapi.RoutesResponse{}
rr.Imported = make(aliceapi.Routes,0)
rr.Filtered = make(aliceapi.Routes,0)
rr.NotExported = make(aliceapi.Routes,0)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// Go over all peers
peerStream, err := gobgp.client.ListPeer(ctx, &api.ListPeerRequest{EnableAdvertised: true})
if err != nil {
return nil
}
for {
peer, err := peerStream.Recv()
if err == io.EOF {
break
}
peerId := fmt.Sprintf("%d_%s",peer.Peer.State.PeerAs, peer.Peer.State.NeighborAddress)
if neighborId == "" || peerId == neighborId {
log.Printf("%s VS %s\n", peerId, neighborId)
pathStream, err := gobgp.client.ListPath(ctx, &api.ListPathRequest{
Name: peer.Peer.State.NeighborAddress,
TableType: api.TableType_ADJ_IN,
Family: &api.Family{
Afi: api.Family_AFI_IP,
Safi: api.Family_SAFI_UNICAST,
},
})
if err != nil {
return nil
}
for {
_path, err := pathStream.Recv()
if err == io.EOF {
break
}
for _, path := range _path.Destination.Paths {
r := aliceapi.Route{}
r.Id = fmt.Sprintf("%d_%s", path.Identifier, _path.Destination.Prefix)
r.NeighbourId = peerId
r.Network = _path.Destination.Prefix
r.Interface = "Unknown"
r.Age = time.Now().Sub(time.Unix(path.Age.GetSeconds(),int64(path.Age.GetNanos())))
r.Primary = path.Best
attrs, _ := apiutil.GetNativePathAttributes(path)
for _, attr := range attrs {
switch attr.(type) {
case *bgp.PathAttributeMultiExitDisc:
med := attr.(*bgp.PathAttributeMultiExitDisc)
r.Bgp.Med = int(med.Value)
case *bgp.PathAttributeNextHop:
nh := attr.(*bgp.PathAttributeNextHop)
r.Gateway = nh.Value.String()
r.Bgp.NextHop = nh.Value.String()
case *bgp.PathAttributeLocalPref:
lp := attr.(*bgp.PathAttributeLocalPref)
r.Bgp.LocalPref = int(lp.Value)
case *bgp.PathAttributeOrigin:
origin := attr.(*bgp.PathAttributeOrigin)
switch origin.Value {
case bgp.BGP_ORIGIN_ATTR_TYPE_IGP:
r.Bgp.Origin = "IGP"
case bgp.BGP_ORIGIN_ATTR_TYPE_EGP:
r.Bgp.Origin = "EGP"
case bgp.BGP_ORIGIN_ATTR_TYPE_INCOMPLETE:
r.Bgp.Origin = "Incomplete"
}
case *bgp.PathAttributeAsPath:
aspath := attr.(*bgp.PathAttributeAsPath)
for _, aspth := range aspath.Value {
for _, as := range aspth.GetAS() {
r.Bgp.AsPath = append(r.Bgp.AsPath, int(as))
}
}
case *bgp.PathAttributeCommunities:
communities := attr.(*bgp.PathAttributeCommunities)
for _, community := range communities.Value {
_community := aliceapi.Community{int((0xffff0000&community)>>16),int(0xffff&community)}
r.Bgp.Communities = append(r.Bgp.Communities, _community)
}
}
}
r.Metric = (r.Bgp.LocalPref + r.Bgp.Med)
if path.Filtered {
rr.Filtered = append(rr.Filtered, &r)
} else {
rr.Imported = append(rr.Imported, &r)
}
}
}
}
}
log.Printf("%+v", rr)
return &rr
}

View File

@ -4,6 +4,7 @@ import (
aliceapi "github.com/alice-lg/alice-lg/backend/api"
"github.com/alice-lg/alice-lg/backend/caches"
api "github.com/osrg/gobgp/api"
"google.golang.org/grpc"
"log"
@ -101,7 +102,7 @@ func (gobgp *GoBGP) Neighbours() (*aliceapi.NeighboursResponse, error) {
response := aliceapi.NeighboursResponse{}
response.Neighbours = make(aliceapi.Neighbours,0)
resp, err := gobgp.client.ListPeer(ctx, &api.ListPeerRequest{})
resp, err := gobgp.client.ListPeer(ctx, &api.ListPeerRequest{EnableAdvertised: true})
if err != nil {
return nil, err
}
@ -112,56 +113,51 @@ func (gobgp *GoBGP) Neighbours() (*aliceapi.NeighboursResponse, error) {
}
neigh := aliceapi.Neighbour{}
neigh.Address = _resp.Peer.State.NeighborAddress
neigh.Asn = int(_resp.Peer.State.PeerAs)
neigh.State = _resp.Peer.State.SessionState.String()
neigh.Description = _resp.Peer.State.Description
//neigh.LastError = _resp.Peer.State.Messages.String()
switch _resp.Peer.State.SessionState {
case api.PeerState_ESTABLISHED:
neigh.State = "up"
default:
neigh.State = "down"
}
neigh.Description = _resp.Peer.Conf.Description
neigh.Id = fmt.Sprintf("%d_%s",neigh.Asn, neigh.Address)
response.Neighbours = append(response.Neighbours, &neigh)
log.Printf("%+v\n", neigh)
for _, afiSafi := range _resp.Peer.AfiSafis {
neigh.RoutesReceived += int(afiSafi.State.Received)
neigh.RoutesExported += int(afiSafi.State.Advertised)
neigh.RoutesAccepted += int(afiSafi.State.Accepted)
neigh.RoutesFiltered += (neigh.RoutesReceived-neigh.RoutesAccepted)
}
if _resp.Peer.Timers.State.Uptime != nil {
neigh.Uptime = time.Now().Sub(time.Unix(_resp.Peer.Timers.State.Uptime.Seconds,int64(_resp.Peer.Timers.State.Uptime.Nanos)))
}
}
log.Printf("%+v\n", response)
/* */
/*type Neighbour struct {
Id string `json:"id"`
// Mandatory fields
Address string `json:"address"`
Asn int `json:"asn"`
State string `json:"state"`
Description string `json:"description"`
RoutesReceived int `json:"routes_received"`
RoutesFiltered int `json:"routes_filtered"`
RoutesExported int `json:"routes_exported"`
RoutesPreferred int `json:"routes_preferred"`
RoutesAccepted int `json:"routes_accepted"`
Uptime time.Duration `json:"uptime"`
LastError string `json:"last_error"`
// Original response
Details map[string]interface{} `json:"details"`
}
*/
return &response, nil
}
// Get neighbors from neighbors summary
func (gobgp *GoBGP) summaryNeighbors() (*aliceapi.NeighboursResponse, error) {
return nil,fmt.Errorf("Not implemented")
return nil,fmt.Errorf("Not implemented summaryNeighbors")
}
// Get neighbors from protocols
func (gobgp *GoBGP) bgpProtocolsNeighbors() (*aliceapi.NeighboursResponse, error) {
return nil,fmt.Errorf("Not implemented")
return nil,fmt.Errorf("Not implemented protocols")
}
// Get filtered and exported routes
func (gobgp *GoBGP) Routes(neighbourId string) (*aliceapi.RoutesResponse, error) {
return nil,fmt.Errorf("Not implemented")
return gobgp.GetRoutes(neighbourId),nil
}
/*
@ -178,32 +174,34 @@ A route deduplication is applied.
*/
func (gobgp *GoBGP) RoutesRequired(neighborId string,) (*aliceapi.RoutesResponse, error) {
return nil,fmt.Errorf("Not implemented")
return nil,fmt.Errorf("Not implemented RoutesRequired")
}
// Get all received routes
func (gobgp *GoBGP) RoutesReceived(neighborId string,) (*aliceapi.RoutesResponse, error) {
return nil,fmt.Errorf("Not implemented")
return gobgp.GetRoutes(neighborId),nil
}
// Get all filtered routes
func (gobgp *GoBGP) RoutesFiltered(neighborId string,) (*aliceapi.RoutesResponse, error) {
return nil,fmt.Errorf("Not implemented")
rr := aliceapi.RoutesResponse{}
return &rr,nil
//return rr,fmt.Errorf("Not implemented RoutesFiltered")
}
// Get all not exported routes
func (gobgp *GoBGP) RoutesNotExported(neighborId string,) (*aliceapi.RoutesResponse, error) {
return nil,fmt.Errorf("Not implemented")
return nil,fmt.Errorf("Not implemented RoutesNotExported")
}
// Make routes lookup
func (gobgp *GoBGP) LookupPrefix(prefix string) (*aliceapi.RoutesLookupResponse, error) {
return nil,fmt.Errorf("Not implemented")
return nil,fmt.Errorf("Not implemented LookupPrefix")
}
func (gobgp *GoBGP) AllRoutes() (*aliceapi.RoutesResponse, error) {
return nil,fmt.Errorf("Not implemented")
return gobgp.GetRoutes(""),nil
}

2
go.mod
View File

@ -4,7 +4,9 @@ require (
github.com/GeertJohan/go.rice v0.0.0-20181229193832-0af3f3b09a0a
github.com/daaku/go.zipexe v0.0.0-20150329023125-a5fe2436ffcb // indirect
github.com/go-ini/ini v1.41.0
github.com/golang/protobuf v1.2.0
github.com/julienschmidt/httprouter v1.2.0
github.com/osrg/gobgp v2.0.0+incompatible
github.com/sirupsen/logrus v1.3.0
google.golang.org/grpc v1.17.0
)

12
go.sum
View File

@ -4,6 +4,7 @@ github.com/GeertJohan/go.rice v0.0.0-20181229193832-0af3f3b09a0a/go.mod h1:DgrzX
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/daaku/go.zipexe v0.0.0-20150329023125-a5fe2436ffcb h1:tUf55Po0vzOendQ7NWytcdK0VuzQmfAgvGBUOQvN0WA=
github.com/daaku/go.zipexe v0.0.0-20150329023125-a5fe2436ffcb/go.mod h1:U0vRfAucUOohvdCxt5MWLF+TePIL0xbCkbKIiV8TQCE=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-ini/ini v1.41.0 h1:526aoxDtxRHFQKMZfcX2OG9oOI8TJ5yPLM0Mkno/uTY=
github.com/go-ini/ini v1.41.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -13,14 +14,25 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/osrg/gobgp v2.0.0+incompatible h1:91ARQbE1AtO0U4TIxHPJ7wYVZIqduyBwS1+FjlHlmrY=
github.com/osrg/gobgp v2.0.0+incompatible/go.mod h1:vGVJPLW6JFDD7WA1vJsjB8OKmbbC2TKwHtr90CZS/u4=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d h1:g9qWBGx4puODJTMVyoPrpoxPFgVGd+z1DZwjfRu4d0I=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522 h1:Ve1ORMCxvRmSXBwJK+t3Oy+V2vRW2OetUQBq4rJIkZE=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=