Skip to content

Commit

Permalink
virtcontainers: Eliminate legacy networking models
Browse files Browse the repository at this point in the history
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: kata-containers#1213

Signed-off-by: Manohar Castelino <manohar.r.castelino@intel.com>
  • Loading branch information
mcastelino committed Feb 5, 2019
1 parent 5f1ca16 commit a89feac
Show file tree
Hide file tree
Showing 4 changed files with 0 additions and 234 deletions.
12 changes: 0 additions & 12 deletions virtcontainers/documentation/api/1.0/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,22 +273,10 @@ const (
// NetXConnectDefaultModel Ask to use DefaultNetInterworkingModel
NetXConnectDefaultModel NetInterworkingModel = iota

// NetXConnectBridgedModel uses a linux bridge to interconnect
// the container interface to the VM. This is the
// safe default that works for most cases except
// macvlan and ipvlan
NetXConnectBridgedModel

// NetXConnectMacVtapModel can be used when the Container network
// interface can be bridged using macvtap
NetXConnectMacVtapModel

// NetXConnectEnlightenedModel can be used when the Network plugins
// are enlightened to create VM native interfaces
// when requested by the runtime
// This will be used for vethtap, macvtap, ipvtap
NetXConnectEnlightenedModel

// NetXConnectInvalidModel is the last item to check valid values by IsValid()
NetXConnectInvalidModel
)
Expand Down
187 changes: 0 additions & 187 deletions virtcontainers/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,10 @@ const (
// NetXConnectDefaultModel Ask to use DefaultNetInterworkingModel
NetXConnectDefaultModel NetInterworkingModel = iota

// NetXConnectBridgedModel uses a linux bridge to interconnect
// the container interface to the VM. This is the
// safe default that works for most cases except
// macvlan and ipvlan
NetXConnectBridgedModel

// NetXConnectMacVtapModel can be used when the Container network
// interface can be bridged using macvtap
NetXConnectMacVtapModel

// NetXConnectEnlightenedModel can be used when the Network plugins
// are enlightened to create VM native interfaces
// when requested by the runtime
// This will be used for vethtap, macvtap, ipvtap
NetXConnectEnlightenedModel

// NetXConnectTCFilterModel redirects traffic from the network interface
// provided by the network plugin to a tap interface.
// This works for ipvlan and macvlan as well.
Expand All @@ -73,12 +61,8 @@ func (n NetInterworkingModel) IsValid() bool {
const (
defaultNetModelStr = "default"

bridgedNetModelStr = "bridged"

macvtapNetModelStr = "macvtap"

enlightenedNetModelStr = "enlightened"

tcFilterNetModelStr = "tcfilter"

noneNetModelStr = "none"
Expand All @@ -90,15 +74,9 @@ func (n *NetInterworkingModel) SetModel(modelName string) error {
case defaultNetModelStr:
*n = DefaultNetInterworkingModel
return nil
case bridgedNetModelStr:
*n = NetXConnectBridgedModel
return nil
case macvtapNetModelStr:
*n = NetXConnectMacVtapModel
return nil
case enlightenedNetModelStr:
*n = NetXConnectEnlightenedModel
return nil
case tcFilterNetModelStr:
*n = NetXConnectTCFilterModel
return nil
Expand Down Expand Up @@ -354,11 +332,6 @@ func createLink(netHandle *netlink.Handle, name string, expectedLink netlink.Lin
var fds []*os.File

switch expectedLink.Type() {
case (&netlink.Bridge{}).Type():
newLink = &netlink.Bridge{
LinkAttrs: netlink.LinkAttrs{Name: name},
MulticastSnooping: expectedLink.(*netlink.Bridge).MulticastSnooping,
}
case (&netlink.Tuntap{}).Type():
flags := netlink.TUNTAP_VNET_HDR
if queues > 0 {
Expand Down Expand Up @@ -427,10 +400,6 @@ func getLinkByName(netHandle *netlink.Handle, name string, expectedLink netlink.
}

switch expectedLink.Type() {
case (&netlink.Bridge{}).Type():
if l, ok := link.(*netlink.Bridge); ok {
return l, nil
}
case (&netlink.Tuntap{}).Type():
if l, ok := link.(*netlink.GenericLink); ok {
return l, nil
Expand Down Expand Up @@ -475,14 +444,10 @@ func xConnectVMNetwork(endpoint Endpoint, h hypervisor) error {
}

switch netPair.NetInterworkingModel {
case NetXConnectBridgedModel:
return bridgeNetworkPair(endpoint, queues, disableVhostNet)
case NetXConnectMacVtapModel:
return tapNetworkPair(endpoint, queues, disableVhostNet)
case NetXConnectTCFilterModel:
return setupTCFiltering(endpoint, queues, disableVhostNet)
case NetXConnectEnlightenedModel:
return fmt.Errorf("Unsupported networking model")
default:
return fmt.Errorf("Invalid internetworking model")
}
Expand All @@ -497,14 +462,10 @@ func xDisconnectVMNetwork(endpoint Endpoint) error {
}

switch netPair.NetInterworkingModel {
case NetXConnectBridgedModel:
return unBridgeNetworkPair(endpoint)
case NetXConnectMacVtapModel:
return untapNetworkPair(endpoint)
case NetXConnectTCFilterModel:
return removeTCFiltering(endpoint)
case NetXConnectEnlightenedModel:
return fmt.Errorf("Unsupported networking model")
default:
return fmt.Errorf("Invalid internetworking model")
}
Expand Down Expand Up @@ -683,90 +644,6 @@ func tapNetworkPair(endpoint Endpoint, queues int, disableVhostNet bool) error {
return nil
}

func bridgeNetworkPair(endpoint Endpoint, queues int, disableVhostNet bool) error {
netHandle, err := netlink.NewHandle()
if err != nil {
return err
}
defer netHandle.Delete()

netPair := endpoint.NetworkPair()

tapLink, fds, err := createLink(netHandle, netPair.TAPIface.Name, &netlink.Tuntap{}, queues)
if err != nil {
return fmt.Errorf("Could not create TAP interface: %s", err)
}
netPair.VMFds = fds

if !disableVhostNet {
vhostFds, err := createVhostFds(queues)
if err != nil {
return fmt.Errorf("Could not setup vhost fds %s : %s", netPair.VirtIface.Name, err)
}
netPair.VhostFds = vhostFds
}

var attrs *netlink.LinkAttrs
var link netlink.Link

link, err = getLinkForEndpoint(endpoint, netHandle)
if err != nil {
return err
}

attrs = link.Attrs()

// Save the veth MAC address to the TAP so that it can later be used
// to build the hypervisor command line. This MAC address has to be
// the one inside the VM in order to avoid any firewall issues. The
// bridge created by the network plugin on the host actually expects
// to see traffic from this MAC address and not another one.
netPair.TAPIface.HardAddr = attrs.HardwareAddr.String()

if err := netHandle.LinkSetMTU(tapLink, attrs.MTU); err != nil {
return fmt.Errorf("Could not set TAP MTU %d: %s", attrs.MTU, err)
}

hardAddr, err := net.ParseMAC(netPair.VirtIface.HardAddr)
if err != nil {
return err
}
if err := netHandle.LinkSetHardwareAddr(link, hardAddr); err != nil {
return fmt.Errorf("Could not set MAC address %s for veth interface %s: %s",
netPair.VirtIface.HardAddr, netPair.VirtIface.Name, err)
}

mcastSnoop := false
bridgeLink, _, err := createLink(netHandle, netPair.Name, &netlink.Bridge{MulticastSnooping: &mcastSnoop}, queues)
if err != nil {
return fmt.Errorf("Could not create bridge: %s", err)
}

if err := netHandle.LinkSetMaster(tapLink, bridgeLink.(*netlink.Bridge)); err != nil {
return fmt.Errorf("Could not attach TAP %s to the bridge %s: %s",
netPair.TAPIface.Name, netPair.Name, err)
}

if err := netHandle.LinkSetUp(tapLink); err != nil {
return fmt.Errorf("Could not enable TAP %s: %s", netPair.TAPIface.Name, err)
}

if err := netHandle.LinkSetMaster(link, bridgeLink.(*netlink.Bridge)); err != nil {
return fmt.Errorf("Could not attach veth %s to the bridge %s: %s",
netPair.VirtIface.Name, netPair.Name, err)
}

if err := netHandle.LinkSetUp(link); err != nil {
return fmt.Errorf("Could not enable veth %s: %s", netPair.VirtIface.Name, err)
}

if err := netHandle.LinkSetUp(bridgeLink); err != nil {
return fmt.Errorf("Could not enable bridge %s: %s", netPair.Name, err)
}

return nil
}

func setupTCFiltering(endpoint Endpoint, queues int, disableVhostNet bool) error {
netHandle, err := netlink.NewHandle()
if err != nil {
Expand Down Expand Up @@ -980,70 +857,6 @@ func untapNetworkPair(endpoint Endpoint) error {
return err
}

func unBridgeNetworkPair(endpoint Endpoint) error {
netHandle, err := netlink.NewHandle()
if err != nil {
return err
}
defer netHandle.Delete()

netPair := endpoint.NetworkPair()

tapLink, err := getLinkByName(netHandle, netPair.TAPIface.Name, &netlink.Tuntap{})
if err != nil {
return fmt.Errorf("Could not get TAP interface: %s", err)
}

bridgeLink, err := getLinkByName(netHandle, netPair.Name, &netlink.Bridge{})
if err != nil {
return fmt.Errorf("Could not get bridge interface: %s", err)
}

if err := netHandle.LinkSetDown(bridgeLink); err != nil {
return fmt.Errorf("Could not disable bridge %s: %s", netPair.Name, err)
}

if err := netHandle.LinkSetDown(tapLink); err != nil {
return fmt.Errorf("Could not disable TAP %s: %s", netPair.TAPIface.Name, err)
}

if err := netHandle.LinkSetNoMaster(tapLink); err != nil {
return fmt.Errorf("Could not detach TAP %s: %s", netPair.TAPIface.Name, err)
}

if err := netHandle.LinkDel(bridgeLink); err != nil {
return fmt.Errorf("Could not remove bridge %s: %s", netPair.Name, err)
}

if err := netHandle.LinkDel(tapLink); err != nil {
return fmt.Errorf("Could not remove TAP %s: %s", netPair.TAPIface.Name, err)
}

link, err := getLinkForEndpoint(endpoint, netHandle)
if err != nil {
return err
}

hardAddr, err := net.ParseMAC(netPair.TAPIface.HardAddr)
if err != nil {
return err
}
if err := netHandle.LinkSetHardwareAddr(link, hardAddr); err != nil {
return fmt.Errorf("Could not set MAC address %s for veth interface %s: %s",
netPair.VirtIface.HardAddr, netPair.VirtIface.Name, err)
}

if err := netHandle.LinkSetDown(link); err != nil {
return fmt.Errorf("Could not disable veth %s: %s", netPair.VirtIface.Name, err)
}

if err := netHandle.LinkSetNoMaster(link); err != nil {
return fmt.Errorf("Could not detach veth %s: %s", netPair.VirtIface.Name, err)
}

return nil
}

func removeTCFiltering(endpoint Endpoint) error {
netHandle, err := netlink.NewHandle()
if err != nil {
Expand Down
28 changes: 0 additions & 28 deletions virtcontainers/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,8 @@ func TestNetInterworkingModelIsValid(t *testing.T) {
}{
{"Invalid Model", NetXConnectInvalidModel, false},
{"Default Model", NetXConnectDefaultModel, true},
{"Bridged Model", NetXConnectBridgedModel, true},
{"TC Filter Model", NetXConnectTCFilterModel, true},
{"Macvtap Model", NetXConnectMacVtapModel, true},
{"Enlightened Model", NetXConnectEnlightenedModel, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand All @@ -140,9 +138,7 @@ func TestNetInterworkingModelSetModel(t *testing.T) {
}{
{"Invalid Model", "Invalid", true},
{"default Model", defaultNetModelStr, false},
{"bridged Model", bridgedNetModelStr, false},
{"macvtap Model", macvtapNetModelStr, false},
{"enlightened Model", enlightenedNetModelStr, false},
{"tcfilter Model", tcFilterNetModelStr, false},
{"none Model", noneNetModelStr, false},
}
Expand Down Expand Up @@ -174,30 +170,6 @@ func TestGenerateRandomPrivateMacAdd(t *testing.T) {
assert.NotEqual(addr1, addr2)
}

func TestCreateGetBridgeLink(t *testing.T) {
if os.Geteuid() != 0 {
t.Skip(testDisabledAsNonRoot)
}

assert := assert.New(t)

netHandle, err := netlink.NewHandle()
defer netHandle.Delete()

assert.NoError(err)

brName := "testbr0"
brLink, _, err := createLink(netHandle, brName, &netlink.Bridge{}, 1)
assert.NoError(err)
assert.NotNil(brLink)

brLink, err = getLinkByName(netHandle, brName, &netlink.Bridge{})
assert.NoError(err)

err = netHandle.LinkDel(brLink)
assert.NoError(err)
}

func TestCreateGetTunTapLink(t *testing.T) {
if os.Geteuid() != 0 {
t.Skip(testDisabledAsNonRoot)
Expand Down
7 changes: 0 additions & 7 deletions virtcontainers/qemu_arch_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,15 +432,8 @@ func (q *qemuArchBase) appendVSockPCI(devices []govmmQemu.Device, vsock kataVSOC

func networkModelToQemuType(model NetInterworkingModel) govmmQemu.NetDeviceType {
switch model {
case NetXConnectBridgedModel:
return govmmQemu.MACVTAP //TODO: We should rename MACVTAP to .NET_FD
case NetXConnectMacVtapModel:
return govmmQemu.MACVTAP
//case ModelEnlightened:
// Here the Network plugin will create a VM native interface
// which could be MacVtap, IpVtap, SRIOV, veth-tap, vhost-user
// In these cases we will determine the interface type here
// and pass in the native interface through
default:
//TAP should work for most other cases
return govmmQemu.TAP
Expand Down

0 comments on commit a89feac

Please sign in to comment.