mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-01 07:47:15 +00:00
network: Set queues to 1 to ensure we get the network fds
We want to have the file descriptors of the opened tuntap device to pass them down to the VMMs, so the VMMs don't have to explicitly open a new tuntap device themselves, as the `container_kvm_t` label does not allow such a thing. With this change we ensure that what's currently done when using QEMU as the hypervisor, can be easily replicated with other VMMs, even if they don't support multiqueue. As a side effect of this, we need to close the received file descriptors in the code of the VMMs which are not going to use them. Fixes: #3533 Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
This commit is contained in:
parent
93b61e0f07
commit
0b75522e1f
@ -1457,25 +1457,22 @@ func (clh *cloudHypervisor) addNet(e Endpoint) error {
|
||||
mac := e.HardwareAddr()
|
||||
netPair := e.NetworkPair()
|
||||
if netPair == nil {
|
||||
return errors.New("net Pair to be added is nil, needed to get TAP path")
|
||||
return errors.New("net Pair to be added is nil, needed to get TAP file descriptors")
|
||||
}
|
||||
|
||||
tapPath := netPair.TapInterface.TAPIface.Name
|
||||
if tapPath == "" {
|
||||
return errors.New("TAP path in network pair is empty")
|
||||
if len(netPair.TapInterface.VMFds) == 0 {
|
||||
return errors.New("The file descriptors for the network pair are not present")
|
||||
}
|
||||
clh.netDevicesFiles[mac] = netPair.TapInterface.VMFds
|
||||
|
||||
clh.Logger().WithFields(log.Fields{
|
||||
"mac": mac,
|
||||
"tap": tapPath,
|
||||
}).Info("Adding Net")
|
||||
|
||||
netRateLimiterConfig := clh.getNetRateLimiterConfig()
|
||||
|
||||
net := chclient.NewNetConfig()
|
||||
net.Mac = &mac
|
||||
net.Tap = &tapPath
|
||||
if netRateLimiterConfig != nil {
|
||||
net.SetRateLimiterConfig(*netRateLimiterConfig)
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ package virtcontainers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -129,25 +130,30 @@ func TestCloudHypervisorAddVSock(t *testing.T) {
|
||||
// Check addNet appends to the network config list new configurations.
|
||||
// Check that the elements in the list has the correct values
|
||||
func TestCloudHypervisorAddNetCheckNetConfigListValues(t *testing.T) {
|
||||
macTest := "00:00:00:00:00"
|
||||
tapPath := "/path/to/tap"
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
macTest := "00:00:00:00:00"
|
||||
|
||||
file, err := ioutil.TempFile("", "netFd")
|
||||
assert.Nil(err)
|
||||
defer os.Remove(file.Name())
|
||||
|
||||
vmFds := make([]*os.File, 1)
|
||||
vmFds = append(vmFds, file)
|
||||
|
||||
clh := cloudHypervisor{}
|
||||
clh.netDevicesFiles = make(map[string][]*os.File)
|
||||
|
||||
e := &VethEndpoint{}
|
||||
e.NetPair.TAPIface.HardAddr = macTest
|
||||
e.NetPair.TapInterface.TAPIface.Name = tapPath
|
||||
e.NetPair.TapInterface.VMFds = vmFds
|
||||
|
||||
err := clh.addNet(e)
|
||||
err = clh.addNet(e)
|
||||
assert.Nil(err)
|
||||
|
||||
assert.Equal(len(*clh.netDevices), 1)
|
||||
if err == nil {
|
||||
assert.Equal(*(*clh.netDevices)[0].Mac, macTest)
|
||||
assert.Equal(*(*clh.netDevices)[0].Tap, tapPath)
|
||||
}
|
||||
|
||||
err = clh.addNet(e)
|
||||
@ -156,7 +162,6 @@ func TestCloudHypervisorAddNetCheckNetConfigListValues(t *testing.T) {
|
||||
assert.Equal(len(*clh.netDevices), 2)
|
||||
if err == nil {
|
||||
assert.Equal(*(*clh.netDevices)[1].Mac, macTest)
|
||||
assert.Equal(*(*clh.netDevices)[1].Tap, tapPath)
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,10 +170,18 @@ func TestCloudHypervisorAddNetCheckNetConfigListValues(t *testing.T) {
|
||||
func TestCloudHypervisorAddNetCheckEnpointTypes(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tapPath := "/path/to/tap"
|
||||
macTest := "00:00:00:00:00"
|
||||
|
||||
file, err := ioutil.TempFile("", "netFd")
|
||||
assert.Nil(err)
|
||||
defer os.Remove(file.Name())
|
||||
|
||||
vmFds := make([]*os.File, 1)
|
||||
vmFds = append(vmFds, file)
|
||||
|
||||
validVeth := &VethEndpoint{}
|
||||
validVeth.NetPair.TapInterface.TAPIface.Name = tapPath
|
||||
validVeth.NetPair.TAPIface.HardAddr = macTest
|
||||
validVeth.NetPair.TapInterface.VMFds = vmFds
|
||||
|
||||
type args struct {
|
||||
e Endpoint
|
||||
@ -189,9 +202,9 @@ func TestCloudHypervisorAddNetCheckEnpointTypes(t *testing.T) {
|
||||
clh.netDevicesFiles = make(map[string][]*os.File)
|
||||
if err := clh.addNet(tt.args.e); (err != nil) != tt.wantErr {
|
||||
t.Errorf("cloudHypervisor.addNet() error = %v, wantErr %v", err, tt.wantErr)
|
||||
|
||||
} else if err == nil {
|
||||
assert.Equal(*(*clh.netDevices)[0].Tap, tapPath)
|
||||
files := clh.netDevicesFiles[macTest]
|
||||
assert.Equal(files, vmFds)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -201,10 +214,15 @@ func TestCloudHypervisorAddNetCheckEnpointTypes(t *testing.T) {
|
||||
func TestCloudHypervisorNetRateLimiter(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
tapPath := "/path/to/tap"
|
||||
file, err := ioutil.TempFile("", "netFd")
|
||||
assert.Nil(err)
|
||||
defer os.Remove(file.Name())
|
||||
|
||||
vmFds := make([]*os.File, 1)
|
||||
vmFds = append(vmFds, file)
|
||||
|
||||
validVeth := &VethEndpoint{}
|
||||
validVeth.NetPair.TapInterface.TAPIface.Name = tapPath
|
||||
validVeth.NetPair.TapInterface.VMFds = vmFds
|
||||
|
||||
type args struct {
|
||||
bwMaxRate int64
|
||||
|
@ -927,6 +927,12 @@ func (fc *firecracker) fcAddNetDevice(ctx context.Context, endpoint Endpoint) {
|
||||
|
||||
ifaceID := endpoint.Name()
|
||||
|
||||
// VMFds are not used by Firecracker, as it opens the tuntap
|
||||
// device by its name. Let's just close those.
|
||||
for _, f := range endpoint.NetworkPair().TapInterface.VMFds {
|
||||
f.Close()
|
||||
}
|
||||
|
||||
// The implementation of rate limiter is based on TBF.
|
||||
// Rate Limiter defines a token bucket with a maximum capacity (size) to store tokens, and an interval for refilling purposes (refill_time).
|
||||
// The refill-rate is derived from size and refill_time, and it is the constant rate at which the tokens replenish.
|
||||
|
@ -411,6 +411,16 @@ func createLink(netHandle *netlink.Handle, name string, expectedLink netlink.Lin
|
||||
flags := netlink.TUNTAP_VNET_HDR | netlink.TUNTAP_NO_PI
|
||||
if queues > 0 {
|
||||
flags |= netlink.TUNTAP_MULTI_QUEUE_DEFAULTS
|
||||
} else {
|
||||
// We need to enforce `queues = 1` here in case
|
||||
// multi-queue is *not* supported, the reason being
|
||||
// `linkModify()`, a method called by `LinkAdd()`, only
|
||||
// returning the file descriptor of the opened tuntap
|
||||
// device when the queues are set to *non zero*.
|
||||
//
|
||||
// Please, for more information, refer to:
|
||||
// https://github.com/kata-containers/kata-containers/blob/e6e5d2593ac319329269d7b58c30f99ba7b2bf5a/src/runtime/vendor/github.com/vishvananda/netlink/link_linux.go#L1164-L1316
|
||||
queues = 1
|
||||
}
|
||||
newLink = &netlink.Tuntap{
|
||||
LinkAttrs: netlink.LinkAttrs{Name: name},
|
||||
|
Loading…
Reference in New Issue
Block a user