mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-20 16:27:52 +00:00
Merge pull request #1214 from mcastelino/topic/network-simplify
Topic/network simplify
This commit is contained in:
@@ -289,12 +289,6 @@ path = "@NETMONPATH@"
|
||||
# the container network interface
|
||||
# Options:
|
||||
#
|
||||
# - bridged (Deprecated)
|
||||
# Uses a linux bridge to interconnect the container interface to
|
||||
# the VM. Works for most cases except macvlan and ipvlan.
|
||||
# ***NOTE: This feature has been deprecated with plans to remove this
|
||||
# feature in the future. Please use other network models listed below.
|
||||
#
|
||||
# - macvtap
|
||||
# Used when the Container network interface can be bridged using
|
||||
# macvtap.
|
||||
@@ -323,7 +317,7 @@ disable_guest_seccomp=@DEFDISABLEGUESTSECCOMP@
|
||||
# If enabled, the runtime will not create a network namespace for shim and hypervisor processes.
|
||||
# This option may have some potential impacts to your host. It should only be used when you know what you're doing.
|
||||
# `disable_new_netns` conflicts with `enable_netmon`
|
||||
# `disable_new_netns` conflicts with `internetworking_model=bridged` and `internetworking_model=macvtap`. It works only
|
||||
# `disable_new_netns` conflicts with `internetworking_model=tcfilter` and `internetworking_model=macvtap`. It works only
|
||||
# with `internetworking_model=none`. The tap device will be in the host network namespace and can connect to a bridge
|
||||
# (like OVS) directly.
|
||||
# If you are using docker, `disable_new_netns` only works with `docker run --net=none`
|
||||
|
@@ -371,12 +371,6 @@ path = "@NETMONPATH@"
|
||||
# the container network interface
|
||||
# Options:
|
||||
#
|
||||
# - bridged (Deprecated)
|
||||
# Uses a linux bridge to interconnect the container interface to
|
||||
# the VM. Works for most cases except macvlan and ipvlan.
|
||||
# ***NOTE: This feature has been deprecated with plans to remove this
|
||||
# feature in the future. Please use other network models listed below.
|
||||
#
|
||||
# - macvtap
|
||||
# Used when the Container network interface can be bridged using
|
||||
# macvtap.
|
||||
|
@@ -379,12 +379,6 @@ path = "@NETMONPATH@"
|
||||
# the container network interface
|
||||
# Options:
|
||||
#
|
||||
# - bridged (Deprecated)
|
||||
# Uses a linux bridge to interconnect the container interface to
|
||||
# the VM. Works for most cases except macvlan and ipvlan.
|
||||
# ***NOTE: This feature has been deprecated with plans to remove this
|
||||
# feature in the future. Please use other network models listed below.
|
||||
#
|
||||
# - macvtap
|
||||
# Used when the Container network interface can be bridged using
|
||||
# macvtap.
|
||||
@@ -413,7 +407,7 @@ disable_guest_seccomp=@DEFDISABLEGUESTSECCOMP@
|
||||
# If enabled, the runtime will not create a network namespace for shim and hypervisor processes.
|
||||
# This option may have some potential impacts to your host. It should only be used when you know what you're doing.
|
||||
# `disable_new_netns` conflicts with `enable_netmon`
|
||||
# `disable_new_netns` conflicts with `internetworking_model=bridged` and `internetworking_model=macvtap`. It works only
|
||||
# `disable_new_netns` conflicts with `internetworking_model=tcfilter` and `internetworking_model=macvtap`. It works only
|
||||
# with `internetworking_model=none`. The tap device will be in the host network namespace and can connect to a bridge
|
||||
# (like OVS) directly.
|
||||
# If you are using docker, `disable_new_netns` only works with `docker run --net=none`
|
||||
|
@@ -28,7 +28,7 @@ const defaultMemSize uint32 = 2048 // MiB
|
||||
const defaultMemSlots uint32 = 10
|
||||
const defaultMemOffset uint32 = 0 // MiB
|
||||
const defaultBridgesCount uint32 = 1
|
||||
const defaultInterNetworkingModel = "macvtap"
|
||||
const defaultInterNetworkingModel = "tcfilter"
|
||||
const defaultDisableBlockDeviceUse bool = false
|
||||
const defaultBlockDeviceDriver = "virtio-scsi"
|
||||
const defaultBlockDeviceCacheSet bool = false
|
||||
|
@@ -278,22 +278,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
|
||||
)
|
||||
|
@@ -38,22 +38,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.
|
||||
@@ -74,12 +62,8 @@ func (n NetInterworkingModel) IsValid() bool {
|
||||
const (
|
||||
defaultNetModelStr = "default"
|
||||
|
||||
bridgedNetModelStr = "bridged"
|
||||
|
||||
macvtapNetModelStr = "macvtap"
|
||||
|
||||
enlightenedNetModelStr = "enlightened"
|
||||
|
||||
tcFilterNetModelStr = "tcfilter"
|
||||
|
||||
noneNetModelStr = "none"
|
||||
@@ -91,15 +75,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
|
||||
@@ -325,11 +303,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 {
|
||||
@@ -400,10 +373,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.Tuntap); ok {
|
||||
return l, nil
|
||||
@@ -448,14 +417,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")
|
||||
}
|
||||
@@ -470,14 +435,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")
|
||||
}
|
||||
@@ -656,100 +617,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)
|
||||
}
|
||||
|
||||
// Clear the IP addresses from the veth interface to prevent ARP conflict
|
||||
netPair.VirtIface.Addrs, err = netlink.AddrList(link, netlink.FAMILY_V4)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to obtain veth IP addresses: %s", err)
|
||||
}
|
||||
|
||||
if err := clearIPs(link, netPair.VirtIface.Addrs); err != nil {
|
||||
return fmt.Errorf("Unable to clear veth IP addresses: %s", 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 {
|
||||
@@ -963,71 +830,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)
|
||||
}
|
||||
|
||||
// Restore the IPs that were cleared
|
||||
return setIPs(link, netPair.VirtIface.Addrs)
|
||||
}
|
||||
|
||||
func removeTCFiltering(endpoint Endpoint) error {
|
||||
netHandle, err := netlink.NewHandle()
|
||||
if err != nil {
|
||||
|
@@ -110,10 +110,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) {
|
||||
@@ -133,9 +131,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},
|
||||
}
|
||||
@@ -167,30 +163,6 @@ func TestGenerateRandomPrivateMacAdd(t *testing.T) {
|
||||
assert.NotEqual(addr1, addr2)
|
||||
}
|
||||
|
||||
func TestCreateGetBridgeLink(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)
|
||||
|
||||
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 tc.NotValid(ktu.NeedRoot()) {
|
||||
t.Skip(testDisabledAsNonRoot)
|
||||
@@ -228,11 +200,11 @@ func TestCreateMacVtap(t *testing.T) {
|
||||
|
||||
assert.NoError(err)
|
||||
|
||||
brName := "testbr0"
|
||||
brLink, _, err := createLink(netHandle, brName, &netlink.Bridge{}, 1)
|
||||
tapName := "testtap0"
|
||||
tapLink, _, err := createLink(netHandle, tapName, &netlink.Tuntap{}, 1)
|
||||
assert.NoError(err)
|
||||
|
||||
attrs := brLink.Attrs()
|
||||
attrs := tapLink.Attrs()
|
||||
|
||||
mcLink := &netlink.Macvtap{
|
||||
Macvlan: netlink.Macvlan{
|
||||
@@ -253,10 +225,10 @@ func TestCreateMacVtap(t *testing.T) {
|
||||
err = netHandle.LinkDel(macvtapLink)
|
||||
assert.NoError(err)
|
||||
|
||||
brLink, err = getLinkByName(netHandle, brName, &netlink.Bridge{})
|
||||
tapLink, err = getLinkByName(netHandle, tapName, &netlink.Tuntap{})
|
||||
assert.NoError(err)
|
||||
|
||||
err = netHandle.LinkDel(brLink)
|
||||
err = netHandle.LinkDel(tapLink)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
|
@@ -467,15 +467,8 @@ func (q *qemuArchBase) appendVSock(devices []govmmQemu.Device, vsock types.VSock
|
||||
|
||||
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
|
||||
|
Reference in New Issue
Block a user