{"record":{"id":"29e2bb657952be51","repo":"cilium/cilium","slug":"pf-kernel-ifname-for-device-s-w","errorCode":null,"errorMessage":"pf kernel ifname for device %s: %w","messagePattern":"pf kernel ifname for device (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/networkdriver/sriov/sriov.go","lineNumber":471,"sourceCode":"\tdev.Vendor = strings.TrimSpace(string(vendor))\n\n\tdevice, err := os.ReadFile(filepath.Join(devicePath, \"device\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdev.DeviceID = strings.TrimSpace(string(device))\n\n\tpfPath, err := os.Readlink(filepath.Join(devicePath, \"physfn\"))\n\tif err != nil {\n\t\t// this is not a vf\n\t\treturn nil, errNotAVF\n\t}\n\n\tpfAddr := filepath.Base(pfPath)\n\n\tpfAttrs, ok := netlinkAttrs[PCIAddr(pfAddr)]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"pf kernel ifname for device %s: %w\", pfAddr, errInterfaceNotFound)\n\t}\n\n\tdev.PFName = pfAttrs.Name\n\tpfDevPath := filepath.Join(mgr.pciDevicesPath(), pfAddr)\n\n\t// to resolve the VF id, we iterate over all VFs under the PF attributes\n\t// and map the ids to the `virtfn$x` path under the pf device.\n\t// if the path linked matches the path of our vf address, then we found the id.\n\tfor _, vf := range pfAttrs.Vfs {\n\t\t// root@c3-small-x86-01-bernardo:/sys/class/net/enp2s0f0np0/device# readlink virtfn0\n\t\t// ../0000:02:00.2\n\t\t// root@c3-small-x86-01-bernardo:/sys/class/net/enp2s0f0np0/device# readlink virtfn1\n\t\t// ../0000:02:00.3\n\t\tv, err := os.Readlink(filepath.Join(pfDevPath, fmt.Sprintf(\"virtfn%d\", vf.ID)))\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n","sourceCodeStart":453,"sourceCodeEnd":489,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/networkdriver/sriov/sriov.go#L453-L489","documentation":"In parseDevice, after resolving the VF's parent PF PCI address from sysfs, the manager looks up the PF's netlink attributes by PCI address; if absent it cannot determine the PF kernel interface name and fails with errInterfaceNotFound. The PF netdev either doesn't exist or wasn't enumerated.","triggerScenarios":"Discovering a VF whose parent PF's PCI address is not in the pciAddr→netlink-attrs map built from LinkList — PF netdev missing, PF bound to a non-netdev driver (vfio-pci), or safenetlink.LinkList failing to return the PF.","commonSituations":"PF bound to DPDK drivers so no kernel interface exists; BIOS/boot option disabling the PF netdev; netlink enumeration race during node boot; sysfs mounted at a non-standard path so ParentDev resolution mismatches.","solutions":["Verify the PF has a kernel netdev: ls /sys/bus/pci/devices/<pf-addr>/net/.","If the PF must be kernel-managed, rebind it to its NIC driver (e.g. mlx5_core) instead of vfio-pci.","Re-run discovery after the PF netdev is registered; boot-time races resolve once links are up.","Check the manager's sysfs root (/host/sys) is mounted correctly in the container."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"pfNet := \"/sys/bus/pci/devices/\" + pfAddr + \"/net\"\nif entries, err := os.ReadDir(pfNet); err != nil || len(entries) == 0 {\n    return fmt.Errorf(\"PF %s has no kernel netdev; SR-IOV discovery will fail\", pfAddr)\n}","typeGuard":null,"tryCatchPattern":"devices, err := mgr.ListDevices(ctx)\nif err != nil {\n    if errors.Is(err, sriov.ErrInterfaceNotFound) {\n        // PF bound to userspace driver or missing; alert and re-run after fix\n    }\n    return err\n}","preventionTips":["Keep the PF bound to its kernel NIC driver when using the sriov manager.","Mount host /sys at the path the manager expects.","Start the manager after NIC drivers have registered their links."],"tags":["sriov","pci","netlink","discovery"],"backgroundTag":"interface-not-found","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}