github.com/cilium/cilium@v1.16.2/pkg/datapath/linux/probes/attach_cgroup.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package probes 5 6 import ( 7 "errors" 8 "fmt" 9 "sync" 10 11 "github.com/cilium/ebpf" 12 "github.com/cilium/ebpf/asm" 13 "github.com/cilium/ebpf/link" 14 "golang.org/x/sys/unix" 15 ) 16 17 // HaveAttachCgroup returns nil if the kernel is compiled with 18 // CONFIG_CGROUP_BPF. 19 // 20 // It's only an approximation and doesn't execute a successful cgroup attachment 21 // under the hood. If any unexpected errors are encountered, the original error 22 // is returned. 23 func HaveAttachCgroup() error { 24 attachCgroupOnce.Do(func() { 25 attachCgroupResult = haveAttachCgroup() 26 }) 27 28 return attachCgroupResult 29 } 30 31 func haveAttachCgroup() error { 32 // Load known-good program supported by the earliest kernels with cgroup 33 // support. 34 spec := &ebpf.ProgramSpec{ 35 Type: ebpf.CGroupSKB, 36 AttachType: ebpf.AttachCGroupInetIngress, 37 Instructions: asm.Instructions{ 38 asm.LoadImm(asm.R0, 0, asm.DWord), 39 asm.Return(), 40 }, 41 } 42 43 p, err := ebpf.NewProgramWithOptions(spec, ebpf.ProgramOptions{ 44 LogDisabled: true, 45 }) 46 if err != nil { 47 return fmt.Errorf("create cgroup program: %w: %w", err, ebpf.ErrNotSupported) 48 } 49 defer p.Close() 50 51 // Attaching to a non-cgroup node should result in EBADF when creating the 52 // link, compared to EINVAL if the kernel does not support or was compiled 53 // without CONFIG_CGROUP_BPF. 54 _, err = link.AttachCgroup(link.CgroupOptions{Path: "/dev/null", Program: p, Attach: spec.AttachType}) 55 if errors.Is(err, unix.EBADF) { 56 // The kernel checked the given file descriptor from within the cgroup prog 57 // attach handler. Assume it supports attaching cgroup progs. 58 return nil 59 } 60 if err != nil { 61 // Preserve the original error in the error string. Needs Go 1.20. 62 return fmt.Errorf("link cgroup program to /dev/null: %w: %w", err, ebpf.ErrNotSupported) 63 } 64 65 return errors.New("attaching prog to /dev/null did not result in error") 66 } 67 68 var attachCgroupOnce sync.Once 69 var attachCgroupResult error