mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-04 02:56:18 +00:00
virtcontainers: support vhost and physical endpoints in AddInterface
Support to hotplug vhost and physical endpoints by AddInterface API Fixes #758 Signed-off-by: Ruidong Cao <caoruidong@huawei.com>
This commit is contained in:
parent
611158ac54
commit
ec87dca2d8
@ -152,6 +152,7 @@ type Endpoint interface {
|
||||
Name() string
|
||||
HardwareAddr() string
|
||||
Type() EndpointType
|
||||
PciAddr() string
|
||||
|
||||
SetProperties(NetworkInfo)
|
||||
Attach(hypervisor) error
|
||||
@ -178,6 +179,7 @@ type PhysicalEndpoint struct {
|
||||
BDF string
|
||||
Driver string
|
||||
VendorDeviceID string
|
||||
PCIAddr string
|
||||
}
|
||||
|
||||
// VhostUserEndpoint represents a vhost-user socket based network interface
|
||||
@ -189,6 +191,7 @@ type VhostUserEndpoint struct {
|
||||
IfaceName string
|
||||
EndpointProperties NetworkInfo
|
||||
EndpointType EndpointType
|
||||
PCIAddr string
|
||||
}
|
||||
|
||||
// Properties returns properties for the veth interface in the network pair.
|
||||
@ -212,6 +215,11 @@ func (endpoint *VirtualEndpoint) Type() EndpointType {
|
||||
return endpoint.EndpointType
|
||||
}
|
||||
|
||||
// PciAddr returns the PCI address of the endpoint.
|
||||
func (endpoint *VirtualEndpoint) PciAddr() string {
|
||||
return endpoint.PCIAddr
|
||||
}
|
||||
|
||||
// SetProperties sets the properties for the endpoint.
|
||||
func (endpoint *VirtualEndpoint) SetProperties(properties NetworkInfo) {
|
||||
endpoint.EndpointProperties = properties
|
||||
@ -309,6 +317,11 @@ 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
|
||||
}
|
||||
|
||||
// Attach for vhostuser endpoint
|
||||
func (endpoint *VhostUserEndpoint) Attach(h hypervisor) error {
|
||||
networkLogger().WithField("endpoint-type", "vhostuser").Info("Attaching endpoint")
|
||||
@ -378,6 +391,11 @@ func (endpoint *PhysicalEndpoint) Type() EndpointType {
|
||||
return endpoint.EndpointType
|
||||
}
|
||||
|
||||
// PciAddr returns the PCI address of the endpoint.
|
||||
func (endpoint *PhysicalEndpoint) PciAddr() string {
|
||||
return endpoint.PCIAddr
|
||||
}
|
||||
|
||||
// SetProperties sets the properties of the physical endpoint.
|
||||
func (endpoint *PhysicalEndpoint) SetProperties(properties NetworkInfo) {
|
||||
endpoint.EndpointProperties = properties
|
||||
@ -1302,7 +1320,10 @@ func createEndpointsFromScan(networkNSPath string, config NetworkConfig) ([]Endp
|
||||
|
||||
idx := 0
|
||||
for _, link := range linkList {
|
||||
var endpoint Endpoint
|
||||
var (
|
||||
endpoint Endpoint
|
||||
errCreate error
|
||||
)
|
||||
|
||||
netInfo, err := networkInfoFromLink(netlinkHandle, link)
|
||||
if err != nil {
|
||||
@ -1323,40 +1344,8 @@ func createEndpointsFromScan(networkNSPath string, config NetworkConfig) ([]Endp
|
||||
}
|
||||
|
||||
if err := doNetNS(networkNSPath, func(_ ns.NetNS) error {
|
||||
|
||||
// TODO: This is the incoming interface
|
||||
// based on the incoming interface we should create
|
||||
// an appropriate EndPoint based on interface type
|
||||
// This should be a switch
|
||||
|
||||
// Check if interface is a physical interface. Do not create
|
||||
// tap interface/bridge if it is.
|
||||
isPhysical, err := isPhysicalIface(netInfo.Iface.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isPhysical {
|
||||
networkLogger().WithField("interface", netInfo.Iface.Name).Info("Physical network interface found")
|
||||
endpoint, err = createPhysicalEndpoint(netInfo)
|
||||
} else {
|
||||
var socketPath string
|
||||
|
||||
// Check if this is a dummy interface which has a vhost-user socket associated with it
|
||||
socketPath, err = vhostUserSocketPath(netInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if socketPath != "" {
|
||||
networkLogger().WithField("interface", netInfo.Iface.Name).Info("VhostUser network interface found")
|
||||
endpoint, err = createVhostUserEndpoint(netInfo, socketPath)
|
||||
} else {
|
||||
endpoint, err = createVirtualNetworkEndpoint(idx, netInfo.Iface.Name, config.InterworkingModel)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
endpoint, errCreate = createEndpoint(netInfo, idx, config.InterworkingModel)
|
||||
return errCreate
|
||||
}); err != nil {
|
||||
return []Endpoint{}, err
|
||||
}
|
||||
@ -1370,6 +1359,43 @@ func createEndpointsFromScan(networkNSPath string, config NetworkConfig) ([]Endp
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
func createEndpoint(netInfo NetworkInfo, idx int, model NetInterworkingModel) (Endpoint, error) {
|
||||
var endpoint Endpoint
|
||||
// TODO: This is the incoming interface
|
||||
// based on the incoming interface we should create
|
||||
// an appropriate EndPoint based on interface type
|
||||
// This should be a switch
|
||||
|
||||
// Check if interface is a physical interface. Do not create
|
||||
// tap interface/bridge if it is.
|
||||
isPhysical, err := isPhysicalIface(netInfo.Iface.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if isPhysical {
|
||||
networkLogger().WithField("interface", netInfo.Iface.Name).Info("Physical network interface found")
|
||||
endpoint, err = createPhysicalEndpoint(netInfo)
|
||||
} else {
|
||||
var socketPath string
|
||||
|
||||
// Check if this is a dummy interface which has a vhost-user socket associated with it
|
||||
socketPath, err = vhostUserSocketPath(netInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if socketPath != "" {
|
||||
networkLogger().WithField("interface", netInfo.Iface.Name).Info("VhostUser network interface found")
|
||||
endpoint, err = createVhostUserEndpoint(netInfo, socketPath)
|
||||
} else {
|
||||
endpoint, err = createVirtualNetworkEndpoint(idx, netInfo.Iface.Name, model)
|
||||
}
|
||||
}
|
||||
|
||||
return endpoint, err
|
||||
}
|
||||
|
||||
// isPhysicalIface checks if an interface is a physical device.
|
||||
// We use ethtool here to not rely on device sysfs inside the network namespace.
|
||||
func isPhysicalIface(ifaceName string) (bool, error) {
|
||||
|
@ -1105,10 +1105,11 @@ func (s *Sandbox) AddInterface(inf *grpc.Interface) (*grpc.Interface, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
endpoint, err := createVirtualNetworkEndpoint(len(s.networkNS.Endpoints), inf.Name, s.config.NetworkConfig.InterworkingModel)
|
||||
endpoint, err := createEndpoint(netInfo, len(s.networkNS.Endpoints), s.config.NetworkConfig.InterworkingModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
endpoint.SetProperties(netInfo)
|
||||
if err := doNetNS(s.networkNS.NetNsPath, func(_ ns.NetNS) error {
|
||||
return endpoint.HotAttach(s.hypervisor)
|
||||
@ -1123,7 +1124,7 @@ func (s *Sandbox) AddInterface(inf *grpc.Interface) (*grpc.Interface, error) {
|
||||
}
|
||||
|
||||
// Add network for vm
|
||||
inf.PciAddr = endpoint.PCIAddr
|
||||
inf.PciAddr = endpoint.PciAddr()
|
||||
return s.agent.updateInterface(inf)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user