@@ -96,10 +96,6 @@ func unlockCNIExecution(lock *flock.Flock) {
9696}
9797
9898func handleVfioPciDetection (netConf * localtypes.NetConf ) error {
99- if netConf .DeviceID == "" {
100- return fmt .Errorf ("device ID is required for VFIO PCI detection" )
101- }
102-
10399 isVfioPci , err := utils .IsVfioPciDevice (netConf .DeviceID )
104100 if err != nil {
105101 return fmt .Errorf ("failed to check vfio-pci driver binding for device %s: %v" , netConf .DeviceID , err )
@@ -132,29 +128,45 @@ func getNetConfNetns(args *skel.CmdArgs) (*localtypes.NetConf, ns.NetNS, error)
132128 infiniBandAnnotation , configuredInfiniBand )
133129 }
134130
135- netConf .GUID = getGUIDFromConf (netConf )
136-
137- // Ensure GUID was provided if ib-kubernetes integration is enabled
138- if netConf .IBKubernetesEnabled && netConf .GUID == "" {
139- return nil , nil , fmt .Errorf (
140- "infiniband SRIOV-CNI failed, Unexpected error. GUID must be provided by ib-kubernetes" )
141- }
142-
143131 if netConf .RdmaIsolation {
144132 err = utils .EnsureRdmaSystemMode ()
145133 if err != nil {
146134 return nil , nil , err
147135 }
148136 }
149137
138+ // Validate deviceID is provided
139+ if netConf .DeviceID == "" {
140+ return nil , nil , fmt .Errorf ("deviceID is required" )
141+ }
142+
150143 // Handle vfio-pci detection
151144 if err := handleVfioPciDetection (netConf ); err != nil {
152145 return nil , nil , err
153146 }
154147
155- err = config .LoadDeviceInfo (netConf )
148+ // Check if device is PF or VF to load appropriate device info
149+ isVF , err := utils .IsVirtualFunction (netConf .DeviceID )
156150 if err != nil {
157- return nil , nil , fmt .Errorf ("failed to get device specific information. %v" , err )
151+ return nil , nil , fmt .Errorf ("failed to determine if device %s is VF or PF: %v" , netConf .DeviceID , err )
152+ }
153+ netConf .IsVFDevice = isVF
154+
155+ netConf .GUID = getGUIDFromConf (netConf )
156+
157+ // Ensure GUID was provided if ib-kubernetes integration is enabled
158+ // Note: PF devices already have their own GUID, so only check for VF devices
159+ if netConf .IBKubernetesEnabled && netConf .IsVFDevice && netConf .GUID == "" {
160+ return nil , nil , fmt .Errorf (
161+ "infiniband SRIOV-CNI failed, Unexpected error. GUID must be provided by ib-kubernetes" )
162+ }
163+
164+ // Only load VF device info for VF devices (PF devices don't need this)
165+ if netConf .IsVFDevice {
166+ err = config .LoadDeviceInfo (netConf )
167+ if err != nil {
168+ return nil , nil , fmt .Errorf ("failed to get VF device information: %v" , err )
169+ }
158170 }
159171
160172 netns , err := ns .GetNS (args .Netns )
@@ -249,23 +261,11 @@ func runIPAMPlugin(stdinData []byte, netConf *localtypes.NetConf) (_ *current.Re
249261 return newResult , nil
250262}
251263
252- func cmdAdd (args * skel.CmdArgs ) (retErr error ) {
253- netConf , netns , err := getNetConfNetns (args )
254- if err != nil {
255- return err
256- }
257- defer netns .Close ()
258-
264+ // handleVFAdd handles VF device configuration in cmdAdd
265+ func handleVFAdd (args * skel.CmdArgs , netConf * localtypes.NetConf , netns ns.NetNS , result * current.Result ) (retErr error ) {
259266 sm := sriov .NewSriovManager ()
260267
261- // Lock CNI operation to serialize the operation
262- lock , err := lockCNIExecution ()
263- if err != nil {
264- return err
265- }
266- defer unlockCNIExecution (lock )
267-
268- err = doVFConfig (sm , netConf , netns , args )
268+ err := doVFConfig (sm , netConf , netns , args )
269269 if err != nil {
270270 return err
271271 }
@@ -284,12 +284,6 @@ func cmdAdd(args *skel.CmdArgs) (retErr error) {
284284 }
285285 }()
286286
287- result := & current.Result {}
288- result .Interfaces = []* current.Interface {{
289- Name : args .IfName ,
290- Sandbox : netns .Path (),
291- }}
292-
293287 // VFIO devices don't have network interfaces, skip IPAM configuration
294288 if netConf .IPAM .Type != "" && ! netConf .VfioPciMode {
295289 var newResult * current.Result
@@ -318,14 +312,53 @@ func cmdAdd(args *skel.CmdArgs) (retErr error) {
318312 return err
319313 }
320314
321- result = newResult
315+ // Update result pointer to point to the new result
316+ * result = * newResult
322317 }
323318
324319 // Cache NetConf for CmdDel
325320 if err = utils .SaveNetConf (args .ContainerID , config .DefaultCNIDir , args .IfName , netConf ); err != nil {
326321 return fmt .Errorf ("error saving NetConf %q" , err )
327322 }
328323
324+ return nil
325+ }
326+
327+ func cmdAdd (args * skel.CmdArgs ) (retErr error ) {
328+ netConf , netns , err := getNetConfNetns (args )
329+ if err != nil {
330+ return err
331+ }
332+ defer netns .Close ()
333+
334+ // Lock CNI operation to serialize the operation
335+ lock , err := lockCNIExecution ()
336+ if err != nil {
337+ return err
338+ }
339+ defer unlockCNIExecution (lock )
340+
341+ result := & current.Result {}
342+ result .Interfaces = []* current.Interface {{
343+ Name : args .IfName ,
344+ Sandbox : netns .Path (),
345+ }}
346+
347+ // Check if device is PF (Physical Function) - flag was set in getNetConfNetns
348+ // PF passthrough devices don't need VF configuration
349+ if ! netConf .IsVFDevice {
350+ // PF device - just cache config and return success
351+ if err = utils .SaveNetConf (args .ContainerID , config .DefaultCNIDir , args .IfName , netConf ); err != nil {
352+ return fmt .Errorf ("error saving NetConf %q" , err )
353+ }
354+ } else {
355+ // VF device - continue with normal VF configuration
356+ err = handleVFAdd (args , netConf , netns , result )
357+ if err != nil {
358+ return err
359+ }
360+ }
361+
329362 return types .PrintResult (result , netConf .CNIVersion )
330363}
331364
@@ -340,6 +373,38 @@ func handleIPAMCleanup(netConf *localtypes.NetConf, stdinData []byte) error {
340373 return ipam .ExecDel (netConf .IPAM .Type , stdinData )
341374}
342375
376+ // handleVFCleanup performs VF-specific cleanup operations
377+ func handleVFCleanup (sm localtypes.Manager , netConf * localtypes.NetConf , args * skel.CmdArgs , netns ns.NetNS ) error {
378+ // VFIO devices don't have network interfaces to release
379+ if ! netConf .VfioPciMode {
380+ err := sm .ReleaseVF (netConf , args .IfName , args .ContainerID , netns )
381+ if err != nil {
382+ return err
383+ }
384+ }
385+
386+ // Move RDMA device to default namespace
387+ // Note(adrianc): Due to some un-intuitive kernel behavior (which i hope will change), moving an RDMA device
388+ // to namespace causes all of its associated ULP devices (IPoIB) to be recreated in the default namespace.
389+ // we strategically place this here to allow:
390+ // 1. netedv cleanup during ReleaseVF.
391+ // 2. rdma dev netns cleanup as ResetVFConfig will rebind the VF.
392+ // Doing anything would have yielded the same results however ResetVFConfig will eventually not trigger VF rebind.
393+ if netConf .RdmaIsolation {
394+ err := utils .MoveRdmaDevFromNs (netConf .RdmaNetState .ContainerRdmaDevName , netns )
395+ if err != nil {
396+ return fmt .Errorf (
397+ "failed to restore RDMA device %s to default namespace. %v" ,
398+ netConf .RdmaNetState .ContainerRdmaDevName , err )
399+ }
400+ }
401+
402+ if err := sm .ResetVFConfig (netConf ); err != nil {
403+ return fmt .Errorf ("cmdDel() error reseting VF: %q" , err )
404+ }
405+ return nil
406+ }
407+
343408func cmdDel (args * skel.CmdArgs ) (retErr error ) {
344409 // https://github.com/kubernetes/kubernetes/pull/35240
345410 if args .Netns == "" {
@@ -388,41 +453,18 @@ func cmdDel(args *skel.CmdArgs) (retErr error) {
388453 }
389454 defer netns .Close ()
390455
456+ if ! netConf .IsVFDevice {
457+ return nil
458+ }
459+
391460 // Lock CNI operation to serialize the operation
392461 lock , err := lockCNIExecution ()
393462 if err != nil {
394463 return err
395464 }
396465 defer unlockCNIExecution (lock )
397466
398- // VFIO devices don't have network interfaces to release
399- if ! netConf .VfioPciMode {
400- err = sm .ReleaseVF (netConf , args .IfName , args .ContainerID , netns )
401- if err != nil {
402- return err
403- }
404- }
405-
406- // Move RDMA device to default namespace
407- // Note(adrianc): Due to some un-intuitive kernel behavior (which i hope will change), moving an RDMA device
408- // to namespace causes all of its associated ULP devices (IPoIB) to be recreated in the default namespace.
409- // we strategically place this here to allow:
410- // 1. netedv cleanup during ReleaseVF.
411- // 2. rdma dev netns cleanup as ResetVFConfig will rebind the VF.
412- // Doing anything would have yielded the same results however ResetVFConfig will eventually not trigger VF rebind.
413- if netConf .RdmaIsolation {
414- err = utils .MoveRdmaDevFromNs (netConf .RdmaNetState .ContainerRdmaDevName , netns )
415- if err != nil {
416- return fmt .Errorf (
417- "failed to restore RDMA device %s to default namespace. %v" ,
418- netConf .RdmaNetState .ContainerRdmaDevName , err )
419- }
420- }
421-
422- if err = sm .ResetVFConfig (netConf ); err != nil {
423- return fmt .Errorf ("cmdDel() error reseting VF: %q" , err )
424- }
425- return nil
467+ return handleVFCleanup (sm , netConf , args , netns )
426468}
427469
428470func cmdCheck (args * skel.CmdArgs ) error {
0 commit comments