mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-27 19:35:32 +00:00
runtime: implement DAN in Go kata-runtime
The DAN feature has already been implemented in kata-runtime-rs, and this commit brings the same capability to the Go kata-runtime. Fixes: #9758 Signed-off-by: Lei Huang <leih@nvidia.com>
This commit is contained in:
parent
c4fb6fbda2
commit
171d298dea
@ -282,6 +282,9 @@ DEFBINDMOUNTS := []
|
||||
# Create Container Timeout in seconds
|
||||
DEFCREATECONTAINERTIMEOUT ?= 60
|
||||
|
||||
# Default directory of directly attachable network config.
|
||||
DEFDANCONF := /run/kata-containers/dans
|
||||
|
||||
SED = sed
|
||||
|
||||
CLI_DIR = cmd
|
||||
@ -772,6 +775,7 @@ USER_VARS += DEFSTATICRESOURCEMGMT_STRATOVIRT
|
||||
USER_VARS += DEFSTATICRESOURCEMGMT_TEE
|
||||
USER_VARS += DEFBINDMOUNTS
|
||||
USER_VARS += DEFCREATECONTAINERTIMEOUT
|
||||
USER_VARS += DEFDANCONF
|
||||
USER_VARS += DEFVFIOMODE
|
||||
USER_VARS += BUILDFLAGS
|
||||
|
||||
|
@ -248,3 +248,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -456,3 +456,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -375,3 +375,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -700,3 +700,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -677,3 +677,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -673,3 +673,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -698,3 +698,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -652,3 +652,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -630,3 +630,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -670,3 +670,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -667,3 +667,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -699,3 +699,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -296,3 +296,12 @@ experimental=@DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -400,3 +400,12 @@ experimental = @DEFAULTEXPFEATURES@
|
||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
||||
|
||||
# Base directory of directly attachable network config.
|
||||
# Network devices for VM-based containers are allowed to be placed in the
|
||||
# host netns to eliminate as many hops as possible, which is what we
|
||||
# called a "Directly Attachable Network". The config, set by special CNI
|
||||
# plugins, is used to tell the Kata containers what devices are attached
|
||||
# to the hypervisor.
|
||||
# (default: /run/kata-containers/dans)
|
||||
dan_conf = "@DEFDANCONF@"
|
||||
|
@ -188,6 +188,7 @@ type runtime struct {
|
||||
EnablePprof bool `toml:"enable_pprof"`
|
||||
DisableGuestEmptyDir bool `toml:"disable_guest_empty_dir"`
|
||||
CreateContainerTimeout uint64 `toml:"create_container_timeout"`
|
||||
DanConf string `toml:"dan_conf"`
|
||||
}
|
||||
|
||||
type agent struct {
|
||||
@ -1636,6 +1637,7 @@ func LoadConfiguration(configPath string, ignoreLogging bool) (resolvedConfigPat
|
||||
|
||||
config.DisableGuestEmptyDir = tomlConf.Runtime.DisableGuestEmptyDir
|
||||
|
||||
config.DanConfig = tomlConf.Runtime.DanConf
|
||||
if err := checkConfig(config); err != nil {
|
||||
return "", config, err
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
goruntime "runtime"
|
||||
@ -160,6 +161,9 @@ type RuntimeConfig struct {
|
||||
// CreateContainer timeout which, if provided, indicates the createcontainer request timeout
|
||||
// needed for the workload ( Mostly used for pulling images in the guest )
|
||||
CreateContainerTimeout uint64
|
||||
|
||||
// Base directory of directly attachable network config
|
||||
DanConfig string
|
||||
}
|
||||
|
||||
// AddKernelParam allows the addition of new kernel parameters to an existing
|
||||
@ -331,7 +335,11 @@ func containerDeviceInfos(spec specs.Spec) ([]config.DeviceInfo, error) {
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
func networkConfig(ocispec specs.Spec, config RuntimeConfig) (vc.NetworkConfig, error) {
|
||||
func getDanConfigPath(danConfigDir string, sandboxID string) string {
|
||||
return filepath.Join(danConfigDir, sandboxID+".json")
|
||||
}
|
||||
|
||||
func networkConfig(ocispec specs.Spec, sandboxID string, config RuntimeConfig) (vc.NetworkConfig, error) {
|
||||
linux := ocispec.Linux
|
||||
if linux == nil {
|
||||
return vc.NetworkConfig{}, ErrNoLinux
|
||||
@ -351,6 +359,12 @@ func networkConfig(ocispec specs.Spec, config RuntimeConfig) (vc.NetworkConfig,
|
||||
netConf.InterworkingModel = config.InterNetworkModel
|
||||
netConf.DisableNewNetwork = config.DisableNewNetNs
|
||||
|
||||
// if dan config exits, it will be used to config network in guest VM
|
||||
danConfig := getDanConfigPath(config.DanConfig, sandboxID)
|
||||
if _, err := os.Stat(danConfig); err == nil {
|
||||
netConf.DanConfigPath = danConfig
|
||||
}
|
||||
|
||||
return netConf, nil
|
||||
}
|
||||
|
||||
@ -1002,7 +1016,7 @@ func SandboxConfig(ocispec specs.Spec, runtime RuntimeConfig, bundlePath, cid st
|
||||
return vc.SandboxConfig{}, err
|
||||
}
|
||||
|
||||
networkConfig, err := networkConfig(ocispec, runtime)
|
||||
networkConfig, err := networkConfig(ocispec, cid, runtime)
|
||||
if err != nil {
|
||||
return vc.SandboxConfig{}, err
|
||||
}
|
||||
|
@ -195,6 +195,8 @@ type NetworkConfig struct {
|
||||
InterworkingModel NetInterworkingModel
|
||||
NetworkCreated bool
|
||||
DisableNewNetwork bool
|
||||
// if DAN config exists, use it to config network
|
||||
DanConfigPath string
|
||||
}
|
||||
|
||||
type Network interface {
|
||||
|
@ -7,6 +7,7 @@ package virtcontainers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
@ -26,6 +27,7 @@ import (
|
||||
|
||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils/katatrace"
|
||||
persistapi "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/api"
|
||||
vctypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
|
||||
)
|
||||
|
||||
@ -41,6 +43,7 @@ type LinuxNetwork struct {
|
||||
eps []Endpoint
|
||||
interworkingModel NetInterworkingModel
|
||||
netNSCreated bool
|
||||
danConfigPath string
|
||||
}
|
||||
|
||||
// NewNetwork creates a new Linux Network from a NetworkConfig.
|
||||
@ -68,6 +71,7 @@ func NewNetwork(configs ...*NetworkConfig) (Network, error) {
|
||||
[]Endpoint{},
|
||||
config.InterworkingModel,
|
||||
config.NetworkCreated,
|
||||
config.DanConfigPath,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -376,6 +380,102 @@ func (n *LinuxNetwork) addAllEndpoints(ctx context.Context, s *Sandbox, hotplug
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertDanDeviceToNetworkInfo(device *vctypes.DanDevice) (*NetworkInfo, error) {
|
||||
var netInfo NetworkInfo
|
||||
var err error
|
||||
netInfo.Iface.Name = device.Name
|
||||
if netInfo.Iface.HardwareAddr, err = net.ParseMAC(device.GuestMac); err != nil {
|
||||
return nil, fmt.Errorf("bad mac address in DAN config: %v", err)
|
||||
}
|
||||
netInfo.Iface.MTU = int(device.NetworkInfo.Interface.MTU)
|
||||
netInfo.Iface.Flags = net.Flags(device.NetworkInfo.Interface.Flags)
|
||||
|
||||
for _, addr := range device.NetworkInfo.Interface.IPAddresses {
|
||||
a, err := netlink.ParseAddr(addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("bad IP address in DAN config: %v", err)
|
||||
}
|
||||
|
||||
netInfo.Addrs = append(netInfo.Addrs, *a)
|
||||
}
|
||||
|
||||
for _, route := range device.NetworkInfo.Routes {
|
||||
var r netlink.Route
|
||||
if len(route.Dest) > 0 {
|
||||
if _, r.Dst, err = net.ParseCIDR(route.Dest); err != nil {
|
||||
return nil, fmt.Errorf("bad route dest in DAN config: %v", err)
|
||||
}
|
||||
}
|
||||
r.Src = net.ParseIP(route.Source)
|
||||
r.Gw = net.ParseIP(route.Gateway)
|
||||
r.Scope = netlink.Scope(route.Scope)
|
||||
if len(r.Gw.To4()) == net.IPv4len {
|
||||
r.Family = unix.AF_INET
|
||||
} else {
|
||||
r.Family = unix.AF_INET6
|
||||
}
|
||||
|
||||
netInfo.Routes = append(netInfo.Routes, r)
|
||||
}
|
||||
|
||||
for _, neigh := range device.NetworkInfo.Neighbors {
|
||||
var n netlink.Neigh
|
||||
n.State = int(neigh.State)
|
||||
n.Flags = int(neigh.Flags)
|
||||
if n.HardwareAddr, err = net.ParseMAC(neigh.HardwareAddr); err != nil {
|
||||
return nil, fmt.Errorf("bad neighbor hardware address in DAN config: %v", err)
|
||||
}
|
||||
|
||||
n.IP = net.ParseIP(neigh.IPAddress)
|
||||
netInfo.Neighbors = append(netInfo.Neighbors, n)
|
||||
}
|
||||
|
||||
return &netInfo, nil
|
||||
}
|
||||
|
||||
// Load network config in DAN config
|
||||
// Create the endpoints for the interfaces in Dan.
|
||||
func (n *LinuxNetwork) addDanEndpoints() error {
|
||||
|
||||
jsonData, err := os.ReadFile(n.danConfigPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fail to load DAN config file: %v", err)
|
||||
}
|
||||
|
||||
var config vctypes.DanConfig
|
||||
err = json.Unmarshal([]byte(jsonData), &config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fail to unmarshal DAN config: %v", err)
|
||||
}
|
||||
|
||||
for _, device := range config.Devices {
|
||||
var endpoint Endpoint
|
||||
networkLogger().WithField("interface", device.Name).Info("DAN interface found")
|
||||
|
||||
_, err := convertDanDeviceToNetworkInfo(&device)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: Add endpoints that are supported via DAN
|
||||
switch device.Device.Type {
|
||||
default:
|
||||
return fmt.Errorf("unknown DAN device type: '%s'", device.Device.Type)
|
||||
}
|
||||
|
||||
// TODO: remove below `nolink` directive after one `case` is added for
|
||||
// above `switch` block.
|
||||
//nolint: govet
|
||||
n.eps = append(n.eps, endpoint)
|
||||
}
|
||||
|
||||
sort.Slice(n.eps, func(i, j int) bool {
|
||||
return n.eps[i].Name() < n.eps[j].Name()
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run runs a callback in the specified network namespace.
|
||||
func (n *LinuxNetwork) Run(ctx context.Context, cb func() error) error {
|
||||
span, _ := n.trace(ctx, "Run")
|
||||
@ -393,8 +493,15 @@ func (n *LinuxNetwork) AddEndpoints(ctx context.Context, s *Sandbox, endpointsIn
|
||||
defer span.End()
|
||||
|
||||
if endpointsInfo == nil {
|
||||
if err := n.addAllEndpoints(ctx, s, hotplug); err != nil {
|
||||
return nil, err
|
||||
// If a sandbox has a DAN configuration, it takes priority and will be used exclusively.
|
||||
if n.danConfigPath != "" {
|
||||
if err := n.addDanEndpoints(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if err := n.addAllEndpoints(ctx, s, hotplug); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, ep := range endpointsInfo {
|
||||
|
@ -7,13 +7,18 @@ package virtcontainers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
||||
pbTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols"
|
||||
vctypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/vishvananda/netlink"
|
||||
@ -322,3 +327,51 @@ func TestTxRateLimiter(t *testing.T) {
|
||||
err = netHandle.LinkDel(link)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
func TestConvertDanDeviceToNetworkInfo(t *testing.T) {
|
||||
|
||||
jsonData, err := os.ReadFile("testdata/dan-config.json")
|
||||
assert.NoError(t, err)
|
||||
var config vctypes.DanConfig
|
||||
err = json.Unmarshal([]byte(jsonData), &config)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ni, err := convertDanDeviceToNetworkInfo(&config.Devices[0])
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1500, ni.Iface.MTU)
|
||||
|
||||
assert.Len(t, ni.Addrs, 1)
|
||||
assert.Equal(t, "10.10.0.5/24", ni.Addrs[0].String())
|
||||
|
||||
dest, _ := netlink.ParseIPNet("10.10.0.0/16")
|
||||
dest.IP = dest.IP.To4()
|
||||
routes := []netlink.Route{
|
||||
{Family: unix.AF_INET, Dst: nil, Gw: net.ParseIP("10.0.0.1"), Src: nil, Scope: 0},
|
||||
{Family: unix.AF_INET, Dst: dest, Gw: net.ParseIP("10.0.0.1"), Src: nil, Scope: 0},
|
||||
}
|
||||
assert.Equal(t, routes, ni.Routes)
|
||||
|
||||
neighMac, _ := net.ParseMAC("0a:58:0a:0a:0a:0a")
|
||||
neigh := netlink.Neigh{
|
||||
HardwareAddr: neighMac,
|
||||
IP: net.ParseIP("10.10.10.10"),
|
||||
}
|
||||
assert.Len(t, ni.Neighbors, 1)
|
||||
assert.Equal(t, neigh, ni.Neighbors[0])
|
||||
}
|
||||
|
||||
func TestAddEndpoints_Dan(t *testing.T) {
|
||||
|
||||
network := &LinuxNetwork{
|
||||
"net-123",
|
||||
[]Endpoint{},
|
||||
NetXConnectDefaultModel,
|
||||
true,
|
||||
"testdata/dan-config.json",
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
_, err := network.AddEndpoints(ctx, nil, nil, true)
|
||||
// TODO: this will be updated after adding supported DAN device
|
||||
assert.ErrorContains(t, err, "unknown DAN device type")
|
||||
}
|
||||
|
36
src/runtime/virtcontainers/testdata/dan-config.json
vendored
Normal file
36
src/runtime/virtcontainers/testdata/dan-config.json
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"netns": "netns",
|
||||
"devices": [
|
||||
{
|
||||
"name": "eth0",
|
||||
"guest_mac": "0a:58:0a:0a:00:05",
|
||||
"device": {
|
||||
"type": "vfio",
|
||||
"pci_device_id": "0000:85:02.5"
|
||||
},
|
||||
"network_info": {
|
||||
"interface": {
|
||||
"ip_addresses": [
|
||||
"10.10.0.5/24"
|
||||
],
|
||||
"mtu": 1500
|
||||
},
|
||||
"routes": [
|
||||
{
|
||||
"gateway": "10.0.0.1"
|
||||
},
|
||||
{
|
||||
"dest": "10.10.0.0/16",
|
||||
"gateway": "10.0.0.1"
|
||||
}
|
||||
],
|
||||
"Neighbors": [
|
||||
{
|
||||
"ip_address": "10.10.10.10",
|
||||
"hardware_addr": "0a:58:0a:0a:0a:0a"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
57
src/runtime/virtcontainers/types/dan.go
Normal file
57
src/runtime/virtcontainers/types/dan.go
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2024 NVIDIA Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package types
|
||||
|
||||
type DanConfig struct {
|
||||
Netns *string `json:"netns"`
|
||||
Devices []DanDevice `json:"devices"`
|
||||
}
|
||||
|
||||
type DanDevice struct {
|
||||
Name string `json:"name"`
|
||||
GuestMac string `json:"guest_mac"`
|
||||
Device Device `json:"device"`
|
||||
NetworkInfo NetworkInfo `json:"network_info"`
|
||||
}
|
||||
|
||||
// DanDeviceType identifies the type of the network interface.
|
||||
type DanDeviceType string
|
||||
|
||||
type Device struct {
|
||||
Type DanDeviceType `json:"type"`
|
||||
Path string `json:"path,omitempty"`
|
||||
PciDeviceID string `json:"pci_device_id,omitempty"`
|
||||
TapName string `json:"tap_name,omitempty"`
|
||||
QueueNum int `json:"queue_num,omitempty"`
|
||||
QueueSize int `json:"queue_size,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkInfo struct {
|
||||
Interface Interface `json:"interface,omitempty"`
|
||||
Routes []Route `json:"routes,omitempty"`
|
||||
Neighbors []ARPNeighbor `json:"neighbors,omitempty"`
|
||||
}
|
||||
|
||||
type Interface struct {
|
||||
IPAddresses []string `json:"ip_addresses"`
|
||||
MTU uint64 `json:"mtu"`
|
||||
NType string `json:"ntype,omitempty"`
|
||||
Flags uint32 `json:"flags,omitempty"`
|
||||
}
|
||||
|
||||
type Route struct {
|
||||
Dest string `json:"dest,omitempty"`
|
||||
Gateway string `json:"gateway"`
|
||||
Source string `json:"source,omitempty"`
|
||||
Scope uint32 `json:"scope,omitempty"`
|
||||
}
|
||||
|
||||
type ARPNeighbor struct {
|
||||
IPAddress string `json:"ip_address"`
|
||||
HardwareAddr string `json:"hardware_addr"`
|
||||
State uint32 `json:"state,omitempty"`
|
||||
Flags uint32 `json:"flags,omitempty"`
|
||||
}
|
Loading…
Reference in New Issue
Block a user