diff --git a/routingtable/adjRIBOut/adj_rib_out_test.go b/routingtable/adjRIBOut/adj_rib_out_test.go index 0d01dd0890f06f1c518101205755162b10081c3e..87e1f854297bdb2540a7e56f9e7305c0380a1643 100644 --- a/routingtable/adjRIBOut/adj_rib_out_test.go +++ b/routingtable/adjRIBOut/adj_rib_out_test.go @@ -498,7 +498,7 @@ func TestBestPathOnlyIBGP(t *testing.T) { expected: []*route.Route{}, }, { - name: "Try to add route with NO_EXPORT community set (without success)", + name: "Try to add route with NO_ADVERTISE community set (without success)", routesAdd: []*route.Route{ route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{ Type: route.BGPPathType, @@ -532,6 +532,271 @@ func TestBestPathOnlyIBGP(t *testing.T) { } } +/* + * Test for iBGP Route Reflector client neighbor + */ + +func TestBestPathOnlyRRClient(t *testing.T) { + neighborBestOnlyRR := &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, + RouteReflectorClient: true, + ClusterID: net.IPv4FromOctets(2, 2, 2, 2).ToUint32(), + } + + adjRIBOut := New(neighborBestOnlyRR, filter.NewAcceptAllFilter()) + + tests := []struct { + name string + routesAdd []*route.Route + routesRemove []*route.Route + expected []*route.Route + expectedCount int64 + }{ + { + name: "Add an iBGP 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{}, + }), + }, + expected: []*route.Route{ + route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{ + Type: route.BGPPathType, + BGPPath: &route.BGPPath{ + Communities: []uint32{}, + LargeCommunities: []types.LargeCommunity{}, + ASPath: types.ASPath{}, + ClusterList: []uint32{ + neighborBestOnlyRR.ClusterID, + }, + }, + }), + }, + expectedCount: 1, + }, + { + name: "Add an eBGP route (replacing previous iBGP route)", + 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{}, + ClusterList: []uint32{ + neighborBestOnlyRR.ClusterID, + }, + }, + }), + }, + 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, // Existing route has 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: 0, + LocalPref: 0, + Source: net.IP{}, + ClusterList: []uint32{ + neighborBestOnlyRR.ClusterID, + }, + }, + }), + }, + 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{}, + ClusterList: []uint32{ + neighborBestOnlyRR.ClusterID, + }, + }, + }), + }, + expected: []*route.Route{}, + expectedCount: 0, + }, + { + name: "Try to add route with NO_ADVERTISE 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, + }, + { + name: "Try to add route with NO_EXPORT community set (with 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{ + route.NewRoute(net.NewPfx(net.IPv4FromOctets(10, 0, 0, 0), 8), &route.Path{ + Type: route.BGPPathType, + BGPPath: &route.BGPPath{ + ASPath: types.ASPath{}, + ASPathLen: 0, + Origin: 0, + MED: 0, + EBGP: false, + Communities: []uint32{ + types.WellKnownCommunityNoExport, + }, + LargeCommunities: []types.LargeCommunity{}, + UnknownAttributes: nil, + PathIdentifier: 0, + LocalPref: 0, + Source: net.IP{}, + ClusterList: []uint32{ + neighborBestOnlyRR.ClusterID, + }, + }, + }), + }, + expectedCount: 1, + }, + } + + for i, test := range tests { + fmt.Printf("Running RR client 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 */