diff --git a/e2etests/tests/advertisement.go b/e2etests/tests/advertisement.go index e1b9aa7a..8c9fdab6 100644 --- a/e2etests/tests/advertisement.go +++ b/e2etests/tests/advertisement.go @@ -284,6 +284,226 @@ var _ = ginkgo.Describe("Advertisement", func() { } }, }), + ginkgo.Entry("IPV4 - Advertise with communities, AllowedMode all", params{ + ipFamily: ipfamily.IPv4, + vrf: "", + myAsn: infra.FRRK8sASN, + prefixes: []string{"192.168.0.0/24", "192.168.1.0/24"}, + modifyPeers: func(ppV4 []config.Peer, ppV6 []config.Peer) { + for i := range ppV4 { + ppV4[i].Neigh.ToAdvertise.Allowed.Mode = frrk8sv1beta1.AllowAll + ppV4[i].Neigh.ToAdvertise.PrefixesWithCommunity = []frrk8sv1beta1.CommunityPrefixes{ + { + Community: "10:100", + Prefixes: []string{"192.168.0.0/24"}, + }, + { + Community: "10:101", + Prefixes: []string{"192.168.1.0/24"}, + }, + } + } + }, + validate: func(ppV4 []config.Peer, ppV6 []config.Peer, nodes []v1.Node) { + for _, p := range ppV4 { + ValidatePrefixesForNeighbor(p.FRR, nodes, "192.168.0.0/24", "192.168.1.0/24") + ValidateNeighborCommunityPrefixes(p.FRR, "10:100", []string{"192.168.0.0"}, ipfamily.IPv4) + ValidateNeighborCommunityPrefixes(p.FRR, "10:101", []string{"192.168.1.0"}, ipfamily.IPv4) + } + }, + }), + ginkgo.Entry("IPV4 - Advertise with multiple communities, AllowedMode restricted", params{ + ipFamily: ipfamily.IPv4, + vrf: "", + myAsn: infra.FRRK8sASN, + prefixes: []string{"192.168.0.0/24", "192.168.1.0/24", "192.168.2.0/24"}, + modifyPeers: func(ppV4 []config.Peer, ppV6 []config.Peer) { + for i := range ppV4 { + ppV4[i].Neigh.ToAdvertise.Allowed.Mode = frrk8sv1beta1.AllowRestricted + ppV4[i].Neigh.ToAdvertise.PrefixesWithCommunity = []frrk8sv1beta1.CommunityPrefixes{ + { + Community: "10:100", + Prefixes: []string{"192.168.0.0/24"}, + }, + { + Community: "10:101", + Prefixes: []string{"192.168.0.0/24", "192.168.1.0/24"}, + }, + { + Prefixes: []string{"192.168.2.0/24"}, + }, + } + } + }, + validate: func(ppV4 []config.Peer, ppV6 []config.Peer, nodes []v1.Node) { + for _, p := range ppV4 { + ValidatePrefixesForNeighbor(p.FRR, nodes, "192.168.0.0/24", "192.168.1.0/24", "192.168.2.0/24") + ValidateNeighborCommunityPrefixes(p.FRR, "10:100", []string{"192.168.0.0"}, ipfamily.IPv4) + ValidateNeighborCommunityPrefixes(p.FRR, "10:101", []string{"192.168.0.0", "192.168.1.0"}, ipfamily.IPv4) + } + }, + }), + ginkgo.Entry("IPV4 - large community", params{ + ipFamily: ipfamily.IPv4, + vrf: "", + myAsn: infra.FRRK8sASN, + prefixes: []string{"192.168.0.0/24", "192.168.1.0/24"}, + modifyPeers: func(ppV4 []config.Peer, ppV6 []config.Peer) { + for i := range ppV4 { + ppV4[i].Neigh.ToAdvertise.Allowed.Mode = frrk8sv1beta1.AllowAll + ppV4[i].Neigh.ToAdvertise.PrefixesWithCommunity = []frrk8sv1beta1.CommunityPrefixes{ + { + Community: "large:123:456:7890", + Prefixes: []string{"192.168.0.0/24"}, + }, + } + } + }, + validate: func(ppV4 []config.Peer, ppV6 []config.Peer, nodes []v1.Node) { + for _, p := range ppV4 { + ValidatePrefixesForNeighbor(p.FRR, nodes, "192.168.0.0/24", "192.168.1.0/24") + ValidateNeighborCommunityPrefixes(p.FRR, "large:123:456:7890", []string{"192.168.0.0"}, ipfamily.IPv4) + } + }, + }), + ginkgo.Entry("IPV6 - Advertise with communities, AllowedMode all", params{ + ipFamily: ipfamily.IPv6, + vrf: "", + myAsn: infra.FRRK8sASN, + prefixes: []string{"fc00:f853:ccd:e799::/64", "fc00:f853:ccd:e800::/64"}, + modifyPeers: func(ppV4 []config.Peer, ppV6 []config.Peer) { + for i := range ppV6 { + ppV6[i].Neigh.ToAdvertise.Allowed.Mode = frrk8sv1beta1.AllowAll + ppV6[i].Neigh.ToAdvertise.PrefixesWithCommunity = []frrk8sv1beta1.CommunityPrefixes{ + { + Community: "10:100", + Prefixes: []string{"fc00:f853:ccd:e799::/64"}, + }, + { + Community: "10:101", + Prefixes: []string{"fc00:f853:ccd:e800::/64"}, + }, + } + } + }, + validate: func(ppV4 []config.Peer, ppV6 []config.Peer, nodes []v1.Node) { + for _, p := range ppV6 { + ValidatePrefixesForNeighbor(p.FRR, nodes, "fc00:f853:ccd:e799::/64", "fc00:f853:ccd:e800::/64") + ValidateNeighborCommunityPrefixes(p.FRR, "10:100", []string{"fc00:f853:ccd:e799::"}, ipfamily.IPv6) + ValidateNeighborCommunityPrefixes(p.FRR, "10:101", []string{"fc00:f853:ccd:e800::"}, ipfamily.IPv6) + } + }, + }), + ginkgo.Entry("IPV6 - Advertise with multiple communities, AllowedMode restricted", params{ + ipFamily: ipfamily.IPv6, + vrf: "", + myAsn: infra.FRRK8sASN, + prefixes: []string{"fc00:f853:ccd:e799::/64", "fc00:f853:ccd:e800::/64", "fc00:f853:ccd:e801::/64"}, + modifyPeers: func(ppV4 []config.Peer, ppV6 []config.Peer) { + for i := range ppV6 { + ppV6[i].Neigh.ToAdvertise.Allowed.Mode = frrk8sv1beta1.AllowRestricted + ppV6[i].Neigh.ToAdvertise.PrefixesWithCommunity = []frrk8sv1beta1.CommunityPrefixes{ + { + Community: "10:100", + Prefixes: []string{"fc00:f853:ccd:e799::/64"}, + }, + { + Community: "10:101", + Prefixes: []string{"fc00:f853:ccd:e799::/64", "fc00:f853:ccd:e800::/64"}, + }, + { + Prefixes: []string{"fc00:f853:ccd:e801::/64"}, + }, + } + } + }, + validate: func(ppV4 []config.Peer, ppV6 []config.Peer, nodes []v1.Node) { + for _, p := range ppV6 { + ValidatePrefixesForNeighbor(p.FRR, nodes, "fc00:f853:ccd:e799::/64", "fc00:f853:ccd:e800::/64", "fc00:f853:ccd:e801::/64") + ValidateNeighborCommunityPrefixes(p.FRR, "10:100", []string{"fc00:f853:ccd:e799::"}, ipfamily.IPv6) + ValidateNeighborCommunityPrefixes(p.FRR, "10:101", []string{"fc00:f853:ccd:e799::", "fc00:f853:ccd:e800::"}, ipfamily.IPv6) + } + }, + }), + ginkgo.Entry("IPV6 - large community", params{ + ipFamily: ipfamily.IPv4, + vrf: "", + myAsn: infra.FRRK8sASN, + prefixes: []string{"fc00:f853:ccd:e799::/64", "fc00:f853:ccd:e800::/64"}, + modifyPeers: func(ppV4 []config.Peer, ppV6 []config.Peer) { + for i := range ppV6 { + ppV6[i].Neigh.ToAdvertise.Allowed.Mode = frrk8sv1beta1.AllowAll + ppV6[i].Neigh.ToAdvertise.PrefixesWithCommunity = []frrk8sv1beta1.CommunityPrefixes{ + { + Community: "large:123:456:7890", + Prefixes: []string{"fc00:f853:ccd:e799::/64"}, + }, + } + } + }, + validate: func(ppV4 []config.Peer, ppV6 []config.Peer, nodes []v1.Node) { + for _, p := range ppV6 { + ValidatePrefixesForNeighbor(p.FRR, nodes, "fc00:f853:ccd:e799::/64", "fc00:f853:ccd:e800::/64") + ValidateNeighborCommunityPrefixes(p.FRR, "large:123:456:7890", []string{"fc00:f853:ccd:e799::"}, ipfamily.IPv4) + } + }, + }), + ginkgo.Entry("DUALSTACK - Advertise with communities, AllowedMode all", params{ + ipFamily: ipfamily.DualStack, + vrf: "", + myAsn: infra.FRRK8sASN, + prefixes: []string{"192.168.2.0/24", "192.169.2.0/24", "fc00:f853:ccd:e799::/64", "fc00:f853:ccd:e800::/64"}, + modifyPeers: func(ppV4 []config.Peer, ppV6 []config.Peer) { + for i := range ppV4 { + ppV4[i].Neigh.ToAdvertise.Allowed.Mode = frrk8sv1beta1.AllowAll + ppV4[i].Neigh.ToAdvertise.PrefixesWithCommunity = []frrk8sv1beta1.CommunityPrefixes{ + { + Community: "10:100", + Prefixes: []string{"192.168.2.0/24"}, + }, + { + Community: "large:123:456:7890", + Prefixes: []string{"192.168.2.0/24"}, + }, + { + Community: "10:101", + Prefixes: []string{"192.168.2.0/24", "192.169.2.0/24"}, + }, + } + } + for i := range ppV6 { + ppV6[i].Neigh.ToAdvertise.Allowed.Mode = frrk8sv1beta1.AllowAll + ppV6[i].Neigh.ToAdvertise.PrefixesWithCommunity = []frrk8sv1beta1.CommunityPrefixes{ + { + Community: "10:100", + Prefixes: []string{"fc00:f853:ccd:e799::/64"}, + }, + { + Community: "large:123:456:7890", + Prefixes: []string{"fc00:f853:ccd:e799::/64"}, + }, + { + Community: "10:101", + Prefixes: []string{"fc00:f853:ccd:e799::/64", "fc00:f853:ccd:e800::/64"}, + }, + } + } + }, + validate: func(ppV4 []config.Peer, ppV6 []config.Peer, nodes []v1.Node) { + for _, p := range ppV4 { + ValidatePrefixesForNeighbor(p.FRR, nodes, "192.168.2.0/24", "192.169.2.0/24") + ValidateNeighborCommunityPrefixes(p.FRR, "10:100", []string{"192.168.2.0"}, ipfamily.IPv4) + ValidateNeighborCommunityPrefixes(p.FRR, "large:123:456:7890", []string{"192.168.2.0"}, ipfamily.IPv4) + ValidateNeighborCommunityPrefixes(p.FRR, "10:101", []string{"192.168.2.0", "192.169.2.0"}, ipfamily.IPv4) + } + for _, p := range ppV6 { + ValidatePrefixesForNeighbor(p.FRR, nodes, "fc00:f853:ccd:e799::/64", "fc00:f853:ccd:e800::/64") + ValidateNeighborCommunityPrefixes(p.FRR, "10:100", []string{"fc00:f853:ccd:e799::"}, ipfamily.IPv6) + ValidateNeighborCommunityPrefixes(p.FRR, "large:123:456:7890", []string{"fc00:f853:ccd:e799::"}, ipfamily.IPv6) + ValidateNeighborCommunityPrefixes(p.FRR, "10:101", []string{"fc00:f853:ccd:e799::", "fc00:f853:ccd:e800::"}, ipfamily.IPv6) + } + }, + }), ) }) }) diff --git a/e2etests/tests/validate.go b/e2etests/tests/validate.go index 17ccaada..a26fc865 100644 --- a/e2etests/tests/validate.go +++ b/e2etests/tests/validate.go @@ -69,3 +69,31 @@ func ValidateNeighborNoPrefixes(neigh frrcontainer.FRR, nodes []v1.Node, prefixe return nil }, 5*time.Second, time.Second).ShouldNot(HaveOccurred()) } + +func ValidateNeighborCommunityPrefixes(neigh frrcontainer.FRR, community string, prefixes []string, ipfam ipfamily.Family) { + Eventually(func() error { + routes, err := frr.RoutesForCommunity(neigh, community, ipfam) + if err != nil { + return err + } + + communityPrefixes := map[string]struct{}{} + for p := range routes { + communityPrefixes[p] = struct{}{} + } + + for _, prefix := range prefixes { + _, ok := communityPrefixes[prefix] + if !ok { + return fmt.Errorf("prefix %s not found in neighbor %s community %s unmatched routes %s", prefix, neigh.Name, community, communityPrefixes) + } + delete(communityPrefixes, prefix) + } + + if len(communityPrefixes) != 0 { + return fmt.Errorf("routes %s for community %s were not matched for neighbor %s", communityPrefixes, community, neigh.Name) + } + + return nil + }, 5*time.Second, time.Second).ShouldNot(HaveOccurred()) +}