diff --git a/examples/bgp/main.go b/examples/bgp/main.go index 11c2a6895ade4237dbf48249437c2d202bb8aa58..c22077168b67c32bd95e27ee099bd4c1449a9419 100644 --- a/examples/bgp/main.go +++ b/examples/bgp/main.go @@ -4,12 +4,9 @@ import ( "fmt" "time" - "github.com/sirupsen/logrus" - - "github.com/bio-routing/bio-rd/protocols/bgp/server" - "github.com/bio-routing/bio-rd/routingtable/locRIB" - bnet "github.com/bio-routing/bio-rd/net" + "github.com/bio-routing/bio-rd/protocols/bgp/server" + "github.com/sirupsen/logrus" ) func strAddr(s string) uint32 { @@ -20,9 +17,8 @@ func strAddr(s string) uint32 { func main() { logrus.Printf("This is a BGP speaker\n") - rib := locRIB.New() b := server.NewBgpServer() - startServer(b, rib) + rib := startServer(b) go func() { for { diff --git a/examples/bgp/main_ipv4.go b/examples/bgp/main_ipv4.go index c280c0723e28449664dcf2692f0150e4a60c5fc2..b397a576d3632cc7547ae799986a89ce6725ee62 100644 --- a/examples/bgp/main_ipv4.go +++ b/examples/bgp/main_ipv4.go @@ -6,19 +6,22 @@ import ( "net" "time" - "github.com/bio-routing/bio-rd/routingtable/locRIB" - "github.com/bio-routing/bio-rd/config" + bnet "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/protocols/bgp/server" "github.com/bio-routing/bio-rd/routingtable" "github.com/bio-routing/bio-rd/routingtable/filter" + "github.com/bio-routing/bio-rd/routingtable/locRIB" "github.com/sirupsen/logrus" - - bnet "github.com/bio-routing/bio-rd/net" ) -func startServer(b server.BGPServer, rib *locRIB.LocRIB) { - err := b.Start(&config.Global{ +func startServer(b server.BGPServer) *locRIB.LocRIB { + rib, err := locRIB.New("inet.0") + if err != nil { + logrus.Fatal(err) + } + + err = b.Start(&config.Global{ Listen: true, LocalAddressList: []net.IP{ net.IPv4(169, 254, 100, 1), @@ -73,4 +76,6 @@ func startServer(b server.BGPServer, rib *locRIB.LocRIB) { AddPathRecv: true, }, }) + + return rib } diff --git a/examples/bgp/main_ipv6.go b/examples/bgp/main_ipv6.go index 30467c00d23fb2d367f8110c0c02fd0e431f4ab6..fd7d347bc7bd11929052276720681f9c4207130d 100644 --- a/examples/bgp/main_ipv6.go +++ b/examples/bgp/main_ipv6.go @@ -7,17 +7,21 @@ import ( "time" "github.com/bio-routing/bio-rd/config" + bnet "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/protocols/bgp/server" "github.com/bio-routing/bio-rd/routingtable" "github.com/bio-routing/bio-rd/routingtable/filter" "github.com/bio-routing/bio-rd/routingtable/locRIB" "github.com/sirupsen/logrus" - - bnet "github.com/bio-routing/bio-rd/net" ) -func startServer(b server.BGPServer, rib *locRIB.LocRIB) { - err := b.Start(&config.Global{ +func startServer(b server.BGPServer) *locRIB.LocRIB { + rib, err := locRIB.New("inet6.0") + if err != nil { + logrus.Fatal(err) + } + + err = b.Start(&config.Global{ Listen: true, LocalAddressList: []net.IP{ net.IP{0x20, 0x01, 0x6, 0x78, 0x1, 0xe0, 0, 0, 0, 0, 0, 0, 0, 0, 0xca, 0xfe}, @@ -68,4 +72,6 @@ func startServer(b server.BGPServer, rib *locRIB.LocRIB) { }, }, }) + + return rib } diff --git a/examples/bmp/main_bmp.go b/examples/bmp/main_bmp.go index 63de954fed0cbefea47ddd398d522b5d96e00b29..ae578cd2db8511daf86f3ffa6cf6f474749b7686 100644 --- a/examples/bmp/main_bmp.go +++ b/examples/bmp/main_bmp.go @@ -13,8 +13,8 @@ import ( func main() { logrus.Printf("This is a BMP speaker\n") - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4, _ := locRIB.New("inet.0") + rib6, _ := locRIB.New("inet6.0") b := server.NewServer() b.AddRouter(net.IP{10, 0, 255, 0}, 30119, rib4, rib6) diff --git a/examples/netlink/main.go b/examples/netlink/main.go index aa4e493acb4e37c1f2745f5593e39811870ecacc..697faf58ae7b1c34c1ca6ebec1ec3517fa678205 100644 --- a/examples/netlink/main.go +++ b/examples/netlink/main.go @@ -6,12 +6,11 @@ import ( "time" "github.com/bio-routing/bio-rd/config" + bnet "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/protocols/bgp/server" "github.com/bio-routing/bio-rd/protocols/netlink" "github.com/bio-routing/bio-rd/routingtable/locRIB" log "github.com/sirupsen/logrus" - - bnet "github.com/bio-routing/bio-rd/net" ) func strAddr(s string) uint32 { @@ -39,7 +38,7 @@ func main() { }, } - rib := locRIB.New() + rib, _ := locRIB.New("netlink-example") b := server.NewBgpServer() startBGPServer(b, rib, cfg) diff --git a/protocols/bgp/server/bmp_router_test.go b/protocols/bgp/server/bmp_router_test.go index 3c74e6b82b358c964b5ed58f6a2a8d3b28944de9..3e3d43a6044ea0d0f9872d326e738b0bb9ae33d5 100644 --- a/protocols/bgp/server/bmp_router_test.go +++ b/protocols/bgp/server/bmp_router_test.go @@ -35,8 +35,8 @@ func TestBMPRouterServe(t *testing.T) { for _, test := range tests { addr := net.IP{10, 20, 30, 40} port := uint16(123) - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4 := locRIB.NewTestLocRIB() + rib6 := locRIB.NewTestLocRIB() conA, conB := net.Pipe() r := newRouter(addr, port, rib4, rib6) @@ -53,8 +53,8 @@ func TestBMPRouterServe(t *testing.T) { func TestStartStopBMP(t *testing.T) { addr := net.IP{10, 20, 30, 40} port := uint16(123) - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4 := locRIB.NewTestLocRIB() + rib6 := locRIB.NewTestLocRIB() con := biotesting.NewMockConn() @@ -260,8 +260,8 @@ func TestProcessPeerUpNotification(t *testing.T) { { name: "Regular BGP by RFC4271", router: &router{ - rib4: locRIB.New(), - rib6: locRIB.New(), + rib4: locRIB.MustNew("93be1b04-4f15-4875-8b7e-13723b710810"), + rib6: locRIB.MustNew("8ae78aa9-b3fb-4ec4-ab6d-5b20767fa4e1"), neighbors: make(map[[16]byte]*neighbor), }, pkt: &bmppkt.PeerUpNotification{ @@ -300,8 +300,8 @@ func TestProcessPeerUpNotification(t *testing.T) { }, wantFail: false, expected: &router{ - rib4: locRIB.New(), - rib6: locRIB.New(), + rib4: locRIB.LocRIBByName("93be1b04-4f15-4875-8b7e-13723b710810"), + rib6: locRIB.LocRIBByName("8ae78aa9-b3fb-4ec4-ab6d-5b20767fa4e1"), neighbors: map[[16]byte]*neighbor{ [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 255, 1}: { localAS: 200, @@ -631,16 +631,16 @@ func TestRegisterClients(t *testing.T) { n := &neighbor{ fsm: &FSM{ ipv4Unicast: &fsmAddressFamily{ - adjRIBIn: locRIB.New(), + adjRIBIn: locRIB.NewTestLocRIB(), }, ipv6Unicast: &fsmAddressFamily{ - adjRIBIn: locRIB.New(), + adjRIBIn: locRIB.NewTestLocRIB(), }, }, } - client4 := locRIB.New() - client6 := locRIB.New() + client4 := locRIB.NewTestLocRIB() + client6 := locRIB.NewTestLocRIB() ac4 := afiClient{ afi: packet.IPv4AFI, client: client4, @@ -677,8 +677,8 @@ func TestIntegrationPeerUpRouteMonitor(t *testing.T) { addr := net.IP{10, 20, 30, 40} port := uint16(12346) - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4 := locRIB.NewTestLocRIB() + rib6 := locRIB.NewTestLocRIB() r := newRouter(addr, port, rib4, rib6) conA, conB := net.Pipe() @@ -810,8 +810,8 @@ func TestIntegrationPeerUpRouteMonitorIPv6IPv4(t *testing.T) { addr := net.IP{10, 20, 30, 40} port := uint16(12346) - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4 := locRIB.NewTestLocRIB() + rib6 := locRIB.NewTestLocRIB() r := newRouter(addr, port, rib4, rib6) conA, conB := net.Pipe() @@ -1020,8 +1020,8 @@ func TestIntegrationPeerUpRouteMonitorIPv4IPv6(t *testing.T) { addr := net.IP{10, 20, 30, 40} port := uint16(12346) - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4 := locRIB.NewTestLocRIB() + rib6 := locRIB.NewTestLocRIB() r := newRouter(addr, port, rib4, rib6) conA, conB := net.Pipe() @@ -1231,8 +1231,8 @@ func TestIntegrationPeerUpRouteMonitorIPv6(t *testing.T) { addr := net.IP{10, 20, 30, 40} port := uint16(12346) - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4 := locRIB.NewTestLocRIB() + rib6 := locRIB.NewTestLocRIB() r := newRouter(addr, port, rib4, rib6) conA, conB := net.Pipe() @@ -1383,8 +1383,8 @@ func TestIntegrationIncompleteBMPMsg(t *testing.T) { addr := net.IP{10, 20, 30, 40} port := uint16(12346) - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4 := locRIB.NewTestLocRIB() + rib6 := locRIB.NewTestLocRIB() r := newRouter(addr, port, rib4, rib6) con := biotesting.NewMockConn() @@ -1461,8 +1461,8 @@ func TestBMPFullRunWithWithdraw(t *testing.T) { addr := net.IP{10, 20, 30, 40} port := uint16(12346) - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4 := locRIB.NewTestLocRIB() + rib6 := locRIB.NewTestLocRIB() r := newRouter(addr, port, rib4, rib6) con := biotesting.NewMockConn() @@ -1630,8 +1630,8 @@ func TestBMPFullRunWithPeerDownNotification(t *testing.T) { addr := net.IP{10, 20, 30, 40} port := uint16(12346) - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4 := locRIB.NewTestLocRIB() + rib6 := locRIB.NewTestLocRIB() r := newRouter(addr, port, rib4, rib6) con := biotesting.NewMockConn() @@ -1790,8 +1790,8 @@ func TestBMPFullRunWithTerminationMessage(t *testing.T) { addr := net.IP{10, 20, 30, 40} port := uint16(12346) - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4 := locRIB.NewTestLocRIB() + rib6 := locRIB.NewTestLocRIB() r := newRouter(addr, port, rib4, rib6) con := biotesting.NewMockConn() @@ -1942,8 +1942,8 @@ func TestIntegrationPeerUpRouteMonitorIPv6WithClientAtEnd(t *testing.T) { addr := net.IP{10, 20, 30, 40} port := uint16(12346) - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4 := locRIB.NewTestLocRIB() + rib6 := locRIB.NewTestLocRIB() r := newRouter(addr, port, rib4, rib6) conA, conB := net.Pipe() @@ -2087,7 +2087,7 @@ func TestIntegrationPeerUpRouteMonitorIPv6WithClientAtEnd(t *testing.T) { t.Errorf("Unexpected IPv4 route count. Expected: 0 Got: %d", count) } - client6 := locRIB.New() + client6 := locRIB.NewTestLocRIB() r.subscribeRIBs(client6, packet.IPv6AFI) count = client6.RouteCount() @@ -2702,13 +2702,13 @@ func TestIntegrationPeerUpRouteMonitorIPv6WithClientBeforeBMPPeer(t *testing.T) addr := net.IP{10, 20, 30, 40} port := uint16(12346) - rib4 := locRIB.New() - rib6 := locRIB.New() + rib4 := locRIB.NewTestLocRIB() + rib6 := locRIB.NewTestLocRIB() r := newRouter(addr, port, rib4, rib6) conA, conB := net.Pipe() - client := locRIB.New() + client := locRIB.NewTestLocRIB() r.subscribeRIBs(client, test.afi) if test.doubleSubscribe { r.subscribeRIBs(client, test.afi) diff --git a/protocols/bgp/server/fsm_test.go b/protocols/bgp/server/fsm_test.go index aae0d7dc20347635e28c84d88b2a062f9e28ff68..26608ffe0b039042b34c0d12f60c5d8bab0a5cac 100644 --- a/protocols/bgp/server/fsm_test.go +++ b/protocols/bgp/server/fsm_test.go @@ -5,12 +5,11 @@ import ( "testing" "time" + bnet "github.com/bio-routing/bio-rd/net" "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" - - bnet "github.com/bio-routing/bio-rd/net" ) // TestFSM255UpdatesIPv4 emulates receiving 255 BGP updates and withdraws. Checks route counts. @@ -19,7 +18,7 @@ func TestFSM255UpdatesIPv4(t *testing.T) { addr: bnet.IPv4FromOctets(169, 254, 100, 100), routerID: bnet.IPv4FromOctets(1, 1, 1, 1).ToUint32(), ipv4: &peerAddressFamily{ - rib: locRIB.New(), + rib: locRIB.NewTestLocRIB(), importFilter: filter.NewAcceptAllFilter(), exportFilter: filter.NewAcceptAllFilter(), }, @@ -133,7 +132,7 @@ func TestFSM255UpdatesIPv6(t *testing.T) { addr: bnet.IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0xffff, 0, 0, 0, 1), routerID: bnet.IPv4FromOctets(1, 1, 1, 1).ToUint32(), ipv6: &peerAddressFamily{ - rib: locRIB.New(), + rib: locRIB.NewTestLocRIB(), importFilter: filter.NewAcceptAllFilter(), exportFilter: filter.NewAcceptAllFilter(), }, diff --git a/protocols/bgp/server/server_test.go b/protocols/bgp/server/server_test.go index 9d9248c4d8e1f574e3cc3f519d412de3bbf5140a..a72a479a2cc347682c7224f5b8ac39e195e711ff 100644 --- a/protocols/bgp/server/server_test.go +++ b/protocols/bgp/server/server_test.go @@ -5,11 +5,10 @@ import ( "time" "github.com/bio-routing/bio-rd/config" + bnet "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/routingtable" "github.com/bio-routing/bio-rd/routingtable/filter" "github.com/bio-routing/bio-rd/routingtable/locRIB" - - bnet "github.com/bio-routing/bio-rd/net" "github.com/stretchr/testify/assert" ) @@ -28,7 +27,7 @@ func TestBgpServerPeerSnapshot(t *testing.T) { t.Fatalf("empty server should have 0 peers, has %d", len(info)) } - rib := locRIB.New() + rib := locRIB.NewTestLocRIB() pc := config.Peer{ AdminEnabled: true, PeerAS: 65300, diff --git a/protocols/bgp/server/update_sender_test.go b/protocols/bgp/server/update_sender_test.go index d30f9b8f27312c9a23188af5d5fd482999b58757..2cb6f92bb8b5c75e2c7ea935260e93c2630de62b 100644 --- a/protocols/bgp/server/update_sender_test.go +++ b/protocols/bgp/server/update_sender_test.go @@ -7,16 +7,14 @@ import ( "testing" "time" - "github.com/bio-routing/bio-rd/protocols/bgp/packet" - "github.com/bio-routing/bio-rd/routingtable" - - "github.com/stretchr/testify/assert" - bnet "github.com/bio-routing/bio-rd/net" + "github.com/bio-routing/bio-rd/protocols/bgp/packet" "github.com/bio-routing/bio-rd/route" + "github.com/bio-routing/bio-rd/routingtable" "github.com/bio-routing/bio-rd/routingtable/filter" "github.com/bio-routing/bio-rd/routingtable/locRIB" btest "github.com/bio-routing/bio-rd/testing" + "github.com/stretchr/testify/assert" ) func TestSender(t *testing.T) { @@ -881,7 +879,7 @@ func TestSender(t *testing.T) { addr: bnet.IPv4FromOctets(169, 254, 100, 100), }) - rib := locRIB.New() + rib := locRIB.NewTestLocRIB() if test.afi == packet.IPv6AFI { fsmA.ipv6Unicast = newFSMAddressFamily(packet.IPv6AFI, packet.UnicastSAFI, &peerAddressFamily{ rib: rib, diff --git a/routingtable/locRIB/loc_rib.go b/routingtable/locRIB/loc_rib.go index b1f975f65fad28e31f3fcd327836ad4f518e0f4f..6be7347a6e45e15710e18317b008970c7893d88b 100644 --- a/routingtable/locRIB/loc_rib.go +++ b/routingtable/locRIB/loc_rib.go @@ -8,25 +8,52 @@ import ( "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/route" "github.com/bio-routing/bio-rd/routingtable" + "github.com/google/uuid" "github.com/sirupsen/logrus" ) // LocRIB represents a routing information base type LocRIB struct { + name string clientManager *routingtable.ClientManager rt *routingtable.RoutingTable mu sync.RWMutex contributingASNs *routingtable.ContributingASNs } +// MustNew creates a new routing information base or panics +func MustNew(name string) *LocRIB { + rib, err := New(name) + if err != nil { + panic(err) + } + + return rib +} + // New creates a new routing information base -func New() *LocRIB { +func New(name string) (*LocRIB, error) { a := &LocRIB{ + name: name, rt: routingtable.NewRoutingTable(), contributingASNs: routingtable.NewContributingASNs(), } a.clientManager = routingtable.NewClientManager(a) - return a + + err := defaultRegistry.register(a) + if err != nil { + return nil, err + } + + return a, nil +} + +// NewTestLocRIB returns an unique RIB and should only be used in tests +func NewTestLocRIB() *LocRIB { + id := uuid.New() + rib, _ := New(id.String()) + + return rib } // GetContributingASNs returns a pointer to the list of contributing ASNs diff --git a/routingtable/locRIB/loc_rib_test.go b/routingtable/locRIB/loc_rib_test.go index 6b3e24e0715ec5ec8a670c9d6bd94f1a28fab5ad..cbce664ca379991be198fbb57693060ce778cc2a 100644 --- a/routingtable/locRIB/loc_rib_test.go +++ b/routingtable/locRIB/loc_rib_test.go @@ -5,7 +5,6 @@ import ( bnet "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/route" - "github.com/stretchr/testify/assert" ) @@ -75,7 +74,7 @@ func TestContainsPfxPath(t *testing.T) { }, } for i, tc := range testCases { - rib := New() + rib := NewTestLocRIB() for _, p := range tc.in { err := rib.AddPath(p.pfx, p.path) assert.Nil(t, err, "could not fill rib in testcase %v", i) @@ -86,7 +85,7 @@ func TestContainsPfxPath(t *testing.T) { } func TestLocRIB_RemovePathUnknown(t *testing.T) { - rib := New() + rib := NewTestLocRIB() assert.True(t, rib.RemovePath(bnet.NewPfx(bnet.IPv4(1), 32), &route.Path{ Type: route.StaticPathType, diff --git a/routingtable/locRIB/registry.go b/routingtable/locRIB/registry.go new file mode 100644 index 0000000000000000000000000000000000000000..251d694fcfe725cedb62c7fdd114799ab58c0dcb --- /dev/null +++ b/routingtable/locRIB/registry.go @@ -0,0 +1,37 @@ +package locRIB + +import ( + "fmt" + "sync" +) + +var defaultRegistry *registry + +func init() { + defaultRegistry = ®istry{ + ribs: make(map[string]*LocRIB), + } +} + +type registry struct { + ribs map[string]*LocRIB + mu sync.Mutex +} + +func LocRIBByName(name string) *LocRIB { + rib, _ := defaultRegistry.ribs[name] + return rib +} + +func (r *registry) register(rib *LocRIB) error { + r.mu.Lock() + defer r.mu.Unlock() + + if _, found := r.ribs[rib.name]; found { + return fmt.Errorf(fmt.Sprintf("a rib with name '%s' already exists", rib.name)) + } + + r.ribs[rib.name] = rib + + return nil +} diff --git a/routingtable/locRIB/registry_test.go b/routingtable/locRIB/registry_test.go new file mode 100644 index 0000000000000000000000000000000000000000..2c0341331b9c58d4b39253796adfe958f9e54b6c --- /dev/null +++ b/routingtable/locRIB/registry_test.go @@ -0,0 +1,17 @@ +package locRIB + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Register(t *testing.T) { + r1, err := New("inet.0") + assert.NotNil(t, r1) + assert.Nil(t, err) + + r2, err := New("inet.0") + assert.Nil(t, r2) + assert.NotNil(t, err) +}