mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-10-09 16:03:36 +00:00
Address some comments for code readability, also add some unit tests. Signed-off-by: Wei Zhang <weizhang555.zw@gmail.com>
172 lines
4.9 KiB
Go
172 lines
4.9 KiB
Go
// Copyright (c) 2018 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package virtcontainers
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/kata-containers/runtime/virtcontainers/device/config"
|
|
persistapi "github.com/kata-containers/runtime/virtcontainers/persist/api"
|
|
"github.com/kata-containers/runtime/virtcontainers/utils"
|
|
)
|
|
|
|
// Long term, this should be made more configurable. For now matching path
|
|
// provided by CNM VPP and OVS-DPDK plugins, available at github.com/clearcontainers/vpp and
|
|
// github.com/clearcontainers/ovsdpdk. The plugins create the socket on the host system
|
|
// using this path.
|
|
const hostSocketSearchPath = "/tmp/vhostuser_%s/vhu.sock"
|
|
|
|
// VhostUserEndpoint represents a vhost-user socket based network interface
|
|
type VhostUserEndpoint struct {
|
|
// Path to the vhost-user socket on the host system
|
|
SocketPath string
|
|
// MAC address of the interface
|
|
HardAddr string
|
|
IfaceName string
|
|
EndpointProperties NetworkInfo
|
|
EndpointType EndpointType
|
|
PCIAddr string
|
|
}
|
|
|
|
// Properties returns the properties of the interface.
|
|
func (endpoint *VhostUserEndpoint) Properties() NetworkInfo {
|
|
return endpoint.EndpointProperties
|
|
}
|
|
|
|
// Name returns name of the interface.
|
|
func (endpoint *VhostUserEndpoint) Name() string {
|
|
return endpoint.IfaceName
|
|
}
|
|
|
|
// HardwareAddr returns the mac address of the vhostuser network interface
|
|
func (endpoint *VhostUserEndpoint) HardwareAddr() string {
|
|
return endpoint.HardAddr
|
|
}
|
|
|
|
// Type indentifies the endpoint as a vhostuser endpoint.
|
|
func (endpoint *VhostUserEndpoint) Type() EndpointType {
|
|
return endpoint.EndpointType
|
|
}
|
|
|
|
// SetProperties sets the properties of the endpoint.
|
|
func (endpoint *VhostUserEndpoint) SetProperties(properties NetworkInfo) {
|
|
endpoint.EndpointProperties = properties
|
|
}
|
|
|
|
// PciAddr returns the PCI address of the endpoint.
|
|
func (endpoint *VhostUserEndpoint) PciAddr() string {
|
|
return endpoint.PCIAddr
|
|
}
|
|
|
|
// SetPciAddr sets the PCI address of the endpoint.
|
|
func (endpoint *VhostUserEndpoint) SetPciAddr(pciAddr string) {
|
|
endpoint.PCIAddr = pciAddr
|
|
}
|
|
|
|
// NetworkPair returns the network pair of the endpoint.
|
|
func (endpoint *VhostUserEndpoint) NetworkPair() *NetworkInterfacePair {
|
|
return nil
|
|
}
|
|
|
|
// Attach for vhostuser endpoint
|
|
func (endpoint *VhostUserEndpoint) Attach(h hypervisor) error {
|
|
// Generate a unique ID to be used for hypervisor commandline fields
|
|
randBytes, err := utils.GenerateRandomBytes(8)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
id := hex.EncodeToString(randBytes)
|
|
|
|
d := config.VhostUserDeviceAttrs{
|
|
DevID: id,
|
|
SocketPath: endpoint.SocketPath,
|
|
MacAddress: endpoint.HardAddr,
|
|
Type: config.VhostUserNet,
|
|
}
|
|
|
|
return h.addDevice(d, vhostuserDev)
|
|
}
|
|
|
|
// Detach for vhostuser endpoint
|
|
func (endpoint *VhostUserEndpoint) Detach(netNsCreated bool, netNsPath string) error {
|
|
return nil
|
|
}
|
|
|
|
// HotAttach for vhostuser endpoint not supported yet
|
|
func (endpoint *VhostUserEndpoint) HotAttach(h hypervisor) error {
|
|
return fmt.Errorf("VhostUserEndpoint does not support Hot attach")
|
|
}
|
|
|
|
// HotDetach for vhostuser endpoint not supported yet
|
|
func (endpoint *VhostUserEndpoint) HotDetach(h hypervisor, netNsCreated bool, netNsPath string) error {
|
|
return fmt.Errorf("VhostUserEndpoint does not support Hot detach")
|
|
}
|
|
|
|
// Create a vhostuser endpoint
|
|
func createVhostUserEndpoint(netInfo NetworkInfo, socket string) (*VhostUserEndpoint, error) {
|
|
|
|
vhostUserEndpoint := &VhostUserEndpoint{
|
|
SocketPath: socket,
|
|
HardAddr: netInfo.Iface.HardwareAddr.String(),
|
|
IfaceName: netInfo.Iface.Name,
|
|
EndpointType: VhostUserEndpointType,
|
|
}
|
|
return vhostUserEndpoint, nil
|
|
}
|
|
|
|
// findVhostUserNetSocketPath checks if an interface is a dummy placeholder
|
|
// for a vhost-user socket, and if it is it returns the path to the socket
|
|
func findVhostUserNetSocketPath(netInfo NetworkInfo) (string, error) {
|
|
if netInfo.Iface.Name == "lo" {
|
|
return "", nil
|
|
}
|
|
|
|
// check for socket file existence at known location.
|
|
for _, addr := range netInfo.Addrs {
|
|
socketPath := fmt.Sprintf(hostSocketSearchPath, addr.IPNet.IP)
|
|
if _, err := os.Stat(socketPath); err == nil {
|
|
return socketPath, nil
|
|
}
|
|
}
|
|
|
|
return "", nil
|
|
}
|
|
|
|
// vhostUserSocketPath returns the path of the socket discovered. This discovery
|
|
// will vary depending on the type of vhost-user socket.
|
|
// Today only VhostUserNetDevice is supported.
|
|
func vhostUserSocketPath(info interface{}) (string, error) {
|
|
|
|
switch v := info.(type) {
|
|
case NetworkInfo:
|
|
return findVhostUserNetSocketPath(v)
|
|
default:
|
|
return "", nil
|
|
}
|
|
|
|
}
|
|
|
|
func (endpoint *VhostUserEndpoint) save() persistapi.NetworkEndpoint {
|
|
return persistapi.NetworkEndpoint{
|
|
Type: string(endpoint.Type()),
|
|
VhostUser: &persistapi.VhostUserEndpoint{
|
|
IfaceName: endpoint.IfaceName,
|
|
PCIAddr: endpoint.PCIAddr,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (endpoint *VhostUserEndpoint) load(s persistapi.NetworkEndpoint) {
|
|
endpoint.EndpointType = VhostUserEndpointType
|
|
|
|
if s.VhostUser != nil {
|
|
endpoint.IfaceName = s.VhostUser.IfaceName
|
|
endpoint.PCIAddr = s.VhostUser.PCIAddr
|
|
}
|
|
}
|