Skip to content
Snippets Groups Projects
Unverified Commit 9dbf70f2 authored by Daniel Czerwonk's avatar Daniel Czerwonk Committed by GitHub
Browse files

Merge branch 'master' into feature/ipv6_support_mp_reach

parents 356850b7 b3c3d0c9
Branches
Tags
No related merge requests found
......@@ -28,7 +28,7 @@ type Route struct {
ecmpPaths uint
}
// NewRoute generates a new route with paths p
// NewRoute generates a new route with path p
func NewRoute(pfx net.Prefix, p *Path) *Route {
r := &Route{
pfx: pfx,
......@@ -43,6 +43,23 @@ func NewRoute(pfx net.Prefix, p *Path) *Route {
return r
}
// NewRouteAddPath generates a new route with paths p
func NewRouteAddPath(pfx net.Prefix, p []*Path) *Route {
r := &Route{
pfx: pfx,
}
if p == nil {
r.paths = make([]*Path, 0)
return r
}
for _, path := range p {
r.paths = append(r.paths, path)
}
return r
}
// Copy returns a copy of route r
func (r *Route) Copy() *Route {
if r == nil {
......
......@@ -19,10 +19,17 @@ go_library(
go_test(
name = "go_default_test",
srcs = ["path_id_manager_test.go"],
srcs = [
"adj_rib_out_test.go",
"path_id_manager_test.go",
],
embed = [":go_default_library"],
deps = [
"//net:go_default_library",
"//protocols/bgp/types:go_default_library",
"//route:go_default_library",
"//routingtable:go_default_library",
"//routingtable/filter:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",
],
)
......@@ -47,6 +47,9 @@ func (a *AdjRIBOut) RouteCount() int64 {
// AddPath adds path p to prefix `pfx`
func (a *AdjRIBOut) AddPath(pfx bnet.Prefix, p *route.Path) error {
if !routingtable.ShouldPropagateUpdate(pfx, p, a.neighbor) {
if a.neighbor.CapAddPathRX {
a.removePathsForPrefix(pfx)
}
return nil
}
......@@ -55,6 +58,7 @@ func (a *AdjRIBOut) AddPath(pfx bnet.Prefix, p *route.Path) error {
return nil
}
// If the neighbor is an eBGP peer and not a Route Server client modify ASPath and Next Hop
p = p.Copy()
if !a.neighbor.IBGP && !a.neighbor.RouteServerClient {
p.BGPPath.Prepend(a.neighbor.LocalASN, 1)
......@@ -130,6 +134,25 @@ func (a *AdjRIBOut) RemovePath(pfx bnet.Prefix, p *route.Path) bool {
return true
}
func (a *AdjRIBOut) removePathsForPrefix(pfx bnet.Prefix) bool {
// We were called before a.AddPath() had a lock, so we need to lock here and release it
// after the get to prevent a dead lock as RemovePath() will acquire a lock itself!
a.mu.Lock()
r := a.rt.Get(pfx)
a.mu.Unlock()
// If no path with this prefix is present, we're done
if r == nil {
return false
}
for _, path := range r.Paths() {
a.RemovePath(pfx, path)
}
return true
}
func (a *AdjRIBOut) isOwnPath(p *route.Path) bool {
if p.Type != a.neighbor.Type {
return false
......
package adjRIBOut
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/bio-routing/bio-rd/net"
"github.com/bio-routing/bio-rd/protocols/bgp/types"
"github.com/bio-routing/bio-rd/routingtable/filter"
"github.com/bio-routing/bio-rd/route"
"github.com/bio-routing/bio-rd/routingtable"
)
func TestBestPathOnlyEBGP(t *testing.T) {
neighborBestOnlyEBGP := &routingtable.Neighbor{
Type: route.BGPPathType,
LocalAddress: net.IPv4FromOctets(127, 0, 0, 1),
Address: net.IPv4FromOctets(127, 0, 0, 2),
IBGP: false,
LocalASN: 41981,
RouteServerClient: false,
CapAddPathRX: false,
}
adjRIBOut := New(neighborBestOnlyEBGP, filter.NewAcceptAllFilter())
tests := []struct {
name string
routesAdd []*route.Route
routesRemove []*route.Route
expected []*route.Route
expectedCount int64
}{
{
name: "Add a valid route",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{},
}),
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
neighborBestOnlyEBGP.LocalASN,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: false,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expectedCount: 1,
},
{
name: "Try to remove unpresent route",
routesRemove: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
neighborBestOnlyEBGP.LocalASN,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 1,
EBGP: false,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
neighborBestOnlyEBGP.LocalASN,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: false,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expectedCount: 1,
},
{
name: "Remove route added in first step",
routesRemove: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
neighborBestOnlyEBGP.LocalASN,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: false,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expected: []*route.Route{},
expectedCount: 0,
},
{
name: "Try to add route with NO_EXPORT community set",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
Communities: []uint32{
types.WellKnownCommunityNoExport,
},
},
}),
},
expected: []*route.Route{},
},
{
name: "Try to add route with NO_ADVERTISE community set",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
Communities: []uint32{
types.WellKnownCommunityNoAdvertise,
},
},
}),
},
expected: []*route.Route{},
expectedCount: 0,
},
{
name: "Re-add valid route again",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{},
}),
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
neighborBestOnlyEBGP.LocalASN,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: false,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expectedCount: 1,
},
{
name: "Try to remove route with NO_EXPORT community set",
routesRemove: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
neighborBestOnlyEBGP.LocalASN,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: false,
Communities: []uint32{
types.WellKnownCommunityNoExport,
},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
neighborBestOnlyEBGP.LocalASN,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: false,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expectedCount: 1,
},
{
name: "Try to remove non-existent prefix",
routesRemove: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 23, 42, 0), 24), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{},
}),
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{NextHop: neighborBestOnlyEBGP.LocalAddress,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
neighborBestOnlyEBGP.LocalASN,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: false,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expectedCount: 1,
},
}
for i, test := range tests {
fmt.Printf("Running eBGP best only test #%d: %s\n", i+1, test.name)
for _, route := range test.routesAdd {
adjRIBOut.AddPath(route.Prefix(), route.Paths()[0])
}
for _, route := range test.routesRemove {
adjRIBOut.RemovePath(route.Prefix(), route.Paths()[0])
}
assert.Equal(t, test.expected, adjRIBOut.rt.Dump())
actualCount := adjRIBOut.RouteCount()
if test.expectedCount != actualCount {
t.Errorf("Expected route count %d differs from actual route count %d!\n", test.expectedCount, actualCount)
}
}
}
func TestBestPathOnlyIBGP(t *testing.T) {
neighborBestOnlyEBGP := &routingtable.Neighbor{
Type: route.BGPPathType,
LocalAddress: net.IPv4FromOctets(127, 0, 0, 1),
Address: net.IPv4FromOctets(127, 0, 0, 2),
IBGP: true,
LocalASN: 41981,
RouteServerClient: false,
CapAddPathRX: false,
}
adjRIBOut := New(neighborBestOnlyEBGP, filter.NewAcceptAllFilter())
tests := []struct {
name string
routesAdd []*route.Route
routesRemove []*route.Route
expected []*route.Route
expectedCount int64
}{
{
name: "Add an iBGP route (without success)",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{},
}),
},
expected: []*route.Route{},
expectedCount: 0,
},
{
name: "Add an eBGP route (with success)",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
EBGP: true,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
},
}),
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expectedCount: 1,
},
{
name: "Try to remove slightly different route",
routesRemove: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 1,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expectedCount: 1,
},
{
name: "Remove route added in 2nd step",
routesRemove: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expected: []*route.Route{},
expectedCount: 0,
},
{
name: "Try to add route with NO_EXPORT community set (without success)",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
Communities: []uint32{
types.WellKnownCommunityNoExport,
},
},
}),
},
expected: []*route.Route{},
},
{
name: "Try to add route with NO_EXPORT community set (without success)",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
Communities: []uint32{
types.WellKnownCommunityNoAdvertise,
},
},
}),
},
expected: []*route.Route{},
},
}
for i, test := range tests {
fmt.Printf("Running iBGP best only test #%d: %s\n", i+1, test.name)
for _, route := range test.routesAdd {
adjRIBOut.AddPath(route.Prefix(), route.Paths()[0])
}
for _, route := range test.routesRemove {
adjRIBOut.RemovePath(route.Prefix(), route.Paths()[0])
}
assert.Equal(t, test.expected, adjRIBOut.rt.Dump())
actualCount := adjRIBOut.RouteCount()
if test.expectedCount != actualCount {
t.Errorf("Expected route count %d differs from actual route count %d!\n", test.expectedCount, actualCount)
}
}
}
/*
* Test for AddPath capabale peer / AdjRIBOut
*/
func TestAddPathIBGP(t *testing.T) {
neighborBestOnlyEBGP := &routingtable.Neighbor{
Type: route.BGPPathType,
LocalAddress: net.IPv4FromOctets(127, 0, 0, 1),
Address: net.IPv4FromOctets(127, 0, 0, 2),
IBGP: true,
LocalASN: 41981,
RouteServerClient: false,
CapAddPathRX: true,
}
adjRIBOut := New(neighborBestOnlyEBGP, filter.NewAcceptAllFilter())
tests := []struct {
name string
routesAdd []*route.Route
routesRemove []*route.Route
expected []*route.Route
expectedCount int64
}{
{
name: "Add an iBGP route (without success)",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{},
}),
},
expected: []*route.Route{},
expectedCount: 0,
},
{
name: "Add an eBGP route (with success)",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
EBGP: true,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
},
}),
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 1,
LocalPref: 0,
Source: net.IP{}},
}),
},
expectedCount: 1,
},
{
name: "Try to remove slightly different route",
routesRemove: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 1, // MED of route present in table is 0
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 1,
LocalPref: 0,
Source: net.IP{}},
}),
},
expectedCount: 1,
},
{
name: "Remove route added in 2nd step",
routesRemove: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0, // We calculate PathID in RIBOut so none is present when removing from RIBOut
LocalPref: 0,
Source: net.IP{}},
}),
},
expected: []*route.Route{},
expectedCount: 0,
},
{
name: "Try to add route with NO_EXPORT community set (without success)",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
Communities: []uint32{
types.WellKnownCommunityNoExport,
},
},
}),
},
expected: []*route.Route{},
expectedCount: 0,
},
{
name: "Try to add route with NO_EXPORT community set (without success)",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
Communities: []uint32{
types.WellKnownCommunityNoAdvertise,
},
},
}),
},
expected: []*route.Route{},
expectedCount: 0,
},
// Ok table is empty, re add previous route
{
name: "Readd an eBGP route (with success)",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
EBGP: true,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
},
}),
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 2,
LocalPref: 0,
Source: net.IP{}},
}),
},
expectedCount: 1,
},
{
name: "Add 2nd path to existing one with different NH (with success)",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
EBGP: true,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
NextHop: net.IPv4FromOctets(2, 3, 4, 5),
},
}),
},
expected: []*route.Route{
route.NewRouteAddPath(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), []*route.Path{
&route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 2,
LocalPref: 0,
Source: net.IP{}},
},
&route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(2, 3, 4, 5),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 3,
LocalPref: 0,
Source: net.IP{}},
}}),
},
expectedCount: 1,
},
{
name: "Remove 2nd path added above",
routesRemove: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(2, 3, 4, 5),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 0,
LocalPref: 0,
Source: net.IP{}},
}),
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 2,
LocalPref: 0,
Source: net.IP{}},
}),
},
expectedCount: 1,
},
{
name: "Re-add 2nd path to existing one with different NH (with success)",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
EBGP: true,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
NextHop: net.IPv4FromOctets(3, 4, 5, 6),
},
}),
},
expected: []*route.Route{
route.NewRouteAddPath(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), []*route.Path{
&route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 2,
LocalPref: 0,
Source: net.IP{}},
},
&route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(3, 4, 5, 6),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 4,
LocalPref: 0,
Source: net.IP{}},
}}),
},
expectedCount: 1,
},
{
name: "Add 3rd path to existing ones, containing NO_EXPORT community (successful)",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
EBGP: true,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
NextHop: net.IPv4FromOctets(4, 5, 6, 7),
Communities: []uint32{
types.WellKnownCommunityNoExport,
},
},
}),
},
expected: []*route.Route{
route.NewRouteAddPath(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), []*route.Path{
&route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(1, 2, 3, 4),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 2,
LocalPref: 0,
Source: net.IP{}},
},
&route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(3, 4, 5, 6),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 4,
LocalPref: 0,
Source: net.IP{}},
},
&route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
NextHop: net.IPv4FromOctets(4, 5, 6, 7),
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
Origin: 0,
MED: 0,
EBGP: true,
Communities: []uint32{
types.WellKnownCommunityNoExport,
},
LargeCommunities: []types.LargeCommunity{},
UnknownAttributes: nil,
PathIdentifier: 5,
LocalPref: 0,
Source: net.IP{}},
},
}),
},
expectedCount: 1,
},
{
name: "Add 4th path to existing ones, containing NO_ADVERTISE community",
routesAdd: []*route.Route{
route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
EBGP: true,
ASPath: types.ASPath{
types.ASPathSegment{
Type: types.ASSequence,
ASNs: []uint32{
201701,
},
},
},
ASPathLen: 1,
NextHop: net.IPv4FromOctets(5, 6, 7, 8),
Communities: []uint32{
types.WellKnownCommunityNoAdvertise,
},
},
}),
},
expected: []*route.Route{},
expectedCount: 0,
},
}
for i, test := range tests {
fmt.Printf("Running iBGP AddPath test #%d: %s\n", i+1, test.name)
for _, route := range test.routesAdd {
adjRIBOut.AddPath(route.Prefix(), route.Paths()[0])
}
for _, route := range test.routesRemove {
adjRIBOut.RemovePath(route.Prefix(), route.Paths()[0])
}
assert.Equal(t, test.expected, adjRIBOut.rt.Dump())
actualCount := adjRIBOut.RouteCount()
if test.expectedCount != actualCount {
t.Errorf("Expected route count %d differs from actual route count %d!\n", test.expectedCount, actualCount)
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment