mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-05 11:36:56 +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
|
Name() string
|
||||||
HardwareAddr() string
|
HardwareAddr() string
|
||||||
Type() EndpointType
|
Type() EndpointType
|
||||||
|
PciAddr() string
|
||||||
|
|
||||||
SetProperties(NetworkInfo)
|
SetProperties(NetworkInfo)
|
||||||
Attach(hypervisor) error
|
Attach(hypervisor) error
|
||||||
@ -178,6 +179,7 @@ type PhysicalEndpoint struct {
|
|||||||
BDF string
|
BDF string
|
||||||
Driver string
|
Driver string
|
||||||
VendorDeviceID string
|
VendorDeviceID string
|
||||||
|
PCIAddr string
|
||||||
}
|
}
|
||||||
|
|
||||||
// VhostUserEndpoint represents a vhost-user socket based network interface
|
// VhostUserEndpoint represents a vhost-user socket based network interface
|
||||||
@ -189,6 +191,7 @@ type VhostUserEndpoint struct {
|
|||||||
IfaceName string
|
IfaceName string
|
||||||
EndpointProperties NetworkInfo
|
EndpointProperties NetworkInfo
|
||||||
EndpointType EndpointType
|
EndpointType EndpointType
|
||||||
|
PCIAddr string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Properties returns properties for the veth interface in the network pair.
|
// Properties returns properties for the veth interface in the network pair.
|
||||||
@ -212,6 +215,11 @@ func (endpoint *VirtualEndpoint) Type() EndpointType {
|
|||||||
return endpoint.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.
|
// SetProperties sets the properties for the endpoint.
|
||||||
func (endpoint *VirtualEndpoint) SetProperties(properties NetworkInfo) {
|
func (endpoint *VirtualEndpoint) SetProperties(properties NetworkInfo) {
|
||||||
endpoint.EndpointProperties = properties
|
endpoint.EndpointProperties = properties
|
||||||
@ -309,6 +317,11 @@ func (endpoint *VhostUserEndpoint) SetProperties(properties NetworkInfo) {
|
|||||||
endpoint.EndpointProperties = properties
|
endpoint.EndpointProperties = properties
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PciAddr returns the PCI address of the endpoint.
|
||||||
|
func (endpoint *VhostUserEndpoint) PciAddr() string {
|
||||||
|
return endpoint.PCIAddr
|
||||||
|
}
|
||||||
|
|
||||||
// Attach for vhostuser endpoint
|
// Attach for vhostuser endpoint
|
||||||
func (endpoint *VhostUserEndpoint) Attach(h hypervisor) error {
|
func (endpoint *VhostUserEndpoint) Attach(h hypervisor) error {
|
||||||
networkLogger().WithField("endpoint-type", "vhostuser").Info("Attaching endpoint")
|
networkLogger().WithField("endpoint-type", "vhostuser").Info("Attaching endpoint")
|
||||||
@ -378,6 +391,11 @@ func (endpoint *PhysicalEndpoint) Type() EndpointType {
|
|||||||
return endpoint.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.
|
// SetProperties sets the properties of the physical endpoint.
|
||||||
func (endpoint *PhysicalEndpoint) SetProperties(properties NetworkInfo) {
|
func (endpoint *PhysicalEndpoint) SetProperties(properties NetworkInfo) {
|
||||||
endpoint.EndpointProperties = properties
|
endpoint.EndpointProperties = properties
|
||||||
@ -1302,7 +1320,10 @@ func createEndpointsFromScan(networkNSPath string, config NetworkConfig) ([]Endp
|
|||||||
|
|
||||||
idx := 0
|
idx := 0
|
||||||
for _, link := range linkList {
|
for _, link := range linkList {
|
||||||
var endpoint Endpoint
|
var (
|
||||||
|
endpoint Endpoint
|
||||||
|
errCreate error
|
||||||
|
)
|
||||||
|
|
||||||
netInfo, err := networkInfoFromLink(netlinkHandle, link)
|
netInfo, err := networkInfoFromLink(netlinkHandle, link)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1323,40 +1344,8 @@ func createEndpointsFromScan(networkNSPath string, config NetworkConfig) ([]Endp
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := doNetNS(networkNSPath, func(_ ns.NetNS) error {
|
if err := doNetNS(networkNSPath, func(_ ns.NetNS) error {
|
||||||
|
endpoint, errCreate = createEndpoint(netInfo, idx, config.InterworkingModel)
|
||||||
// TODO: This is the incoming interface
|
return errCreate
|
||||||
// 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
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return []Endpoint{}, err
|
return []Endpoint{}, err
|
||||||
}
|
}
|
||||||
@ -1370,6 +1359,43 @@ func createEndpointsFromScan(networkNSPath string, config NetworkConfig) ([]Endp
|
|||||||
return endpoints, nil
|
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.
|
// isPhysicalIface checks if an interface is a physical device.
|
||||||
// We use ethtool here to not rely on device sysfs inside the network namespace.
|
// We use ethtool here to not rely on device sysfs inside the network namespace.
|
||||||
func isPhysicalIface(ifaceName string) (bool, error) {
|
func isPhysicalIface(ifaceName string) (bool, error) {
|
||||||
|
@ -1105,10 +1105,11 @@ func (s *Sandbox) AddInterface(inf *grpc.Interface) (*grpc.Interface, error) {
|
|||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
endpoint.SetProperties(netInfo)
|
endpoint.SetProperties(netInfo)
|
||||||
if err := doNetNS(s.networkNS.NetNsPath, func(_ ns.NetNS) error {
|
if err := doNetNS(s.networkNS.NetNsPath, func(_ ns.NetNS) error {
|
||||||
return endpoint.HotAttach(s.hypervisor)
|
return endpoint.HotAttach(s.hypervisor)
|
||||||
@ -1123,7 +1124,7 @@ func (s *Sandbox) AddInterface(inf *grpc.Interface) (*grpc.Interface, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add network for vm
|
// Add network for vm
|
||||||
inf.PciAddr = endpoint.PCIAddr
|
inf.PciAddr = endpoint.PciAddr()
|
||||||
return s.agent.updateInterface(inf)
|
return s.agent.updateInterface(inf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user