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:
Lei Huang 2024-06-24 13:04:50 -07:00
parent c4fb6fbda2
commit 171d298dea
22 changed files with 405 additions and 4 deletions

View File

@ -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

View File

@ -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@"

View File

@ -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@"

View File

@ -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@"

View File

@ -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@"

View File

@ -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@"

View File

@ -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@"

View File

@ -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@"

View File

@ -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@"

View File

@ -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@"

View File

@ -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@"

View File

@ -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@"

View File

@ -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@"

View File

@ -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@"

View File

@ -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@"

View File

@ -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
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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")
}

View 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"
}
]
}
}
]
}

View 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"`
}