{"record":{"id":"5d70fa2ff671aa9b","repo":"cilium/cilium","slug":"attaching-netkit-program-s-w","errorCode":null,"errorMessage":"attaching netkit program %s: %w","messagePattern":"attaching netkit program (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/datapath/loader/tc.go","lineNumber":38,"sourceCode":"\t\"github.com/cilium/cilium/pkg/datapath/linux/safenetlink\"\n\t\"github.com/cilium/cilium/pkg/logging/logfields\"\n\t\"github.com/cilium/cilium/pkg/option\"\n)\n\n// attachSKBProgram attaches prog to device using tcx if available and enabled,\n// or legacy tc as a fallback.\nfunc attachSKBProgram(logger *slog.Logger, device netlink.Link, prog *ebpf.Program, progName, bpffsDir string, parent uint32, tcxEnabled bool) error {\n\tif prog == nil {\n\t\treturn fmt.Errorf(\"program %s is nil\", progName)\n\t}\n\n\tif tcxEnabled {\n\t\t// If the device is a netkit device, we know that netkit links are\n\t\t// supported, therefore use netkit instead of tcx. For all others like\n\t\t// host devices, rely on tcx.\n\t\tif device.Type() == \"netkit\" {\n\t\t\tif err := upsertNetkitProgram(logger, device, prog, progName, bpffsDir, parent); err != nil {\n\t\t\t\treturn fmt.Errorf(\"attaching netkit program %s: %w\", progName, err)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\t// Attach using tcx if available. This is seamless on interfaces with\n\t\t// existing tc programs since attaching tcx disables legacy tc evaluation.\n\t\terr := upsertTCXProgram(logger, device, prog, progName, bpffsDir, parent)\n\t\tif err == nil {\n\t\t\t// Created tcx link, clean up any leftover legacy tc attachments.\n\t\t\tif err := removeTCFilters(device, parent); err != nil {\n\t\t\t\tlogger.Warn(\n\t\t\t\t\t\"Cleaning up legacy tc after attaching tcx program\",\n\t\t\t\t\tlogfields.Error, err,\n\t\t\t\t\tlogfields.ProgName, progName,\n\t\t\t\t)\n\t\t\t}\n\t\t\t// Don't fall back to legacy tc.\n\t\t\treturn nil","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/datapath/loader/tc.go#L20-L56","documentation":"When tcx is enabled and the target device is a netkit link, attachSKBProgram delegates to upsertNetkitProgram; any failure is wrapped as \"attaching netkit program %s\". Netkit attachment goes through cilium's link helpers, so failures usually mean the netkit link does not support the attachment mode or the kernel lacks netkit support.","triggerScenarios":"attachSKBProgram(device.Type() == \"netkit\" && tcxEnabled) where upsertNetkitProgram fails: unsupported attach flags on the netkit peer, kernel without netkit attachment support despite the link type, or bpffs pin dir issues for the program link.","commonSituations":"Running on kernels older than netkit-attach requirements (e.g. pre-6.7 quirks) where the link exists but BPF link attach fails (EOPNOTSUPP/EINVAL); wrong parent/hook flags (ingress vs egress) passed down; corrupted pinned links in bpffs.","solutions":["Check the wrapped error for errno (EOPNOTSUPP, EINVAL) to see if the kernel supports netkit BPF linking.","Verify the parent/attach flags match netkit expectations (ingress/egress semantics).","Upgrade the kernel to a version fully supporting netkit program attachment.","Remove stale pinned program links in the bpffs dir and retry.","As a last resort, use a non-netkit device type or disable the netkit path."],"exampleFix":"// before: parent flags mismatched for netkit egress\nattachSKBProgram(log, nk, prog, name, dir, netkit_ingress, true)\n// after: match intended direction\nattachSKBProgram(log, nk, prog, name, dir, netkit_egress, true)","handlingStrategy":"try-catch","validationCode":"if device.Type() == \"netkit\" {\n    // ensure kernel supports netkit BPF linking before calling\n    if err := checkNetkitSupport(); err != nil {\n        return fmt.Errorf(\"netkit attach unsupported: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := attachSKBProgram(...); err != nil {\n    if strings.Contains(err.Error(), \"attaching netkit program\") {\n        if errors.Is(err, unix.EOPNOTSUPP) {\n            logger.Warn(\"kernel lacks netkit attach; use tcx/tc device instead\")\n        }\n        return err\n    }\n}","preventionTips":["Run kernels that fully support netkit program attachment","Use consistent ingress/egress parent flags for netkit links","Clean stale pinned netkit links in bpffs before re-attaching"],"tags":["ebpf","netkit","tcx","kernel"],"backgroundTag":"ebpf-attach-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}