Skip to content

Commit b4c5e84

Browse files
committed
Log or fail on each branch of SR-IOV VF MTU validation, add unit test
Signed-off-by: Masaharu Kanda <kanlkan.naklnak@gmail.com>
1 parent f8fa173 commit b4c5e84

2 files changed

Lines changed: 76 additions & 13 deletions

File tree

pkg/driver/dra_hooks.go

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -275,20 +275,25 @@ func (np *NetworkDriver) prepareResourceClaim(ctx context.Context, claim *resour
275275
deviceCfg.NetworkInterfaceConfigInPod.Interface.Name = ifName
276276
}
277277

278-
// For SR-IOV VFs, check that the requested MTU does not exceed the parent PF's MTU.
279-
// If it does, log an error and fail the Pod creation to avoid silent misconfiguration.
278+
// For SR-IOV VFs, the requested MTU must not exceed the parent PF's MTU.
279+
// Otherwise the claim is rejected so the Pod fails fast instead of being
280+
// created with an illegal MTU configuration.
280281
if deviceCfg.NetworkInterfaceConfigInPod.Interface.MTU != nil {
281-
if pfName, err := inventory.GetPFInterfaceName(ifName); err == nil {
282-
if pfLink, err := nlHandle.LinkByName(pfName); err == nil {
283-
pfMTU := pfLink.Attrs().MTU
284-
requestedMTU := int(*deviceCfg.NetworkInterfaceConfigInPod.Interface.MTU)
285-
if requestedMTU > pfMTU {
286-
klog.Errorf("requested MTU %d for SR-IOV VF %s exceeds parent PF %s MTU %d",
287-
requestedMTU, ifName, pfName, pfMTU)
288-
errorList = append(errorList, fmt.Errorf("requested MTU %d for SR-IOV VF %s exceeds parent PF %s MTU %d",
289-
requestedMTU, ifName, pfName, pfMTU))
290-
continue
291-
}
282+
pfName, err := inventory.GetPFInterfaceName(ifName)
283+
if err != nil {
284+
// Not an SR-IOV VF, or the parent PF cannot be determined. This is
285+
// expected for regular interfaces, so skip the check and only log it.
286+
klog.V(4).Infof("skipping SR-IOV VF MTU check for interface %s: %v", ifName, err)
287+
} else {
288+
pfLink, err := nlHandle.LinkByName(pfName)
289+
if err != nil {
290+
errorList = append(errorList, fmt.Errorf("failed to get netlink to parent PF %s of VF %s: %v", pfName, ifName, err))
291+
continue
292+
}
293+
requestedMTU := int(*deviceCfg.NetworkInterfaceConfigInPod.Interface.MTU)
294+
if err := validateVFMTU(ifName, pfName, requestedMTU, pfLink.Attrs().MTU); err != nil {
295+
errorList = append(errorList, err)
296+
continue
292297
}
293298
}
294299
}
@@ -517,6 +522,17 @@ func buildRDMAConfig(rdmaDevName string, charDevices sets.Set[string]) RDMAConfi
517522
return cfg
518523
}
519524

525+
// validateVFMTU returns an error if the MTU requested for an SR-IOV VF exceeds
526+
// the parent PF's MTU, which is an illegal configuration. vfName and pfName are
527+
// only used to build a descriptive error message.
528+
func validateVFMTU(vfName, pfName string, requestedMTU, pfMTU int) error {
529+
if requestedMTU > pfMTU {
530+
return fmt.Errorf("requested MTU %d for SR-IOV VF %s exceeds parent PF %s MTU %d",
531+
requestedMTU, vfName, pfName, pfMTU)
532+
}
533+
return nil
534+
}
535+
520536
// getRuleInfo lists all IP rules in the host network namespace and groups them
521537
// by the route table they are associated with. It returns a map where keys are
522538
// table IDs and values are slices of RuleConfig. Rules associated with the

pkg/driver/dra_hooks_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,50 @@ func TestPublishResourcesMetrics(t *testing.T) {
276276
}
277277
})
278278
}
279+
280+
func TestValidateVFMTU(t *testing.T) {
281+
testCases := []struct {
282+
name string
283+
requestedMTU int
284+
pfMTU int
285+
wantErr bool
286+
}{
287+
{
288+
name: "requested MTU below PF MTU is allowed",
289+
requestedMTU: 1500,
290+
pfMTU: 9000,
291+
wantErr: false,
292+
},
293+
{
294+
name: "requested MTU equal to PF MTU is allowed",
295+
requestedMTU: 9000,
296+
pfMTU: 9000,
297+
wantErr: false,
298+
},
299+
{
300+
name: "requested MTU above PF MTU is rejected",
301+
requestedMTU: 9000,
302+
pfMTU: 1500,
303+
wantErr: true,
304+
},
305+
}
306+
307+
for _, tc := range testCases {
308+
t.Run(tc.name, func(t *testing.T) {
309+
err := validateVFMTU("eth1", "eth0", tc.requestedMTU, tc.pfMTU)
310+
if tc.wantErr {
311+
if err == nil {
312+
t.Fatalf("validateVFMTU() expected error, got nil")
313+
}
314+
want := fmt.Sprintf("requested MTU %d for SR-IOV VF eth1 exceeds parent PF eth0 MTU %d", tc.requestedMTU, tc.pfMTU)
315+
if err.Error() != want {
316+
t.Errorf("validateVFMTU() error = %q, want %q", err.Error(), want)
317+
}
318+
return
319+
}
320+
if err != nil {
321+
t.Errorf("validateVFMTU() unexpected error: %v", err)
322+
}
323+
})
324+
}
325+
}

0 commit comments

Comments
 (0)