Skip to content

Commit

Permalink
E2E: implement tests for receiving prefixes
Browse files Browse the repository at this point in the history
Here we implement e2e test to ensure frr-k8s is able to receive routes
from outside.

Signed-off-by: Federico Paolinelli <[email protected]>
  • Loading branch information
fedepaol committed Jul 14, 2023
1 parent 3d3ec1b commit 31e15d7
Show file tree
Hide file tree
Showing 4 changed files with 444 additions and 0 deletions.
13 changes: 13 additions & 0 deletions e2etests/pkg/routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ import (
"k8s.io/kubernetes/test/e2e/framework"
)

// PodHasPrefixFromContainer tells if the given frr-k8s pod has recevied a route for
// the given prefix from the given container.
func PodHasPrefixFromContainer(pod *v1.Pod, frr frrcontainer.FRR, prefix string) bool {
_, cidr, _ := net.ParseCIDR(prefix)
ipFamily := ipfamily.ForCIDR(cidr)
nextHop := frr.Ipv4
if ipFamily == ipfamily.IPv6 {
nextHop = frr.Ipv6
}
vrf := frr.RouterConfig.VRF
return havePrefix(pod, ipFamily, cidr, nextHop, vrf)
}

// CheckNeighborHasPrefix tells if the given frr container has a route toward the given prefix
// via the set of node passed to this function.
func CheckNeighborHasPrefix(neighbor frrcontainer.FRR, prefix string, nodes []v1.Node) (bool, error) {
Expand Down
105 changes: 105 additions & 0 deletions e2etests/pkg/routes/routes.go.old
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// SPDX-License-Identifier:Apache-2.0

package routes

import (
"bytes"
"fmt"
"net"

"go.universe.tf/e2etest/pkg/frr"
frrcontainer "go.universe.tf/e2etest/pkg/frr/container"
"go.universe.tf/e2etest/pkg/ipfamily"
"go.universe.tf/metallb/e2etest/pkg/executor"
v1 "k8s.io/api/core/v1"
"k8s.io/kubernetes/test/e2e/framework"
)

func PodHasPrefixFromContainer(pod *v1.Pod, frr frrcontainer.FRR, prefix string) bool {
_, cidr, _ := net.ParseCIDR(prefix)
ipFamily := ipfamily.ForCIDR(cidr)
nextHop := frr.Ipv4
if ipFamily == ipfamily.IPv6 {
nextHop = frr.Ipv6
}
vrf := frr.RouterConfig.VRF
return havePrefix(pod, ipFamily, cidr, nextHop, vrf)
}

// CheckNeighborHasPrefix tells if the given frr container has a route toward the given prefix
// via the set of node passed to this function.
func CheckNeighborHasPrefix(neighbor *frrcontainer.FRR, prefix string, nodes []v1.Node) error {
routesV4, routesV6, err := frr.Routes(neighbor)
if err != nil {
return err
}

_, cidr, err := net.ParseCIDR(prefix)
if err != nil {
return err
}

route, err := routeForCIDR(cidr, routesV4, routesV6)
if err != nil {
return err
}

cidrFamily := ipfamily.ForCIDR(cidr)
err = frr.RoutesMatchNodes(nodes, route, cidrFamily, neighbor.RouterConfig.VRF)
if err != nil {
return err
}
return nil
}

func cidrsAreEqual(a, b *net.IPNet) bool {
return a.IP.Equal(b.IP) && bytes.Equal(a.Mask, b.Mask)
}

type RouteNotFoundError string

func (e RouteNotFoundError) Error() string {
return string(e)
}

func routeForCIDR(cidr *net.IPNet, routesV4 map[string]frr.Route, routesV6 map[string]frr.Route) (frr.Route, error) {
for _, route := range routesV4 {
if cidrsAreEqual(route.Destination, cidr) {
return route, nil
}
}
for _, route := range routesV6 {
if cidrsAreEqual(route.Destination, cidr) {
return route, nil
}
}
return frr.Route{}, RouteNotFoundError(fmt.Sprintf("route %s not found", cidr))
}

func havePrefix(pod *v1.Pod, pairingFamily ipfamily.Family, prefix *net.IPNet, nextHop, vrf string) bool {
found := false
podExec := executor.ForPod(pod.Namespace, pod.Name, "frr")
routes, frrRoutesV6, err := frr.RoutesForVRF(vrf, podExec)
framework.ExpectNoError(err)

if pairingFamily == ipfamily.IPv6 {
routes = frrRoutesV6
}

out:
for _, route := range routes {
if !cidrsAreEqual(route.Destination, prefix) {
continue
}
for _, nh := range route.NextHops {
if nh.String() == nextHop {
found = true
break out
}
}
}
if !found {
return false
}
return true
}
Loading

0 comments on commit 31e15d7

Please sign in to comment.