GoBGP seams to working, alongside github.com/Netnod/gobgp @ 3eaf07cadc4f0033c2b3a777ef24752295f83131
This commit is contained in:
parent
4ff0967a2b
commit
92481b8dc4
@ -1300,4 +1300,4 @@ func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) {
|
||||
return bgp.NewPathAttributeUnknown(bgp.BGPAttrFlag(a.Flags), bgp.BGPAttrType(a.Type), a.Value), nil
|
||||
}
|
||||
return nil, errors.New("unknown path attribute")
|
||||
}
|
||||
}
|
1554
backend/sources/gobgp/apiutil/attribute_test.go
Normal file
1554
backend/sources/gobgp/apiutil/attribute_test.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -243,4 +243,4 @@ func UnmarshalCapabilities(values []*any.Any) ([]bgp.ParameterCapabilityInterfac
|
||||
caps = append(caps, c)
|
||||
}
|
||||
return caps, nil
|
||||
}
|
||||
}
|
||||
|
269
backend/sources/gobgp/apiutil/capability_test.go
Normal file
269
backend/sources/gobgp/apiutil/capability_test.go
Normal file
@ -0,0 +1,269 @@
|
||||
// Copyright (C) 2018 Nippon Telegraph and Telephone Corporation.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package apiutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
api "github.com/osrg/gobgp/api"
|
||||
"github.com/osrg/gobgp/pkg/packet/bgp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_MultiProtocolCapability(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := &api.MultiProtocolCapability{
|
||||
Family: &api.Family{
|
||||
Afi: api.Family_AFI_IP,
|
||||
Safi: api.Family_SAFI_UNICAST,
|
||||
},
|
||||
}
|
||||
|
||||
a, err := ptypes.MarshalAny(input)
|
||||
assert.Nil(err)
|
||||
n, err := unmarshalCapability(a)
|
||||
assert.Nil(err)
|
||||
c := n.(*bgp.CapMultiProtocol)
|
||||
assert.Equal(bgp.RF_IPv4_UC, c.CapValue)
|
||||
|
||||
output := NewMultiProtocolCapability(c)
|
||||
assert.Equal(input, output)
|
||||
}
|
||||
|
||||
func Test_RouteRefreshCapability(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := &api.RouteRefreshCapability{}
|
||||
|
||||
a, err := ptypes.MarshalAny(input)
|
||||
assert.Nil(err)
|
||||
n, err := unmarshalCapability(a)
|
||||
assert.Nil(err)
|
||||
|
||||
output := NewRouteRefreshCapability(n.(*bgp.CapRouteRefresh))
|
||||
assert.Equal(input, output)
|
||||
}
|
||||
|
||||
func Test_CarryingLabelInfoCapability(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := &api.CarryingLabelInfoCapability{}
|
||||
|
||||
a, err := ptypes.MarshalAny(input)
|
||||
assert.Nil(err)
|
||||
n, err := unmarshalCapability(a)
|
||||
assert.Nil(err)
|
||||
|
||||
output := NewCarryingLabelInfoCapability(n.(*bgp.CapCarryingLabelInfo))
|
||||
assert.Equal(input, output)
|
||||
}
|
||||
|
||||
func Test_ExtendedNexthopCapability(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := &api.ExtendedNexthopCapability{
|
||||
Tuples: []*api.ExtendedNexthopCapabilityTuple{
|
||||
{
|
||||
NlriFamily: &api.Family{
|
||||
Afi: api.Family_AFI_IP,
|
||||
Safi: api.Family_SAFI_UNICAST,
|
||||
},
|
||||
NexthopFamily: &api.Family{
|
||||
Afi: api.Family_AFI_IP6,
|
||||
Safi: api.Family_SAFI_UNICAST,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
a, err := ptypes.MarshalAny(input)
|
||||
assert.Nil(err)
|
||||
n, err := unmarshalCapability(a)
|
||||
assert.Nil(err)
|
||||
c := n.(*bgp.CapExtendedNexthop)
|
||||
assert.Equal(1, len(c.Tuples))
|
||||
assert.Equal(uint16(bgp.AFI_IP), c.Tuples[0].NLRIAFI)
|
||||
assert.Equal(uint16(bgp.SAFI_UNICAST), c.Tuples[0].NLRISAFI)
|
||||
assert.Equal(uint16(bgp.AFI_IP6), c.Tuples[0].NexthopAFI)
|
||||
|
||||
output := NewExtendedNexthopCapability(c)
|
||||
assert.Equal(input, output)
|
||||
}
|
||||
|
||||
func Test_GracefulRestartCapability(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := &api.GracefulRestartCapability{
|
||||
Flags: 0x08 | 0x04, // restarting|notification
|
||||
Time: 90,
|
||||
Tuples: []*api.GracefulRestartCapabilityTuple{
|
||||
{
|
||||
Family: &api.Family{
|
||||
Afi: api.Family_AFI_IP,
|
||||
Safi: api.Family_SAFI_UNICAST,
|
||||
},
|
||||
Flags: 0x80, // forward
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
a, err := ptypes.MarshalAny(input)
|
||||
assert.Nil(err)
|
||||
n, err := unmarshalCapability(a)
|
||||
assert.Nil(err)
|
||||
|
||||
c := n.(*bgp.CapGracefulRestart)
|
||||
assert.Equal(1, len(c.Tuples))
|
||||
assert.Equal(uint8(0x08|0x04), c.Flags)
|
||||
assert.Equal(uint16(90), c.Time)
|
||||
assert.Equal(uint16(bgp.AFI_IP), c.Tuples[0].AFI)
|
||||
assert.Equal(uint8(bgp.SAFI_UNICAST), c.Tuples[0].SAFI)
|
||||
assert.Equal(uint8(0x80), c.Tuples[0].Flags)
|
||||
|
||||
output := NewGracefulRestartCapability(c)
|
||||
assert.Equal(input, output)
|
||||
}
|
||||
|
||||
func Test_FourOctetASNumberCapability(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := &api.FourOctetASNumberCapability{
|
||||
As: 100,
|
||||
}
|
||||
|
||||
a, err := ptypes.MarshalAny(input)
|
||||
assert.Nil(err)
|
||||
n, err := unmarshalCapability(a)
|
||||
assert.Nil(err)
|
||||
|
||||
c := n.(*bgp.CapFourOctetASNumber)
|
||||
assert.Equal(uint32(100), c.CapValue)
|
||||
|
||||
output := NewFourOctetASNumberCapability(c)
|
||||
assert.Equal(input, output)
|
||||
}
|
||||
|
||||
func Test_AddPathCapability(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := &api.AddPathCapability{
|
||||
Tuples: []*api.AddPathCapabilityTuple{
|
||||
{
|
||||
Family: &api.Family{
|
||||
Afi: api.Family_AFI_IP,
|
||||
Safi: api.Family_SAFI_UNICAST,
|
||||
},
|
||||
Mode: api.AddPathMode_MODE_BOTH,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
a, err := ptypes.MarshalAny(input)
|
||||
assert.Nil(err)
|
||||
n, err := unmarshalCapability(a)
|
||||
assert.Nil(err)
|
||||
|
||||
c := n.(*bgp.CapAddPath)
|
||||
assert.Equal(1, len(c.Tuples))
|
||||
assert.Equal(bgp.RF_IPv4_UC, c.Tuples[0].RouteFamily)
|
||||
assert.Equal(bgp.BGP_ADD_PATH_BOTH, c.Tuples[0].Mode)
|
||||
|
||||
output := NewAddPathCapability(c)
|
||||
assert.Equal(input, output)
|
||||
}
|
||||
|
||||
func Test_EnhancedRouteRefreshCapability(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := &api.EnhancedRouteRefreshCapability{}
|
||||
|
||||
a, err := ptypes.MarshalAny(input)
|
||||
assert.Nil(err)
|
||||
n, err := unmarshalCapability(a)
|
||||
assert.Nil(err)
|
||||
|
||||
output := NewEnhancedRouteRefreshCapability(n.(*bgp.CapEnhancedRouteRefresh))
|
||||
assert.Equal(input, output)
|
||||
}
|
||||
|
||||
func Test_LongLivedGracefulRestartCapability(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := &api.LongLivedGracefulRestartCapability{
|
||||
Tuples: []*api.LongLivedGracefulRestartCapabilityTuple{
|
||||
{
|
||||
Family: &api.Family{
|
||||
Afi: api.Family_AFI_IP,
|
||||
Safi: api.Family_SAFI_UNICAST,
|
||||
},
|
||||
Flags: 0x80, // forward
|
||||
Time: 90,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
a, err := ptypes.MarshalAny(input)
|
||||
assert.Nil(err)
|
||||
n, err := unmarshalCapability(a)
|
||||
assert.Nil(err)
|
||||
|
||||
c := n.(*bgp.CapLongLivedGracefulRestart)
|
||||
assert.Equal(1, len(c.Tuples))
|
||||
assert.Equal(uint16(bgp.AFI_IP), c.Tuples[0].AFI)
|
||||
assert.Equal(uint8(bgp.SAFI_UNICAST), c.Tuples[0].SAFI)
|
||||
assert.Equal(uint8(0x80), c.Tuples[0].Flags)
|
||||
assert.Equal(uint32(90), c.Tuples[0].RestartTime)
|
||||
|
||||
output := NewLongLivedGracefulRestartCapability(c)
|
||||
assert.Equal(input, output)
|
||||
}
|
||||
|
||||
func Test_RouteRefreshCiscoCapability(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := &api.RouteRefreshCiscoCapability{}
|
||||
|
||||
a, err := ptypes.MarshalAny(input)
|
||||
assert.Nil(err)
|
||||
n, err := unmarshalCapability(a)
|
||||
assert.Nil(err)
|
||||
|
||||
output := NewRouteRefreshCiscoCapability(n.(*bgp.CapRouteRefreshCisco))
|
||||
assert.Equal(input, output)
|
||||
}
|
||||
|
||||
func Test_UnknownCapability(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
input := &api.UnknownCapability{
|
||||
Code: 0xff,
|
||||
Value: []byte{0x11, 0x22, 0x33, 0x44},
|
||||
}
|
||||
|
||||
a, err := ptypes.MarshalAny(input)
|
||||
assert.Nil(err)
|
||||
n, err := unmarshalCapability(a)
|
||||
assert.Nil(err)
|
||||
|
||||
c := n.(*bgp.CapUnknown)
|
||||
assert.Equal(bgp.BGPCapabilityCode(0xff), c.CapCode)
|
||||
assert.Equal([]byte{0x11, 0x22, 0x33, 0x44}, c.CapValue)
|
||||
|
||||
output := NewUnknownCapability(c)
|
||||
assert.Equal(input, output)
|
||||
}
|
@ -125,4 +125,4 @@ func ToApiFamily(afi uint16, safi uint8) *api.Family {
|
||||
Afi: api.Family_Afi(afi),
|
||||
Safi: api.Family_Safi(safi),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ func NewRoutesResponse() (aliceapi.RoutesResponse) {
|
||||
}
|
||||
|
||||
func generatePeerId(peer *api.Peer) string {
|
||||
return fmt.Sprintf("%d_%s",peer.State.PeerAs, peer.State.NeighborAddress)
|
||||
return PeerHash(peer)
|
||||
}
|
||||
|
||||
func (gobgp *GoBGP) lookupNeighbour(neighborId string) (*api.Peer,error) {
|
||||
@ -88,22 +88,24 @@ func (gobgp *GoBGP) GetRoutes(peer *api.Peer, tableType api.TableType, rr *alice
|
||||
return nil
|
||||
}
|
||||
|
||||
rib := make([]*api.Destination,0)
|
||||
for {
|
||||
_path, err := pathStream.Recv()
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
log.Print(err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
for _, path := range _path.Destination.Paths {
|
||||
|
||||
log.Printf("%+v", _path)
|
||||
|
||||
rib = append(rib, _path.Destination)
|
||||
}
|
||||
|
||||
for _, d := range rib {
|
||||
for _, path := range d.Paths {
|
||||
r := aliceapi.Route{}
|
||||
r.Id = fmt.Sprintf("%d_%s", path.Identifier, _path.Destination.Prefix)
|
||||
r.Id = fmt.Sprintf("%d_%s", path.Identifier, d.Prefix)
|
||||
r.NeighbourId = generatePeerId(peer)
|
||||
r.Network = _path.Destination.Prefix
|
||||
r.Network = d.Prefix
|
||||
r.Interface = "Unknown"
|
||||
r.Age = time.Now().Sub(time.Unix(path.Age.GetSeconds(),int64(path.Age.GetNanos())))
|
||||
r.Primary = path.Best
|
||||
@ -152,18 +154,19 @@ func (gobgp *GoBGP) GetRoutes(peer *api.Peer, tableType api.TableType, rr *alice
|
||||
case *bgp.PathAttributeExtendedCommunities:
|
||||
communities := attr.(*bgp.PathAttributeExtendedCommunities)
|
||||
for _, community := range communities.Value {
|
||||
log.Printf("%+s\n", community)
|
||||
if _community, ok := community.(*bgp.TwoOctetAsSpecificExtended); ok {
|
||||
r.Bgp.ExtCommunities = append(r.Bgp.ExtCommunities, aliceapi.ExtCommunity{_community.AS, _community.LocalAdmin})
|
||||
}
|
||||
}
|
||||
case *bgp.PathAttributeLargeCommunities:
|
||||
communities := attr.(*bgp.PathAttributeLargeCommunities)
|
||||
for _, community := range communities.Values {
|
||||
log.Printf("%+s\n", community)
|
||||
r.Bgp.LargeCommunities = append(r.Bgp.LargeCommunities, aliceapi.Community{int(community.ASN), int(community.LocalData1), int(community.LocalData2)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r.Metric = (r.Bgp.LocalPref + r.Bgp.Med)
|
||||
|
||||
if path.Filtered {
|
||||
rr.Filtered = append(rr.Filtered, &r)
|
||||
} else {
|
||||
@ -172,6 +175,6 @@ func (gobgp *GoBGP) GetRoutes(peer *api.Peer, tableType api.TableType, rr *alice
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Printf("%+v", rr)
|
||||
|
||||
return nil
|
||||
}
|
@ -124,7 +124,7 @@ func (gobgp *GoBGP) Neighbours() (*aliceapi.NeighboursResponse, error) {
|
||||
}
|
||||
neigh.Description = _resp.Peer.Conf.Description
|
||||
|
||||
neigh.Id = fmt.Sprintf("%d_%s",neigh.Asn, neigh.Address)
|
||||
neigh.Id = PeerHash(_resp.Peer)
|
||||
|
||||
|
||||
response.Neighbours = append(response.Neighbours, &neigh)
|
||||
@ -147,6 +147,7 @@ func (gobgp *GoBGP) Neighbours() (*aliceapi.NeighboursResponse, error) {
|
||||
|
||||
// Get neighbors from neighbors summary
|
||||
func (gobgp *GoBGP) summaryNeighbors() (*aliceapi.NeighboursResponse, error) {
|
||||
|
||||
return nil,fmt.Errorf("Not implemented summaryNeighbors")
|
||||
}
|
||||
|
||||
@ -183,8 +184,22 @@ RoutesNotExported() API.
|
||||
A route deduplication is applied.
|
||||
*/
|
||||
|
||||
func (gobgp *GoBGP) getRoutes(neighbourId string,) (*aliceapi.RoutesResponse, error) {
|
||||
neigh, err := gobgp.lookupNeighbour(neighbourId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
routes := NewRoutesResponse();
|
||||
err = gobgp.GetRoutes(neigh,api.TableType_ADJ_IN,&routes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &routes,nil
|
||||
}
|
||||
|
||||
func (gobgp *GoBGP) RoutesRequired(neighbourId string,) (*aliceapi.RoutesResponse, error) {
|
||||
return nil,fmt.Errorf("Not implemented RoutesRequired")
|
||||
return gobgp.getRoutes(neighbourId)
|
||||
}
|
||||
|
||||
|
||||
@ -200,22 +215,16 @@ func (gobgp *GoBGP) RoutesReceived(neighbourId string,) (*aliceapi.RoutesRespons
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
routes.Filtered = nil
|
||||
return &routes,nil
|
||||
}
|
||||
|
||||
|
||||
// Get all filtered routes
|
||||
func (gobgp *GoBGP) RoutesFiltered(neighbourId string,) (*aliceapi.RoutesResponse, error) {
|
||||
neigh, err := gobgp.lookupNeighbour(neighbourId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
routes := NewRoutesResponse();
|
||||
err = gobgp.GetRoutes(neigh,api.TableType_ADJ_IN,&routes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &routes,nil
|
||||
routes, err := gobgp.getRoutes(neighbourId)
|
||||
routes.Imported = nil
|
||||
return routes, err
|
||||
}
|
||||
|
||||
// Get all not exported routes
|
||||
@ -225,13 +234,12 @@ func (gobgp *GoBGP) RoutesNotExported(neighbourId string,) (*aliceapi.RoutesResp
|
||||
return nil, err
|
||||
}
|
||||
routes := NewRoutesResponse();
|
||||
err = gobgp.GetRoutes(neigh,api.TableType_ADJ_OUT,&routes)
|
||||
err = gobgp.GetRoutes(neigh,api.TableType_LOCAL,&routes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
routes.Imported = nil
|
||||
return &routes,nil
|
||||
|
||||
return nil,fmt.Errorf("Not implemented RoutesNotExported")
|
||||
}
|
||||
|
||||
// Make routes lookup
|
||||
@ -239,6 +247,11 @@ func (gobgp *GoBGP) LookupPrefix(prefix string) (*aliceapi.RoutesLookupResponse,
|
||||
return nil,fmt.Errorf("Not implemented LookupPrefix")
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
AllRoutes:
|
||||
Here a routes dump (filtered, received) is returned, which is used to learn all prefixes to build up a local store for searching.
|
||||
*/
|
||||
func (gobgp *GoBGP) AllRoutes() (*aliceapi.RoutesResponse, error) {
|
||||
routes := NewRoutesResponse();
|
||||
peers, err := gobgp.GetNeighbours()
|
||||
|
21
backend/sources/gobgp/utils.go
Normal file
21
backend/sources/gobgp/utils.go
Normal file
@ -0,0 +1,21 @@
|
||||
package gobgp;
|
||||
|
||||
import (
|
||||
// Standard imports
|
||||
"crypto/sha1"
|
||||
"io"
|
||||
"fmt"
|
||||
|
||||
// External imports
|
||||
api "github.com/osrg/gobgp/api"
|
||||
|
||||
// Internal imports
|
||||
)
|
||||
|
||||
func PeerHash(peer *api.Peer) (string) {
|
||||
h := sha1.New()
|
||||
io.WriteString(h, string(peer.State.PeerAs))
|
||||
io.WriteString(h, peer.State.NeighborAddress)
|
||||
sum := h.Sum(nil)
|
||||
return fmt.Sprintf("%x",sum[0:5])
|
||||
}
|
1
go.mod
1
go.mod
@ -2,6 +2,7 @@ module github.com/alice-lg/alice-lg
|
||||
|
||||
require (
|
||||
github.com/GeertJohan/go.rice v0.0.0-20181229193832-0af3f3b09a0a
|
||||
github.com/Netnod/gobgp v2.0.0+incompatible
|
||||
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
|
||||
|
2
go.sum
2
go.sum
@ -1,6 +1,8 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/GeertJohan/go.rice v0.0.0-20181229193832-0af3f3b09a0a h1:QgnJzkfb29JXtLXJN8alxzPWZhiNcAYZOa06dU5O46w=
|
||||
github.com/GeertJohan/go.rice v0.0.0-20181229193832-0af3f3b09a0a/go.mod h1:DgrzXonpdQbfN3uYaGz1EG4Sbhyum/MMIn6Cphlh2bw=
|
||||
github.com/Netnod/gobgp v2.0.0+incompatible h1:HNS9LlIdLKG9vDlyGGkdEEWlvg7XrBqeCsLI5aCokww=
|
||||
github.com/Netnod/gobgp v2.0.0+incompatible/go.mod h1:3nV4IxumgQWTcmCIRAdfoB74YRw1FOUqaDMKdK2ZAZI=
|
||||
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=
|
||||
|
Loading…
x
Reference in New Issue
Block a user