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

Merge branch 'master' into feature/unknown_attr_pass

parents e4fb787b 41f347aa
No related branches found
No related tags found
No related merge requests found
Showing
with 316 additions and 81 deletions
......@@ -69,7 +69,7 @@ func (pfx Prefix) Contains(x Prefix) bool {
return false
}
mask := (uint32(1) << (32 - pfx.pfxlen))
mask := uint32((math.MaxUint32 << (32 - pfx.pfxlen)))
return (pfx.addr & mask) == (x.addr & mask)
}
......
......@@ -179,6 +179,18 @@ func TestContains(t *testing.T) {
},
expected: false,
},
{
name: "Test 7",
a: Prefix{
addr: strAddr("169.0.0.0"),
pfxlen: 25,
},
b: Prefix{
addr: strAddr("169.1.1.0"),
pfxlen: 26,
},
expected: false,
},
}
for _, test := range tests {
......@@ -332,3 +344,8 @@ func TestStrToAddr(t *testing.T) {
assert.Equal(t, test.expected, res)
}
}
func strAddr(s string) uint32 {
ret, _ := StrToAddr(s)
return ret
}
......@@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"fake_conn.go",
"fsm.go",
"fsm_active.go",
"fsm_cease.go",
......
package server
import (
"net"
"time"
)
type fakeConn struct {
}
type fakeAddr struct {
}
func (f fakeAddr) Network() string {
return ""
}
func (f fakeAddr) String() string {
return "169.254.100.100:179"
}
func (f fakeConn) Read(b []byte) (n int, err error) {
return 0, nil
}
func (f fakeConn) Write(b []byte) (n int, err error) {
return len(b), nil
}
func (f fakeConn) Close() error {
return nil
}
func (f fakeConn) LocalAddr() net.Addr {
return fakeAddr{}
}
func (f fakeConn) RemoteAddr() net.Addr {
return fakeAddr{}
}
func (f fakeConn) SetDeadline(t time.Time) error {
return nil
}
func (f fakeConn) SetReadDeadline(t time.Time) error {
return nil
}
func (f fakeConn) SetWriteDeadline(t time.Time) error {
return nil
}
package server
import (
"net"
"sync"
"testing"
"time"
"github.com/bio-routing/bio-rd/protocols/bgp/packet"
"github.com/bio-routing/bio-rd/routingtable/filter"
"github.com/bio-routing/bio-rd/routingtable/locRIB"
"github.com/stretchr/testify/assert"
)
// TestFSM100Updates emulates receiving 100 BGP updates and withdraws. Checks route counts.
func TestFSM100Updates(t *testing.T) {
fsmA := newFSM2(&peer{
addr: net.ParseIP("169.254.100.100"),
rib: locRIB.New(),
importFilter: filter.NewAcceptAllFilter(),
exportFilter: filter.NewAcceptAllFilter(),
})
fsmA.holdTimer = time.NewTimer(time.Second * 90)
fsmA.keepaliveTimer = time.NewTimer(time.Second * 30)
fsmA.connectRetryTimer = time.NewTimer(time.Second * 120)
fsmA.state = newEstablishedState(fsmA)
var wg sync.WaitGroup
wg.Add(1)
go func() {
fsmA.con = fakeConn{}
for {
nextState, reason := fsmA.state.run()
fsmA.state = nextState
stateName := stateName(nextState)
switch stateName {
case "idle":
wg.Done()
return
case "cease":
t.Errorf("Unexpected cease state: %s", reason)
wg.Done()
return
case "established":
continue
default:
t.Errorf("Unexpected new state: %s", reason)
wg.Done()
return
}
}
}()
for i := uint8(0); i < 255; i++ {
a := i % 10
b := i % 8
update := []byte{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
0, 54,
2,
0, 0,
0, 26,
64, // Attribute flags
1, // Attribute Type code (ORIGIN)
1, // Length
2, // INCOMPLETE
64, // Attribute flags
2, // Attribute Type code (AS Path)
12, // Length
2, // Type = AS_SEQUENCE
2, // Path Segement Length
59, 65, // AS15169
12, 248, // AS3320
1, // Type = AS_SET
2, // Path Segement Length
59, 65, // AS15169
12, 248, // AS3320
0, // Attribute flags
3, // Attribute Type code (Next Hop)
4, // Length
10, 11, 12, 13, // Next Hop
b + 25, 169, a, i, 0,
}
fsmA.msgRecvCh <- update
}
time.Sleep(time.Second)
ribRouteCount := fsmA.rib.RouteCount()
if ribRouteCount != 255 {
t.Errorf("Unexpected route count in LocRIB: %d", ribRouteCount)
}
for i := uint8(0); i < 255; i++ {
a := i % 10
b := i % 8
update := []byte{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
0, 28,
2,
0, 5,
b + 25, 169, a, i, 0,
0, 0,
}
fsmA.msgRecvCh <- update
ribRouteCount = fsmA.rib.RouteCount()
}
time.Sleep(time.Second * 1)
ribRouteCount = fsmA.rib.RouteCount()
if ribRouteCount != 0 {
t.Errorf("Unexpected route count in LocRIB: %d", ribRouteCount)
}
fsmA.eventCh <- ManualStop
wg.Wait()
}
func TestOpenMessage(t *testing.T) {
tests := []struct {
name string
......
......@@ -57,6 +57,12 @@ func (u *UpdateSender) UpdateNewClient(client routingtable.RouteTableClient) err
return nil
}
// RouteCount does nothing
func (u *UpdateSender) RouteCount() int64 {
log.Warningf("BGP Update Sender: RouteCount() not supported")
return 0
}
func asPathString(iBGP bool, localASN uint16, asPath string) string {
ret := ""
if iBGP {
......
......@@ -53,3 +53,9 @@ func (u *UpdateSenderAddPath) UpdateNewClient(client routingtable.RouteTableClie
log.Warningf("BGP Update Sender: UpdateNewClient not implemented")
return nil
}
// RouteCount returns the number of stored routes
func (u *UpdateSenderAddPath) RouteCount() int64 {
log.Warningf("BGP Update Sender: RouteCount not implemented")
return 0
}
......@@ -54,6 +54,11 @@ func (a *AdjRIBIn) UpdateNewClient(client routingtable.RouteTableClient) error {
return nil
}
// RouteCount returns the number of stored routes
func (a *AdjRIBIn) RouteCount() int64 {
return a.rt.GetRouteCount()
}
// AddPath replaces the path for prefix `pfx`. If the prefix doesn't exist it is added.
func (a *AdjRIBIn) AddPath(pfx net.Prefix, p *route.Path) error {
a.mu.Lock()
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
......@@ -16,3 +16,13 @@ go_library(
"//vendor/github.com/sirupsen/logrus:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["path_id_manager_test.go"],
embed = [":go_default_library"],
deps = [
"//route:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",
],
)
......@@ -39,6 +39,11 @@ func (a *AdjRIBOut) UpdateNewClient(client routingtable.RouteTableClient) error
return nil
}
// RouteCount returns the number of stored routes
func (a *AdjRIBOut) RouteCount() int64 {
return a.rt.GetRouteCount()
}
// 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) {
......
......@@ -55,104 +55,96 @@ X:
func TestReleasePath(t *testing.T) {
tests := []struct {
name string
pm *pathIDManager
adds []*route.Path
release *route.Path
expected *pathIDManager
expected []*route.Path
wantFail bool
}{
{
name: "Release existent",
pm: &pathIDManager{
ids: map[uint32]uint64{
0: 1,
1: 1,
2: 1,
},
idByPath: map[route.BGPPath]uint32{
route.BGPPath{
adds: []*route.Path{
{
BGPPath: &route.BGPPath{
LocalPref: 0,
}: 0,
route.BGPPath{
},
},
{
BGPPath: &route.BGPPath{
LocalPref: 1,
}: 1,
route.BGPPath{
},
},
{
BGPPath: &route.BGPPath{
LocalPref: 2,
}: 2,
},
},
last: 2,
used: 3,
},
release: &route.Path{BGPPath: &route.BGPPath{
LocalPref: 2,
}},
expected: &pathIDManager{
ids: map[uint32]uint64{
0: 1,
1: 1,
},
idByPath: map[route.BGPPath]uint32{
route.BGPPath{
expected: []*route.Path{
{
BGPPath: &route.BGPPath{
LocalPref: 0,
}: 0,
route.BGPPath{
},
},
{
BGPPath: &route.BGPPath{
LocalPref: 1,
}: 1,
},
},
last: 2,
used: 2,
},
},
{
name: "Release non-existent",
pm: &pathIDManager{
ids: map[uint32]uint64{
0: 1,
1: 1,
2: 1,
},
idByPath: map[route.BGPPath]uint32{
route.BGPPath{
adds: []*route.Path{
{
BGPPath: &route.BGPPath{
LocalPref: 0,
}: 0,
route.BGPPath{
},
},
{
BGPPath: &route.BGPPath{
LocalPref: 1,
}: 1,
route.BGPPath{
},
},
{
BGPPath: &route.BGPPath{
LocalPref: 2,
}: 2,
},
},
last: 2,
used: 3,
},
release: &route.Path{BGPPath: &route.BGPPath{
LocalPref: 4,
LocalPref: 5,
}},
expected: &pathIDManager{
ids: map[uint32]uint64{
0: 1,
1: 1,
2: 1,
},
idByPath: map[route.BGPPath]uint32{
route.BGPPath{
expected: []*route.Path{
{
BGPPath: &route.BGPPath{
LocalPref: 0,
}: 0,
route.BGPPath{
},
},
{
BGPPath: &route.BGPPath{
LocalPref: 1,
}: 1,
route.BGPPath{
},
},
{
BGPPath: &route.BGPPath{
LocalPref: 2,
}: 2,
},
},
last: 2,
used: 3,
},
wantFail: true,
},
}
for _, test := range tests {
_, err := test.pm.releasePath(test.release)
pm := newPathIDManager()
for _, add := range test.adds {
pm.addPath(add)
}
_, err := pm.releasePath(test.release)
if err != nil {
if test.wantFail {
continue
......@@ -167,7 +159,12 @@ func TestReleasePath(t *testing.T) {
continue
}
assert.Equalf(t, test.expected, test.pm, "%s", test.name)
expectedPM := newPathIDManager()
for _, x := range test.expected {
expectedPM.addPath(x)
}
expectedPM.last++
assert.Equalf(t, expectedPM, pm, "%s", test.name)
}
}
......@@ -13,4 +13,5 @@ type RouteTableClient interface {
Register(RouteTableClient)
RegisterWithOptions(RouteTableClient, ClientOptions)
Unregister(RouteTableClient)
RouteCount() int64
}
......@@ -34,6 +34,10 @@ func (m MockClient) Unregister(RouteTableClient) {
return
}
func (m MockClient) RouteCount() int64 {
return 0
}
func TestClients(t *testing.T) {
tests := []struct {
name string
......
......@@ -34,7 +34,7 @@ func TestInRange(t *testing.T) {
},
{
name: "matches end of range (22-24)",
prefix: net.NewPfx(strAddr("1.2.128.0"), 24),
prefix: net.NewPfx(strAddr("1.2.3.0"), 24),
pattern: net.NewPfx(strAddr("1.2.0.0"), 22),
begin: 22,
end: 24,
......
......@@ -55,6 +55,11 @@ func (a *LocRIB) UpdateNewClient(client routingtable.RouteTableClient) error {
return nil
}
// RouteCount returns the number of stored routes
func (a *LocRIB) RouteCount() int64 {
return a.rt.GetRouteCount()
}
// AddPath replaces the path for prefix `pfx`. If the prefix doesn't exist it is added.
func (a *LocRIB) AddPath(pfx net.Prefix, p *route.Path) error {
a.mu.Lock()
......
......@@ -50,3 +50,7 @@ func (m *RTMockClient) RemovePath(pfx net.Prefix, p *route.Path) bool {
m.removePathParams.Path = p
return true
}
func (m *RTMockClient) RouteCount() int64 {
return 0
}
......@@ -40,7 +40,11 @@ func (rt *RoutingTable) addPath(pfx net.Prefix, p *route.Path) error {
return nil
}
rt.root = rt.root.addPath(pfx, p)
root, isNew := rt.root.addPath(pfx, p)
rt.root = root
if isNew {
atomic.AddInt64(&rt.routeCount, 1)
}
return nil
}
......
......@@ -118,47 +118,50 @@ func (n *node) get(pfx net.Prefix) *node {
return n.h.get(pfx)
}
func (n *node) addPath(pfx net.Prefix, p *route.Path) *node {
func (n *node) addPath(pfx net.Prefix, p *route.Path) (*node, bool) {
currentPfx := n.route.Prefix()
if currentPfx == pfx {
n.route.AddPath(p)
n.dummy = false
return n
return n, true
}
// is pfx NOT a subnet of this node?
if !currentPfx.Contains(pfx) {
if pfx.Contains(currentPfx) {
return n.insertBefore(pfx, p, n.route.Pfxlen()-n.skip-1)
return n.insertBefore(pfx, p, n.route.Pfxlen()-n.skip-1), true
}
return n.newSuperNode(pfx, p)
return n.newSuperNode(pfx, p), true
}
// pfx is a subnet of this node
b := getBitUint32(pfx.Addr(), n.route.Pfxlen()+1)
if !b {
return n.insertLow(pfx, p, currentPfx.Pfxlen())
}
return n.insertHigh(pfx, p, n.route.Pfxlen())
}
func (n *node) insertLow(pfx net.Prefix, p *route.Path, parentPfxLen uint8) *node {
func (n *node) insertLow(pfx net.Prefix, p *route.Path, parentPfxLen uint8) (*node, bool) {
if n.l == nil {
n.l = newNode(pfx, p, pfx.Pfxlen()-parentPfxLen-1, false)
return n
return n, true
}
n.l = n.l.addPath(pfx, p)
return n
newRoot, isNew := n.l.addPath(pfx, p)
n.l = newRoot
return n, isNew
}
func (n *node) insertHigh(pfx net.Prefix, p *route.Path, parentPfxLen uint8) *node {
func (n *node) insertHigh(pfx net.Prefix, p *route.Path, parentPfxLen uint8) (*node, bool) {
if n.h == nil {
n.h = newNode(pfx, p, pfx.Pfxlen()-parentPfxLen-1, false)
return n
return n, true
}
n.h = n.h.addPath(pfx, p)
return n
newRoot, isNew := n.h.addPath(pfx, p)
n.h = newRoot
return n, isNew
}
func (n *node) newSuperNode(pfx net.Prefix, p *route.Path) *node {
......@@ -223,5 +226,6 @@ func (n *node) dump(res []*route.Route) []*route.Route {
res = n.l.dump(res)
res = n.h.dump(res)
return res
}
......@@ -13,7 +13,7 @@ go_library(
"union.go",
"version.go",
],
importmap = "vendor/github.com/Masterminds/semver",
importmap = "github.com/bio-routing/bio-rd/vendor/github.com/Masterminds/semver",
importpath = "github.com/Masterminds/semver",
visibility = ["//visibility:public"],
)
......@@ -12,7 +12,7 @@ go_library(
"vcs_local_lookup.go",
"vcs_remote_lookup.go",
],
importmap = "vendor/github.com/Masterminds/vcs",
importmap = "github.com/bio-routing/bio-rd/vendor/github.com/Masterminds/vcs",
importpath = "github.com/Masterminds/vcs",
visibility = ["//visibility:public"],
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment