Skip to content

Commit

Permalink
added vxlan route manager to handle the route configuration and test …
Browse files Browse the repository at this point in the history
…suite
  • Loading branch information
alacuku authored and palexster committed Jun 9, 2021
1 parent 2bd1100 commit afe86ee
Show file tree
Hide file tree
Showing 7 changed files with 563 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -29,7 +29,7 @@ endif

# Run unit tests
unit: test-container
docker run --cap-add=NET_ADMIN --privileged=true --mount type=bind,src=$(shell pwd),dst=/go/src/liqo -w /go/src/liqo --rm liqo-test
docker run --privileged=true --mount type=bind,src=$(shell pwd),dst=/go/src/liqo -w /go/src/liqo --rm liqo-test

# Run e2e tests
e2e: gen
Expand Down
20 changes: 4 additions & 16 deletions pkg/liqonet/overlay/overlay_suite_test.go
@@ -1,13 +1,12 @@
package overlay

import (
"fmt"
"net"
"testing"

"github.com/vishvananda/netlink"

"github.com/liqotech/liqo/pkg/liqonet"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
Expand All @@ -23,27 +22,16 @@ func TestOverlay(t *testing.T) {

var _ = BeforeSuite(func() {
var err error
defaultIfaceIP, err = getIFaceIP("0.0.0.0")
defaultIfaceIP, err = getIFaceIP()
Expect(err).ShouldNot(HaveOccurred())
Expect(defaultIfaceIP).ShouldNot(BeNil())
// Create dummy link
err = netlink.LinkAdd(&netlink.Dummy{LinkAttrs: netlink.LinkAttrs{Name: "dummy-link"}})
Expect(err).ShouldNot(HaveOccurred())
})

/*var _ = AfterSuite(func() {
})*/

func getIFaceIP(ipAddress string) (net.IP, error) {
func getIFaceIP() (net.IP, error) {
var ifaceIndex int
// Convert the given IP address from string to net.IP format
ip := net.ParseIP(ipAddress)
if ip == nil {
return nil, &liqonet.ParseIPError{
IPToBeParsed: ipAddress,
}
}
routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
if err != nil {
return nil, err
Expand All @@ -55,7 +43,7 @@ func getIFaceIP(ipAddress string) (net.IP, error) {
}
}
if ifaceIndex == 0 {
return nil, &liqonet.NoRouteFound{IPAddress: ipAddress}
return nil, fmt.Errorf("unable to get ip for default interface")
}
// Get link.
link, err := netlink.LinkByIndex(ifaceIndex)
Expand Down
27 changes: 23 additions & 4 deletions pkg/liqonet/overlay/vxlan.go
Expand Up @@ -89,7 +89,7 @@ func createVxLanLink(link *netlink.Vxlan) (*netlink.Vxlan, error) {
// If a vxlan exists with the same name then we use this function to check if the configuration is the same.
func isVxlanConfigTheSame(newLink, current netlink.Link) bool {
if newLink.Type() != current.Type() {
klog.V(4).Infof("different types for the interfaces: newLink -> %v, current -> %v", newLink.Type(), current.Type())
klog.V(4).Infof("different types for the interfaces: newLink -> %s, current -> %s", newLink.Type(), current.Type())
return false
}
newNetlinkVxlan := newLink.(*netlink.Vxlan)
Expand All @@ -100,7 +100,7 @@ func isVxlanConfigTheSame(newLink, current netlink.Link) bool {
return false
}
if !reflect.DeepEqual(newNetlinkVxlan.SrcAddr, currentNetlinkVxlan.SrcAddr) {
klog.V(4).Infof("different Source Addresses for the interfaces: newLink -> %v, current -> %v", newNetlinkVxlan.SrcAddr, currentNetlinkVxlan.SrcAddr)
klog.V(4).Infof("different Source Addresses for the interfaces: newLink -> %s, current -> %s", newNetlinkVxlan.SrcAddr, currentNetlinkVxlan.SrcAddr)
return false
}
if newNetlinkVxlan.Port != currentNetlinkVxlan.Port {
Expand All @@ -111,9 +111,28 @@ func isVxlanConfigTheSame(newLink, current netlink.Link) bool {
return true
}

// ConfigureIPAddress configures the IP address of the vxlan interface.
// The IP address has to be in CIDR notation.
func (vxlan *VxlanDevice) ConfigureIPAddress(ipAddr string) error {
// Parse the address.
ipNet, err := netlink.ParseIPNet(ipAddr)
if err != nil {
return err
}
err = netlink.AddrAdd(vxlan.Link, &netlink.Addr{IPNet: ipNet})
if errors.Is(err, unix.EEXIST) {
klog.V(4).Infof("ip address %s is already configured on vxlan device %s", ipNet.String(), vxlan.Link.Name)
return nil
} else if err != nil {
return err
}
klog.Infof("IP address %s configured on vxlan device %s", ipNet.String(), vxlan.Link.Name)
return nil
}

// AddFDB adds a fdb entry for the given neighbor into the current vxlan device.
func (vxlan *VxlanDevice) AddFDB(n Neighbor) error {
klog.V(4).Infof("calling AppendFDB: %v, %v", n.IP, n.MAC)
klog.V(4).Infof("calling AppendFDB: %s, %s", n.IP, n.MAC)
err := netlink.NeighAdd(&netlink.Neigh{
LinkIndex: vxlan.Link.Index,
State: netlink.NUD_PERMANENT | netlink.NUD_NOARP,
Expand All @@ -123,7 +142,7 @@ func (vxlan *VxlanDevice) AddFDB(n Neighbor) error {
IP: n.IP,
HardwareAddr: n.MAC,
})
if errors.Is(err, unix.ENOENT) {
if errors.Is(err, unix.EEXIST) {
return nil
}
if err != nil {
Expand Down
48 changes: 44 additions & 4 deletions pkg/liqonet/overlay/vxlan_test.go
Expand Up @@ -12,6 +12,7 @@ import (
var (
vxlanConfig, vxlanOld *VxlanDeviceAttrs
vxlanOldLink netlink.Link
vxlanDev VxlanDevice
fdbOld, fdbNew Neighbor
)

Expand Down Expand Up @@ -97,6 +98,7 @@ var _ = Describe("Vxlan", func() {
Mtu: 1450,
}
vxlanOldLink, err = createLink(vxlanOld)
vxlanDev = VxlanDevice{Link: vxlanOldLink.(*netlink.Vxlan)}
Expect(err).ShouldNot(HaveOccurred())
Expect(vxlanOldLink).NotTo(BeNil())
mac, err := net.ParseMAC("92:ce:cb:3b:82:ee")
Expand Down Expand Up @@ -185,15 +187,13 @@ var _ = Describe("Vxlan", func() {
Describe("configuring fdb of a vxlan device", func() {
Context("adding new fdb entry", func() {
It("fdb does not exist, should return nil", func() {
vxlanDev := VxlanDevice{Link: vxlanOldLink.(*netlink.Vxlan)}
Expect(vxlanDev.AddFDB(fdbNew)).ShouldNot(HaveOccurred())
fdbs, err := netlink.NeighList(vxlanDev.Link.Index, syscall.AF_BRIDGE)
Expect(err).ShouldNot(HaveOccurred())
Expect(containsFdbEntry(fdbs, fdbNew)).Should(BeTrue())
})

It("fdb does exist, should return nil", func() {
vxlanDev := VxlanDevice{Link: vxlanOldLink.(*netlink.Vxlan)}
Expect(vxlanDev.AddFDB(fdbOld)).ShouldNot(HaveOccurred())
fdbs, err := netlink.NeighList(vxlanDev.Link.Index, syscall.AF_BRIDGE)
Expect(err).ShouldNot(HaveOccurred())
Expand All @@ -203,21 +203,61 @@ var _ = Describe("Vxlan", func() {

Context("removing fdb entry", func() {
It("fdb does not exist, should return nil", func() {
vxlanDev := VxlanDevice{Link: vxlanOldLink.(*netlink.Vxlan)}
Expect(vxlanDev.DelFDB(fdbNew)).ShouldNot(HaveOccurred())
fdbs, err := netlink.NeighList(vxlanDev.Link.Index, syscall.AF_BRIDGE)
Expect(err).ShouldNot(HaveOccurred())
Expect(containsFdbEntry(fdbs, fdbNew)).Should(BeFalse())
})

It("fdb does exist, should return nil", func() {
vxlanDev := VxlanDevice{Link: vxlanOldLink.(*netlink.Vxlan)}
Expect(vxlanDev.DelFDB(fdbOld)).ShouldNot(HaveOccurred())
fdbs, err := netlink.NeighList(vxlanDev.Link.Index, syscall.AF_BRIDGE)
Expect(err).ShouldNot(HaveOccurred())
Expect(containsFdbEntry(fdbs, fdbOld)).Should(BeFalse())
})
})

})

Describe("configure ip address for vxlan interface", func() {
Context("ip address is in wrong format", func() {
It("should return error", func() {
wrongAddress := "10.234.0.8"
err := vxlanDev.ConfigureIPAddress(wrongAddress)
Expect(err).Should(HaveOccurred())
Expect(err).Should(MatchError(&net.ParseError{
Type: "CIDR address",
Text: wrongAddress,
}))
})
})

Context("ip address is not configured", func() {
It("should return nil", func() {
ipAddress := "10.234.0.5/24"
err := vxlanDev.ConfigureIPAddress(ipAddress)
Expect(err).ShouldNot(HaveOccurred())
addresses, err := netlink.AddrList(vxlanDev.Link, netlink.FAMILY_V4)
Expect(err).ShouldNot(HaveOccurred())
Expect(len(addresses)).Should(BeNumerically("==", 1))
Expect(addresses[0].IPNet.String()).Should(Equal(ipAddress))
})
})

Context("ip address is already configured", func() {
It("should return nil", func() {
ipAddress := "10.234.0.5/24"
ipAddr, err := netlink.ParseIPNet(ipAddress)
Expect(err).ShouldNot(HaveOccurred())
err = netlink.AddrAdd(vxlanDev.Link, &netlink.Addr{IPNet: ipAddr})
Expect(err).ShouldNot(HaveOccurred())
err = vxlanDev.ConfigureIPAddress(ipAddress)
Expect(err).ShouldNot(HaveOccurred())
addresses, err := netlink.AddrList(vxlanDev.Link, netlink.FAMILY_V4)
Expect(err).ShouldNot(HaveOccurred())
Expect(len(addresses)).Should(BeNumerically("==", 1))
Expect(addresses[0].IPNet.String()).Should(Equal(ipAddress))
})
})
})
})
28 changes: 21 additions & 7 deletions pkg/liqonet/routing/routing_suite_test.go
Expand Up @@ -8,6 +8,8 @@ import (
"reflect"
"testing"

"github.com/liqotech/liqo/pkg/liqonet/overlay"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/vishvananda/netlink"
Expand All @@ -17,13 +19,15 @@ import (
)

var (
ipAddress1 = "10.0.0.1/24"
ipAddress1NoSubnet = "10.0.0.1"
ipAddress2 = "10.0.0.2/24"
ipAddress2NoSubnet = "10.0.0.2"
dummylink1, dummyLink2 netlink.Link
iFacesNames = []string{"lioo-test-1", "liqo-test-2"}
drm Routing
ipAddress1 = "10.0.0.1/24"
ipAddress1NoSubnet = "10.0.0.1"
ipAddress2 = "10.0.0.2/24"
ipAddress2NoSubnet = "10.0.0.2"
// The value of ipAddress2NoSubnet when is mapped to the overlay network.
ipAddress2NoSubnetOverlay = "240.0.0.2"
dummylink1, dummyLink2 netlink.Link
iFacesNames = []string{"liqo-test-1", "liqo-test-2"}
drm, vrm Routing

tep netv1alpha1.TunnelEndpoint
)
Expand Down Expand Up @@ -53,10 +57,20 @@ var _ = BeforeSuite(func() {
VethIFaceIndex: 12345,
GatewayIP: ipAddress2NoSubnet,
}}

// Create vxlan device for Vxlan Routing manager tests.
link, err := setUpVxlanLink(vxlanConfig)
Expect(err).ShouldNot(HaveOccurred())
overlayDevice = overlay.VxlanDevice{Link: link.(*netlink.Vxlan)}
// Create Vxlan Routing Manager.
vrm, err = NewVxlanRoutingManager(routingTableIDVRM, ipAddress1NoSubnet, overlayNetPrexif, overlayDevice)
Expect(err).Should(BeNil())
Expect(vrm).NotTo(BeNil())
})

var _ = AfterSuite(func() {
tearDownInterfaces()
deleteLink(vxlanConfig.Name)
})

func setUpInterfaces() {
Expand Down

0 comments on commit afe86ee

Please sign in to comment.