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

Merge pull request #41 from hikhvar/improvement/increased-test-coverage

Bugfix and increased test coverage
parents ec587cf4 59fbc525
No related branches found
No related tags found
No related merge requests found
...@@ -1580,6 +1580,212 @@ func TestSerialize(t *testing.T) { ...@@ -1580,6 +1580,212 @@ func TestSerialize(t *testing.T) {
} }
} }
func TestSerializeAddPath(t *testing.T) {
tests := []struct {
name string
msg *BGPUpdateAddPath
expected []byte
wantFail bool
}{
{
name: "Withdraw only",
msg: &BGPUpdateAddPath{
WithdrawnRoutes: &NLRIAddPath{
PathIdentifier: 257,
IP: strAddr("100.110.120.0"),
Pfxlen: 24,
},
},
expected: []byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0, 31, // Length
2, // Msg Type
0, 8, // Withdrawn Routes Length
0, 0, 1, 1, // Path Identifier
24, 100, 110, 120, // NLRI
0, 0, // Total Path Attribute Length
},
},
{
name: "NLRI only",
msg: &BGPUpdateAddPath{
NLRI: &NLRIAddPath{
PathIdentifier: 257,
IP: strAddr("100.110.128.0"),
Pfxlen: 17,
},
},
expected: []byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0, 31, // Length
2, // Msg Type
0, 0, // Withdrawn Routes Length
0, 0, // Total Path Attribute Length
0, 0, 1, 1, // Path Identifier
17, 100, 110, 128, // NLRI
},
},
{
name: "Path Attributes only",
msg: &BGPUpdateAddPath{
PathAttributes: &PathAttribute{
Optional: true,
Transitive: true,
TypeCode: OriginAttr,
Value: uint8(0), // IGP
},
},
expected: []byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0, 27, // Length
2, // Msg Type
0, 0, // Withdrawn Routes Length
0, 4, // Total Path Attribute Length
64, // Attr. Flags
1, // Attr. Type Code
1, // Length
0, // Value
},
},
{
name: "Full test",
msg: &BGPUpdateAddPath{
WithdrawnRoutes: &NLRIAddPath{
IP: strAddr("10.0.0.0"),
Pfxlen: 8,
Next: &NLRIAddPath{
IP: strAddr("192.168.0.0"),
Pfxlen: 16,
},
},
PathAttributes: &PathAttribute{
TypeCode: OriginAttr,
Value: uint8(0),
Next: &PathAttribute{
TypeCode: ASPathAttr,
Value: ASPath{
{
Type: 2,
ASNs: []uint32{100, 155, 200},
},
{
Type: 1,
ASNs: []uint32{10, 20},
},
},
Next: &PathAttribute{
TypeCode: NextHopAttr,
Value: strAddr("10.20.30.40"),
Next: &PathAttribute{
TypeCode: MEDAttr,
Value: uint32(100),
Next: &PathAttribute{
TypeCode: LocalPrefAttr,
Value: uint32(500),
Next: &PathAttribute{
TypeCode: AtomicAggrAttr,
Next: &PathAttribute{
TypeCode: AggregatorAttr,
Value: uint16(200),
},
},
},
},
},
},
},
NLRI: &NLRIAddPath{
IP: strAddr("8.8.8.0"),
Pfxlen: 24,
Next: &NLRIAddPath{
IP: strAddr("185.65.240.0"),
Pfxlen: 22,
},
},
},
expected: []byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0, 102, // Length
2, // Msg Type
// Withdraws
0, 13, // Withdrawn Routes Length
0, 0, 0, 0, // Path Identifier
8, 10, // Withdraw 10/8
0, 0, 0, 0, // Path Identifier
16, 192, 168, // Withdraw 192.168/16
0, 50, // Total Path Attribute Length
// ORIGIN
64, // Attr. Flags
1, // Attr. Type Code
1, // Length
0, // Value
// ASPath
64, // Attr. Flags
2, // Attr. Type Code
14, // Attr. Length
2, // Path Segment Type = AS_SEQUENCE
3, // Path Segment Length
0, 100, 0, 155, 0, 200, // ASNs
1, // Path Segment Type = AS_SET
2, // Path Segment Type = AS_SET
0, 10, 0, 20, // ASNs
// Next Hop
64, // Attr. Flags
3, // Attr. Type Code
4, // Length
10, 20, 30, 40, // Next Hop Address
// MED
128, // Attr. Flags
4, // Attr Type Code
4, // Length
0, 0, 0, 100, // MED = 100
// LocalPref
64, // Attr. Flags
5, // Attr. Type Code
4, // Length
0, 0, 1, 244, // Localpref
// Atomic Aggregate
64, // Attr. Flags
6, // Attr. Type Code
0, // Length
// Aggregator
192, // Attr. Flags
7, // Attr. Type Code
2, // Length
0, 200, // Aggregator ASN = 200
// NLRI
0, 0, 0, 0, // Path Identifier
24, 8, 8, 8, // 8.8.8.0/24
0, 0, 0, 0, // Path Identifier
22, 185, 65, 240, // 185.65.240.0/22
},
},
}
for _, test := range tests {
res, err := test.msg.SerializeUpdate()
if err != nil {
if test.wantFail {
continue
}
t.Errorf("Unexpected failure for test %q: %v", test.name, err)
continue
}
if test.wantFail {
t.Errorf("Unexpected success for test %q", test.name)
continue
}
assert.Equalf(t, test.expected, res, "%s", test.name)
}
}
func TestParseASPathStr(t *testing.T) { func TestParseASPathStr(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
......
...@@ -2,10 +2,12 @@ package server ...@@ -2,10 +2,12 @@ package server
import ( import (
"fmt" "fmt"
"io"
"strings" "strings"
"github.com/bio-routing/bio-rd/protocols/bgp/packet" "github.com/bio-routing/bio-rd/protocols/bgp/packet"
"github.com/bio-routing/bio-rd/route" "github.com/bio-routing/bio-rd/route"
log "github.com/sirupsen/logrus"
) )
func pathAttribues(p *route.Path, fsm *FSM) (*packet.PathAttribute, error) { func pathAttribues(p *route.Path, fsm *FSM) (*packet.PathAttribute, error) {
...@@ -68,3 +70,21 @@ func addOptionalPathAttribues(p *route.Path, parent *packet.PathAttribute) error ...@@ -68,3 +70,21 @@ func addOptionalPathAttribues(p *route.Path, parent *packet.PathAttribute) error
return nil return nil
} }
type serializeAbleUpdate interface {
SerializeUpdate() ([]byte, error)
}
func serializeAndSendUpdate(out io.Writer, update serializeAbleUpdate) error {
updateBytes, err := update.SerializeUpdate()
if err != nil {
log.Errorf("Unable to serialize BGP Update: %v", err)
return nil
}
_, err = out.Write(updateBytes)
if err != nil {
return fmt.Errorf("Failed sending Update: %v", err)
}
return nil
}
package server
import (
"io"
"testing"
"bytes"
"github.com/bio-routing/bio-rd/protocols/bgp/packet"
"errors"
"github.com/bio-routing/bio-rd/net"
"github.com/stretchr/testify/assert"
)
type failingUpdate struct{}
func (f *failingUpdate) SerializeUpdate() ([]byte, error) {
return nil, errors.New("general error")
}
type WriterByter interface {
Bytes() []byte
io.Writer
}
type failingReadWriter struct {
}
func (f *failingReadWriter) Write(p []byte) (n int, err error) {
return 0, errors.New("general error")
}
func (f *failingReadWriter) Bytes() []byte {
return []byte{}
}
func TestSerializeAndSendUpdate(t *testing.T) {
tests := []struct {
name string
buf WriterByter
err error
testUpdate serializeAbleUpdate
expected []byte
}{
{
name: "normal bgp update",
buf: bytes.NewBuffer(nil),
err: nil,
testUpdate: &packet.BGPUpdate{
WithdrawnRoutesLen: 5,
WithdrawnRoutes: &packet.NLRI{
IP: strAddr("10.0.0.0"),
Pfxlen: 8,
Next: &packet.NLRI{
IP: strAddr("192.168.0.0"),
Pfxlen: 16,
},
},
},
expected: []byte{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // Marker
0, 28, // Length
2, // Type = Update
0, 5, 8, 10, 16, 192, 168, 0, 0, // 2 withdraws
},
},
{
name: "failed serialization",
buf: bytes.NewBuffer(nil),
err: nil,
testUpdate: &failingUpdate{},
expected: nil,
},
{
name: "failed connection",
buf: &failingReadWriter{},
err: errors.New("Failed sending Update: general error"),
testUpdate: &packet.BGPUpdate{
WithdrawnRoutesLen: 5,
WithdrawnRoutes: &packet.NLRI{
IP: strAddr("10.0.0.0"),
Pfxlen: 8,
Next: &packet.NLRI{
IP: strAddr("192.168.0.0"),
Pfxlen: 16,
},
},
},
expected: []byte{},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := serializeAndSendUpdate(test.buf, test.testUpdate)
assert.Equal(t, test.err, err)
assert.Equal(t, test.expected, test.buf.Bytes())
})
}
}
func strAddr(s string) uint32 {
ret, _ := net.StrToAddr(s)
return ret
}
...@@ -34,26 +34,15 @@ func (u *UpdateSender) AddPath(pfx net.Prefix, p *route.Path) error { ...@@ -34,26 +34,15 @@ func (u *UpdateSender) AddPath(pfx net.Prefix, p *route.Path) error {
return nil return nil
} }
update := &packet.BGPUpdateAddPath{ update := &packet.BGPUpdate{
PathAttributes: pathAttrs, PathAttributes: pathAttrs,
NLRI: &packet.NLRIAddPath{ NLRI: &packet.NLRI{
PathIdentifier: p.BGPPath.PathIdentifier, IP: pfx.Addr(),
IP: pfx.Addr(), Pfxlen: pfx.Pfxlen(),
Pfxlen: pfx.Pfxlen(),
}, },
} }
updateBytes, err := update.SerializeUpdate() return serializeAndSendUpdate(u.fsm.con, update)
if err != nil {
log.Errorf("Unable to serialize BGP Update: %v", err)
return nil
}
_, err = u.fsm.con.Write(updateBytes)
if err != nil {
return fmt.Errorf("Failed sending Update: %v", err)
}
return nil
} }
// RemovePath withdraws prefix `pfx` from a peer // RemovePath withdraws prefix `pfx` from a peer
......
package server package server
import ( import (
"fmt"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/net"
...@@ -32,26 +30,15 @@ func (u *UpdateSenderAddPath) AddPath(pfx net.Prefix, p *route.Path) error { ...@@ -32,26 +30,15 @@ func (u *UpdateSenderAddPath) AddPath(pfx net.Prefix, p *route.Path) error {
log.Errorf("Unable to create BGP Update: %v", err) log.Errorf("Unable to create BGP Update: %v", err)
return nil return nil
} }
update := &packet.BGPUpdateAddPath{
update := &packet.BGPUpdate{
PathAttributes: pathAttrs, PathAttributes: pathAttrs,
NLRI: &packet.NLRI{ NLRI: &packet.NLRIAddPath{
IP: pfx.Addr(), PathIdentifier: p.BGPPath.PathIdentifier,
Pfxlen: pfx.Pfxlen(), IP: pfx.Addr(),
Pfxlen: pfx.Pfxlen(),
}, },
} }
return serializeAndSendUpdate(u.fsm.con, update)
updateBytes, err := update.SerializeUpdate()
if err != nil {
log.Errorf("Unable to serialize BGP Update: %v", err)
return nil
}
_, err = u.fsm.con.Write(updateBytes)
if err != nil {
return fmt.Errorf("Failed sending Update: %v", err)
}
return nil
} }
// RemovePath withdraws prefix `pfx` from a peer // RemovePath withdraws prefix `pfx` from a peer
......
...@@ -35,12 +35,8 @@ func withDrawPrefixes(out io.Writer, prefixes ...net.Prefix) error { ...@@ -35,12 +35,8 @@ func withDrawPrefixes(out io.Writer, prefixes ...net.Prefix) error {
update := &packet.BGPUpdate{ update := &packet.BGPUpdate{
WithdrawnRoutes: rootNLRI, WithdrawnRoutes: rootNLRI,
} }
data, err := update.SerializeUpdate() return serializeAndSendUpdate(out, update)
if err != nil {
return err
}
_, err = out.Write(data)
return err
} }
// withDrawPrefixesAddPath generates a BGPUpdateAddPath message and write it to the given // withDrawPrefixesAddPath generates a BGPUpdateAddPath message and write it to the given
...@@ -59,10 +55,5 @@ func withDrawPrefixesAddPath(out io.Writer, pfx net.Prefix, p *route.Path) error ...@@ -59,10 +55,5 @@ func withDrawPrefixesAddPath(out io.Writer, pfx net.Prefix, p *route.Path) error
Pfxlen: pfx.Pfxlen(), Pfxlen: pfx.Pfxlen(),
}, },
} }
data, err := update.SerializeUpdate() return serializeAndSendUpdate(out, update)
if err != nil {
return err
}
_, err = out.Write(data)
return err
} }
...@@ -262,6 +262,12 @@ func TestGetLonger(t *testing.T) { ...@@ -262,6 +262,12 @@ func TestGetLonger(t *testing.T) {
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil), route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 12), nil),
}, },
}, },
{
name: "Test 2: Empty root",
routes: nil,
needle: net.NewPfx(strAddr("10.0.0.0"), 8),
expected: []*route.Route{},
},
} }
for _, test := range tests { for _, test := range tests {
...@@ -445,6 +451,372 @@ func TestRemovePath(t *testing.T) { ...@@ -445,6 +451,372 @@ func TestRemovePath(t *testing.T) {
} }
} }
func TestReplacePath(t *testing.T) {
tests := []struct {
name string
routes []*route.Route
replacePfx net.Prefix
replacePath *route.Path
expected []*route.Route
expectedOld []*route.Path
}{
{
name: "replace in empty table",
replacePfx: net.NewPfx(strAddr("10.0.0.0"), 8),
replacePath: &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{},
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{},
}),
},
expectedOld: nil,
},
{
name: "replace not existing prefix with multiple paths",
routes: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1001,
NextHop: 101,
},
}),
route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1002,
NextHop: 100,
},
}),
},
replacePfx: net.NewPfx(strAddr("10.0.0.0"), 8),
replacePath: &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1000,
},
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1000,
},
}),
newMultiPathRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1001,
NextHop: 101,
},
}, &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1002,
NextHop: 100,
},
}),
},
expectedOld: []*route.Path{},
},
{
name: "replace existing prefix with multiple paths",
routes: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1,
},
}),
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 2,
},
}),
route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1001,
NextHop: 101,
},
}),
route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1002,
NextHop: 100,
},
}),
},
replacePfx: net.NewPfx(strAddr("10.0.0.0"), 8),
replacePath: &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1000,
},
},
expected: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1000,
},
}),
newMultiPathRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1001,
NextHop: 101,
},
}, &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1002,
NextHop: 100,
},
}),
},
expectedOld: []*route.Path{
{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1,
},
},
{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 2,
},
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
rt := NewRoutingTable()
for _, route := range test.routes {
for _, p := range route.Paths() {
rt.AddPath(route.Prefix(), p)
}
}
old := rt.ReplacePath(test.replacePfx, test.replacePath)
assert.ElementsMatch(t, test.expectedOld, old)
assert.ElementsMatch(t, test.expected, rt.Dump())
})
}
}
func TestRemovePrefix(t *testing.T) {
tests := []struct {
name string
routes []*route.Route
removePfx net.Prefix
expected []*route.Route
expectedOld []*route.Path
}{
{
name: "remove in empty table",
removePfx: net.NewPfx(strAddr("10.0.0.0"), 8),
expected: []*route.Route{},
expectedOld: nil,
},
{
name: "remove not exist prefix",
routes: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1,
},
}),
route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1002,
NextHop: 100,
},
}),
},
removePfx: net.NewPfx(strAddr("12.0.0.0"), 8),
expected: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1,
},
}),
route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1002,
NextHop: 100,
},
}),
},
expectedOld: nil,
},
{
name: "remove not existing more specific prefix",
routes: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1,
},
}),
route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1002,
NextHop: 100,
},
}),
},
removePfx: net.NewPfx(strAddr("10.0.0.0"), 9),
expected: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1,
},
}),
route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1002,
NextHop: 100,
},
}),
},
expectedOld: nil,
},
{
name: "remove not existing more less prefix",
routes: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1,
},
}),
route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1002,
NextHop: 100,
},
}),
},
removePfx: net.NewPfx(strAddr("10.0.0.0"), 7),
expected: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1,
},
}),
route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1002,
NextHop: 100,
},
}),
},
expectedOld: nil,
},
{
name: "remove existing prefix",
routes: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1,
},
}),
route.NewRoute(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 2,
},
}),
route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1002,
NextHop: 100,
},
}),
},
removePfx: net.NewPfx(strAddr("10.0.0.0"), 8),
expected: []*route.Route{
route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1002,
NextHop: 100,
},
}),
},
expectedOld: []*route.Path{
{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 1,
},
},
{
Type: route.BGPPathType,
BGPPath: &route.BGPPath{
LocalPref: 2,
},
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
rt := NewRoutingTable()
for _, route := range test.routes {
for _, p := range route.Paths() {
rt.AddPath(route.Prefix(), p)
}
}
old := rt.RemovePfx(test.removePfx)
assert.ElementsMatch(t, test.expectedOld, old)
assert.ElementsMatch(t, test.expected, rt.Dump())
})
}
}
func newMultiPathRoute(pfx net.Prefix, paths ...*route.Path) *route.Route {
if len(paths) == 0 {
return route.NewRoute(pfx, nil)
}
r := route.NewRoute(pfx, paths[0])
for i := 1; i < len(paths); i++ {
r.AddPath(paths[i])
}
return r
}
func strAddr(s string) uint32 { func strAddr(s string) uint32 {
ret, _ := net.StrToAddr(s) ret, _ := net.StrToAddr(s)
return ret return ret
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment