From 2edc924a242694a0a603ba337158ac0771415706 Mon Sep 17 00:00:00 2001 From: gkopels <81898506+gkopels@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:10:31 +0200 Subject: [PATCH] cnf: networking - Add bgp dynamic multihop tc (#328) Co-authored-by: Gregory Kopels --- .../metallb/internal/tsparams/mlbvars.go | 2 + .../metallb/tests/bgp-remote-as-dynamic.go | 149 +++++++++++++++++- 2 files changed, 146 insertions(+), 5 deletions(-) diff --git a/tests/cnf/core/network/metallb/internal/tsparams/mlbvars.go b/tests/cnf/core/network/metallb/internal/tsparams/mlbvars.go index df2cadc9f..6b835d35c 100644 --- a/tests/cnf/core/network/metallb/internal/tsparams/mlbvars.go +++ b/tests/cnf/core/network/metallb/internal/tsparams/mlbvars.go @@ -44,6 +44,8 @@ var ( FrrDsName = "frr-k8s" // FRRK8sDefaultLabel represents the default metalLb FRRK8S pod label. FRRK8sDefaultLabel = "component=frr-k8s" + // FRRK8sNodeLabel represents the default metalLb FRRK8S node label. + FRRK8sNodeLabel = "app=frr-k8s" // ExternalMacVlanNADName represents default external NetworkAttachmentDefinition name. ExternalMacVlanNADName = "external" // HubMacVlanNADName represents default external NetworkAttachmentDefinition name. diff --git a/tests/cnf/core/network/metallb/tests/bgp-remote-as-dynamic.go b/tests/cnf/core/network/metallb/tests/bgp-remote-as-dynamic.go index fac02bf36..10353d902 100644 --- a/tests/cnf/core/network/metallb/tests/bgp-remote-as-dynamic.go +++ b/tests/cnf/core/network/metallb/tests/bgp-remote-as-dynamic.go @@ -12,6 +12,7 @@ import ( "github.com/openshift-kni/eco-goinfra/pkg/reportxml" "github.com/openshift-kni/eco-goinfra/pkg/schemes/metallb/mlbtypesv1beta2" . "github.com/openshift-kni/eco-gotests/tests/cnf/core/network/internal/netinittools" + "github.com/openshift-kni/eco-gotests/tests/cnf/core/network/internal/netparam" "github.com/openshift-kni/eco-gotests/tests/cnf/core/network/metallb/internal/frr" "github.com/openshift-kni/eco-gotests/tests/cnf/core/network/metallb/internal/metallbenv" "github.com/openshift-kni/eco-gotests/tests/cnf/core/network/metallb/internal/tsparams" @@ -22,9 +23,13 @@ import ( var _ = Describe("BGP remote-dynamicAS", Ordered, Label(tsparams.LabelDynamicRemoteASTestCases), ContinueOnFailure, func() { var ( - err error - dynamicASiBGP = "internal" - dynamicASeBGP = "external" + err error + dynamicASiBGP = "internal" + dynamicASeBGP = "external" + frrExternalMasterIPAddress = "172.16.0.1" + hubIPv4ExternalAddresses = []string{"172.16.0.10", "172.16.0.11"} + externalAdvertisedIPv4Routes = []string{"192.168.100.0/24", "192.168.200.0/24"} + externalAdvertisedIPv6Routes = []string{"2001:100::0/64", "2001:200::0/64"} ) BeforeAll(func() { @@ -61,9 +66,7 @@ var _ = Describe("BGP remote-dynamicAS", Ordered, Label(tsparams.LabelDynamicRem Context("single hop", func() { var ( - hubIPv4ExternalAddresses = []string{"172.16.0.10", "172.16.0.11"} externalAdvertisedIPv4Routes = []string{"192.168.100.0/24", "192.168.200.0/24"} - externalAdvertisedIPv6Routes = []string{"2001:100::0/64", "2001:200::0/64"} ) AfterEach(func() { @@ -119,6 +122,70 @@ var _ = Describe("BGP remote-dynamicAS", Ordered, Label(tsparams.LabelDynamicRem fmt.Sprintf("The remoteASN does not match the expected AS: %d", 0)) }) }) + + Context("multi hop", func() { + var ( + frrNodeSecIntIPv4Addresses = []string{"10.100.100.254", "10.100.100.253"} + hubPodWorkerNames = []string{"hub-pod-worker-0", "hub-pod-worker-1"} + ) + + AfterEach(func() { + By("Removing static routes from the speakers") + frrk8sPods, err := pod.List(APIClient, NetConfig.MlbOperatorNamespace, metav1.ListOptions{ + LabelSelector: tsparams.FRRK8sDefaultLabel, + }) + Expect(err).ToNot(HaveOccurred(), "Failed to list pods") + + speakerRoutesMap := buildRoutesMapWithSpecificRoutes(frrk8sPods, []string{ipv4metalLbIPList[0], + ipv4metalLbIPList[1], frrNodeSecIntIPv4Addresses[0], frrNodeSecIntIPv4Addresses[1]}) + + for _, frrk8sPod := range frrk8sPods { + out, err := frr.SetStaticRoute(frrk8sPod, "del", frrExternalMasterIPAddress, speakerRoutesMap) + Expect(err).ToNot(HaveOccurred(), out) + } + + By("Clean metallb operator and test namespaces") + resetOperatorAndTestNS() + }) + + It("Verify the establishment of a multi-hop iBGP adjacency using neighbor peer remote-as external", + reportxml.ID("76823"), func() { + frrPod, frrk8sPods := setupBGPRemoteASMultiHopTest(ipv4metalLbIPList, hubIPv4ExternalAddresses, + externalAdvertisedIPv4Routes, externalAdvertisedIPv6Routes, hubPodWorkerNames, + frrExternalMasterIPAddress, tsparams.LocalBGPASN, false) + + By("Creating a BGP Peer with dynamicASN") + createBGPPeerWithDynamicASN(frrExternalMasterIPAddress, dynamicASiBGP, false) + + By("Checking that BGP session is established and up") + verifyMetalLbBGPSessionsAreUPOnFrrPod(frrPod, removePrefixFromIPList(ipv4NodeAddrList)) + + By("Validating external FRR AS number received on the FRR nodes") + Eventually(func() error { + return frr.ValidateBGPRemoteAS(frrk8sPods, frrExternalMasterIPAddress, tsparams.LocalBGPASN) + }, 60*time.Second, 5*time.Second).Should(Succeed(), + fmt.Sprintf("The remoteASN does not match the expected AS: %d", tsparams.LocalBGPASN)) + }) + + It("Verify the establishment of a multi-hop eBGP adjacency using neighbor peer remote-as external", + reportxml.ID("76824"), func() { + frrPod, frrk8sPods := setupBGPRemoteASMultiHopTest(ipv4metalLbIPList, hubIPv4ExternalAddresses, + externalAdvertisedIPv4Routes, externalAdvertisedIPv6Routes, hubPodWorkerNames, + frrExternalMasterIPAddress, tsparams.RemoteBGPASN, true) + + By("Creating a BGP Peer with dynamicASN") + createBGPPeerWithDynamicASN(frrExternalMasterIPAddress, dynamicASeBGP, true) + + By("Checking that BGP session is established and up") + verifyMetalLbBGPSessionsAreUPOnFrrPod(frrPod, removePrefixFromIPList(ipv4NodeAddrList)) + + By("Validating external FRR AS number received on the FRR nodes") + Eventually(func() error { + return frr.ValidateBGPRemoteAS(frrk8sPods, frrExternalMasterIPAddress, tsparams.RemoteBGPASN) + }, 60*time.Second, 5*time.Second).Should(Succeed(), + fmt.Sprintf("The remoteASN does not match the expected AS: %d", tsparams.RemoteBGPASN)) + }) + }) }) func createBGPPeerWithDynamicASN(peerIP, dynamicASN string, eBgpMultiHop bool) { @@ -179,3 +246,75 @@ func setupBGPRemoteASTestCase(hubIPv4ExternalAddresses, externalAdvertisedIPv4Ro return frrk8sPods, frrPod } + +func setupBGPRemoteASMultiHopTest(ipv4metalLbIPList, hubIPv4ExternalAddresses, externalAdvertisedIPv4Routes, + externalAdvertisedIPv6Routes, hubPodWorkerName []string, frrExternalMasterIPAddress string, asNumber int, + eBGP bool) (*pod.Builder, []*pod.Builder) { + By("Creating a new instance of MetalLB Speakers on workers") + + err := metallbenv.CreateNewMetalLbDaemonSetAndWaitUntilItsRunning(tsparams.DefaultTimeout, workerLabelMap) + Expect(err).ToNot(HaveOccurred(), "Failed to recreate metalLb daemonset") + + By("Collecting information before test") + + frrk8sPods, err := pod.List(APIClient, NetConfig.MlbOperatorNamespace, metav1.ListOptions{ + LabelSelector: tsparams.FRRK8sNodeLabel, + }) + Expect(err).ToNot(HaveOccurred(), "Failed to list frrk8 pods") + By("Setting test parameters") + + masterClientPodIP, _, _, nodeAddrList, _, _, err := + metallbenv.DefineIterationParams( + ipv4metalLbIPList, ipv6metalLbIPList, ipv4NodeAddrList, ipv6NodeAddrList, netparam.IPV4Family) + Expect(err).ToNot(HaveOccurred(), "Fail to set iteration parameters") + + By("Creating External NAD for master FRR pod") + createExternalNad(tsparams.ExternalMacVlanNADName) + + By("Creating External NAD for hub FRR pods") + createExternalNad(tsparams.HubMacVlanNADName) + + By("Creating static ip annotation for hub0") + + hub0BRstaticIPAnnotation := createStaticIPAnnotations(tsparams.ExternalMacVlanNADName, + tsparams.HubMacVlanNADName, + []string{fmt.Sprintf("%s/24", ipv4metalLbIPList[0])}, + []string{fmt.Sprintf("%s/24", hubIPv4ExternalAddresses[0])}) + + By("Creating static ip annotation for hub1") + + hub1BRstaticIPAnnotation := createStaticIPAnnotations(tsparams.ExternalMacVlanNADName, + tsparams.HubMacVlanNADName, + []string{fmt.Sprintf("%s/24", ipv4metalLbIPList[1])}, + []string{fmt.Sprintf("%s/24", hubIPv4ExternalAddresses[1])}) + + By("Creating MetalLb Hub pod configMap") + + hubConfigMap := createHubConfigMap("hub-node-config") + + By("Creating FRR Hub pod on worker node 0") + + _ = createFrrHubPod(hubPodWorkerName[0], + workerNodeList[0].Object.Name, hubConfigMap.Definition.Name, []string{}, hub0BRstaticIPAnnotation) + + By("Creating FRR Hub pod on worker node 1") + + _ = createFrrHubPod(hubPodWorkerName[1], + workerNodeList[1].Object.Name, hubConfigMap.Definition.Name, []string{}, hub1BRstaticIPAnnotation) + + By("Creating configmap and MetalLb Master pod") + + frrPod := createMasterFrrPod(asNumber, frrExternalMasterIPAddress, nodeAddrList, hubIPv4ExternalAddresses, + externalAdvertisedIPv4Routes, externalAdvertisedIPv6Routes, eBGP) + + By("Adding static routes to the speakers") + + speakerRoutesMap := buildRoutesMapWithSpecificRoutes(frrk8sPods, ipv4metalLbIPList) + + for _, frrk8sPod := range frrk8sPods { + out, err := frr.SetStaticRoute(frrk8sPod, "add", masterClientPodIP, speakerRoutesMap) + Expect(err).ToNot(HaveOccurred(), out) + } + + return frrPod, frrk8sPods +}