Files
kata-containers/virtcontainers/network_test.go
Manohar Castelino dffc988d92 virtcontainers: Eliminate legacy networking models
Prior to the addition of tcMirroring support kata-runtime had
compatibility issues with some CNI plugins some of which were addressed
by the bridged model. With the addition of tc mode there are no gaps in
networking that can be filled by the bridged mode or enlightened mode
(which was never implemented).

Eliminate both of these options to simplify the setup.

Fixes: #1213

Signed-off-by: Manohar Castelino <manohar.r.castelino@intel.com>
2019-11-11 09:14:38 -08:00

272 lines
6.7 KiB
Go

// Copyright (c) 2016 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
package virtcontainers
import (
"net"
"os"
"reflect"
"testing"
ktu "github.com/kata-containers/runtime/pkg/katatestutils"
vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types"
"github.com/stretchr/testify/assert"
"github.com/vishvananda/netlink"
)
func TestCreateDeleteNetNS(t *testing.T) {
assert := assert.New(t)
if tc.NotValid(ktu.NeedRoot()) {
t.Skip(testDisabledAsNonRoot)
}
netNSPath, err := createNetNS()
assert.NoError(err)
assert.NotEmpty(netNSPath)
_, err = os.Stat(netNSPath)
assert.NoError(err)
err = deleteNetNS(netNSPath)
assert.NoError(err)
}
func TestGenerateInterfacesAndRoutes(t *testing.T) {
//
//Create a couple of addresses
//
address1 := &net.IPNet{IP: net.IPv4(172, 17, 0, 2), Mask: net.CIDRMask(16, 32)}
address2 := &net.IPNet{IP: net.IPv4(182, 17, 0, 2), Mask: net.CIDRMask(16, 32)}
addrs := []netlink.Addr{
{IPNet: address1, Label: "phyaddr1"},
{IPNet: address2, Label: "phyaddr2"},
}
// Create a couple of routes:
dst2 := &net.IPNet{IP: net.IPv4(172, 17, 0, 0), Mask: net.CIDRMask(16, 32)}
src2 := net.IPv4(172, 17, 0, 2)
gw2 := net.IPv4(172, 17, 0, 1)
routes := []netlink.Route{
{LinkIndex: 329, Dst: nil, Src: nil, Gw: net.IPv4(172, 17, 0, 1), Scope: netlink.Scope(254)},
{LinkIndex: 329, Dst: dst2, Src: src2, Gw: gw2},
}
networkInfo := NetworkInfo{
Iface: NetlinkIface{
LinkAttrs: netlink.LinkAttrs{MTU: 1500},
Type: "",
},
Addrs: addrs,
Routes: routes,
}
ep0 := &PhysicalEndpoint{
IfaceName: "eth0",
HardAddr: net.HardwareAddr{0x02, 0x00, 0xca, 0xfe, 0x00, 0x04}.String(),
EndpointProperties: networkInfo,
}
endpoints := []Endpoint{ep0}
nns := NetworkNamespace{NetNsPath: "foobar", NetNsCreated: true, Endpoints: endpoints}
resInterfaces, resRoutes, err := generateInterfacesAndRoutes(nns)
//
// Build expected results:
//
expectedAddresses := []*vcTypes.IPAddress{
{Family: netlink.FAMILY_V4, Address: "172.17.0.2", Mask: "16"},
{Family: netlink.FAMILY_V4, Address: "182.17.0.2", Mask: "16"},
}
expectedInterfaces := []*vcTypes.Interface{
{Device: "eth0", Name: "eth0", IPAddresses: expectedAddresses, Mtu: 1500, HwAddr: "02:00:ca:fe:00:04"},
}
expectedRoutes := []*vcTypes.Route{
{Dest: "", Gateway: "172.17.0.1", Device: "eth0", Source: "", Scope: uint32(254)},
{Dest: "172.17.0.0/16", Gateway: "172.17.0.1", Device: "eth0", Source: "172.17.0.2"},
}
assert.Nil(t, err, "unexpected failure when calling generateKataInterfacesAndRoutes")
assert.True(t, reflect.DeepEqual(resInterfaces, expectedInterfaces),
"Interfaces returned didn't match: got %+v, expecting %+v", resInterfaces, expectedInterfaces)
assert.True(t, reflect.DeepEqual(resRoutes, expectedRoutes),
"Routes returned didn't match: got %+v, expecting %+v", resRoutes, expectedRoutes)
}
func TestNetInterworkingModelIsValid(t *testing.T) {
tests := []struct {
name string
n NetInterworkingModel
want bool
}{
{"Invalid Model", NetXConnectInvalidModel, false},
{"Default Model", NetXConnectDefaultModel, true},
{"TC Filter Model", NetXConnectTCFilterModel, true},
{"Macvtap Model", NetXConnectMacVtapModel, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.n.IsValid(); got != tt.want {
t.Errorf("NetInterworkingModel.IsValid() = %v, want %v", got, tt.want)
}
})
}
}
func TestNetInterworkingModelSetModel(t *testing.T) {
var n NetInterworkingModel
tests := []struct {
name string
modelName string
wantErr bool
}{
{"Invalid Model", "Invalid", true},
{"default Model", defaultNetModelStr, false},
{"macvtap Model", macvtapNetModelStr, false},
{"tcfilter Model", tcFilterNetModelStr, false},
{"none Model", noneNetModelStr, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := n.SetModel(tt.modelName); (err != nil) != tt.wantErr {
t.Errorf("NetInterworkingModel.SetModel() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestGenerateRandomPrivateMacAdd(t *testing.T) {
assert := assert.New(t)
addr1, err := generateRandomPrivateMacAddr()
assert.NoError(err)
_, err = net.ParseMAC(addr1)
assert.NoError(err)
addr2, err := generateRandomPrivateMacAddr()
assert.NoError(err)
_, err = net.ParseMAC(addr2)
assert.NoError(err)
assert.NotEqual(addr1, addr2)
}
func TestCreateGetTunTapLink(t *testing.T) {
if tc.NotValid(ktu.NeedRoot()) {
t.Skip(testDisabledAsNonRoot)
}
assert := assert.New(t)
netHandle, err := netlink.NewHandle()
defer netHandle.Delete()
assert.NoError(err)
tapName := "testtap0"
tapLink, fds, err := createLink(netHandle, tapName, &netlink.Tuntap{}, 1)
assert.NoError(err)
assert.NotNil(tapLink)
assert.NotZero(len(fds))
tapLink, err = getLinkByName(netHandle, tapName, &netlink.Tuntap{})
assert.NoError(err)
err = netHandle.LinkDel(tapLink)
assert.NoError(err)
}
func TestCreateMacVtap(t *testing.T) {
if tc.NotValid(ktu.NeedRoot()) {
t.Skip(testDisabledAsNonRoot)
}
assert := assert.New(t)
netHandle, err := netlink.NewHandle()
defer netHandle.Delete()
assert.NoError(err)
tapName := "testtap0"
tapLink, _, err := createLink(netHandle, tapName, &netlink.Tuntap{}, 1)
assert.NoError(err)
attrs := tapLink.Attrs()
mcLink := &netlink.Macvtap{
Macvlan: netlink.Macvlan{
LinkAttrs: netlink.LinkAttrs{
TxQLen: attrs.TxQLen,
ParentIndex: attrs.Index,
},
},
}
macvtapName := "testmc0"
_, err = createMacVtap(netHandle, macvtapName, mcLink, 1)
assert.NoError(err)
macvtapLink, err := getLinkByName(netHandle, macvtapName, &netlink.Macvtap{})
assert.NoError(err)
err = netHandle.LinkDel(macvtapLink)
assert.NoError(err)
tapLink, err = getLinkByName(netHandle, tapName, &netlink.Tuntap{})
assert.NoError(err)
err = netHandle.LinkDel(tapLink)
assert.NoError(err)
}
func TestTcRedirectNetwork(t *testing.T) {
if tc.NotValid(ktu.NeedRoot()) {
t.Skip(testDisabledAsNonRoot)
}
assert := assert.New(t)
netHandle, err := netlink.NewHandle()
assert.NoError(err)
defer netHandle.Delete()
// Create a test veth interface.
vethName := "foo"
veth := &netlink.Veth{LinkAttrs: netlink.LinkAttrs{Name: vethName, TxQLen: 200, MTU: 1400}, PeerName: "bar"}
err = netlink.LinkAdd(veth)
assert.NoError(err)
endpoint, err := createVethNetworkEndpoint(1, vethName, NetXConnectTCFilterModel)
assert.NoError(err)
link, err := netlink.LinkByName(vethName)
assert.NoError(err)
err = netHandle.LinkSetUp(link)
assert.NoError(err)
err = setupTCFiltering(endpoint, 1, true)
assert.NoError(err)
err = removeTCFiltering(endpoint)
assert.NoError(err)
// Remove the veth created for testing.
err = netHandle.LinkDel(link)
assert.NoError(err)
}