network: Implement hotplug for physical endpoints

Enable physical network interfaces to be hotplugged.
For this, we need to change the signature of the HotAttach method
to make use of Sandbox instead of Hypervisor. Similar approach was
followed for Attach method, but this change was overlooked for
HotAttach.
The signature change is required in order to make use of
device manager and receiver for physical network
enpoints.

Fixes: #8405

Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
This commit is contained in:
Archana Shinde 2023-12-06 12:09:56 -08:00
parent 2fef4bc844
commit 1e304e6307
12 changed files with 48 additions and 15 deletions

View File

@ -26,7 +26,7 @@ type Endpoint interface {
SetPciPath(vcTypes.PciPath)
Attach(context.Context, *Sandbox) error
Detach(ctx context.Context, netNsCreated bool, netNsPath string) error
HotAttach(ctx context.Context, h Hypervisor) error
HotAttach(context.Context, *Sandbox) error
HotDetach(ctx context.Context, h Hypervisor, netNsCreated bool, netNsPath string) error
save() persistapi.NetworkEndpoint

View File

@ -125,10 +125,11 @@ func (endpoint *IPVlanEndpoint) Detach(ctx context.Context, netNsCreated bool, n
})
}
func (endpoint *IPVlanEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
func (endpoint *IPVlanEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
span, ctx := ipvlanTrace(ctx, "HotAttach", endpoint)
defer span.End()
h := s.hypervisor
if err := xConnectVMNetwork(ctx, endpoint, h); err != nil {
networkLogger().WithError(err).Error("Error bridging ipvlan ep")
return err

View File

@ -122,10 +122,11 @@ func (endpoint *MacvlanEndpoint) Detach(ctx context.Context, netNsCreated bool,
})
}
func (endpoint *MacvlanEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
func (endpoint *MacvlanEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
span, ctx := macvlanTrace(ctx, "HotAttach", endpoint)
defer span.End()
h := s.hypervisor
if err := xConnectVMNetwork(ctx, endpoint, h); err != nil {
networkLogger().WithError(err).Error("Error bridging macvlan ep")
return err

View File

@ -93,7 +93,7 @@ func (endpoint *MacvtapEndpoint) Detach(ctx context.Context, netNsCreated bool,
}
// HotAttach for macvtap endpoint not supported yet
func (endpoint *MacvtapEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
func (endpoint *MacvtapEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
return fmt.Errorf("MacvtapEndpoint does not support Hot attach")
}

View File

@ -202,7 +202,7 @@ func (n *LinuxNetwork) addSingleEndpoint(ctx context.Context, s *Sandbox, netInf
networkLogger().WithField("endpoint-type", endpoint.Type()).WithField("hotplug", hotplug).Info("Attaching endpoint")
if hotplug {
if err := endpoint.HotAttach(ctx, s.hypervisor); err != nil {
if err := endpoint.HotAttach(ctx, s); err != nil {
return nil, err
}
} else {

View File

@ -123,8 +123,32 @@ func (endpoint *PhysicalEndpoint) Detach(ctx context.Context, netNsCreated bool,
}
// HotAttach for physical endpoint not supported yet
func (endpoint *PhysicalEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
return fmt.Errorf("PhysicalEndpoint does not support Hot attach")
func (endpoint *PhysicalEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
span, ctx := physicalTrace(ctx, "HotAttach", endpoint)
defer span.End()
// Unbind physical interface from host driver and bind to vfio
// so that it can be passed to the hypervisor.
vfioPath, err := bindNICToVFIO(endpoint)
if err != nil {
return err
}
c, err := resCtrl.DeviceToCgroupDeviceRule(vfioPath)
if err != nil {
return err
}
d := config.DeviceInfo{
ContainerPath: vfioPath,
DevType: string(c.Type),
Major: c.Major,
Minor: c.Minor,
ColdPlug: false,
}
_, err = s.AddDevice(ctx, d)
return err
}
// HotDetach for physical endpoint not supported yet

View File

@ -27,9 +27,11 @@ func TestPhysicalEndpoint_HotAttach(t *testing.T) {
HardAddr: net.HardwareAddr{0x02, 0x00, 0xca, 0xfe, 0x00, 0x04}.String(),
}
h := &mockHypervisor{}
s := &Sandbox{
hypervisor: &mockHypervisor{},
}
err := v.HotAttach(context.Background(), h)
err := v.HotAttach(context.Background(), s)
assert.Error(err)
}

View File

@ -92,12 +92,13 @@ func (endpoint *TapEndpoint) Detach(ctx context.Context, netNsCreated bool, netN
}
// HotAttach for the tap endpoint uses hot plug device
func (endpoint *TapEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
func (endpoint *TapEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
networkLogger().Info("Hot attaching tap endpoint")
span, ctx := tapTrace(ctx, "HotAttach", endpoint)
defer span.End()
h := s.hypervisor
if err := tapNetwork(endpoint, h.HypervisorConfig().NumVCPUs(), h.HypervisorConfig().DisableVhostNet); err != nil {
networkLogger().WithError(err).Error("Error bridging tap ep")
return err

View File

@ -103,12 +103,13 @@ func (endpoint *TuntapEndpoint) Detach(ctx context.Context, netNsCreated bool, n
}
// HotAttach for the tun/tap endpoint uses hot plug device
func (endpoint *TuntapEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
func (endpoint *TuntapEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
networkLogger().Info("Hot attaching tun/tap endpoint")
span, ctx := tuntapTrace(ctx, "HotAttach", endpoint)
defer span.End()
h := s.hypervisor
if err := tuntapNetwork(endpoint, h.HypervisorConfig().NumVCPUs(), h.HypervisorConfig().DisableVhostNet); err != nil {
networkLogger().WithError(err).Error("Error bridging tun/tap ep")
return err

View File

@ -126,10 +126,11 @@ func (endpoint *VethEndpoint) Detach(ctx context.Context, netNsCreated bool, net
}
// HotAttach for the veth endpoint uses hot plug device
func (endpoint *VethEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
func (endpoint *VethEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
span, ctx := vethTrace(ctx, "HotAttach", endpoint)
defer span.End()
h := s.hypervisor
if err := xConnectVMNetwork(ctx, endpoint, h); err != nil {
networkLogger().WithError(err).Error("Error bridging virtual ep")
return err

View File

@ -107,7 +107,7 @@ func (endpoint *VhostUserEndpoint) Detach(ctx context.Context, netNsCreated bool
}
// HotAttach for vhostuser endpoint not supported yet
func (endpoint *VhostUserEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
func (endpoint *VhostUserEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
return fmt.Errorf("VhostUserEndpoint does not support Hot attach")
}

View File

@ -97,9 +97,11 @@ func TestVhostUserEndpoint_HotAttach(t *testing.T) {
EndpointType: VhostUserEndpointType,
}
h := &mockHypervisor{}
s := &Sandbox{
hypervisor: &mockHypervisor{},
}
err := v.HotAttach(context.Background(), h)
err := v.HotAttach(context.Background(), s)
assert.Error(err)
}