syscalls.go (2674B)
1 package link 2 3 import ( 4 "errors" 5 6 "github.com/cilium/ebpf" 7 "github.com/cilium/ebpf/asm" 8 "github.com/cilium/ebpf/internal" 9 "github.com/cilium/ebpf/internal/sys" 10 "github.com/cilium/ebpf/internal/unix" 11 ) 12 13 // Type is the kind of link. 14 type Type = sys.LinkType 15 16 // Valid link types. 17 const ( 18 UnspecifiedType = sys.BPF_LINK_TYPE_UNSPEC 19 RawTracepointType = sys.BPF_LINK_TYPE_RAW_TRACEPOINT 20 TracingType = sys.BPF_LINK_TYPE_TRACING 21 CgroupType = sys.BPF_LINK_TYPE_CGROUP 22 IterType = sys.BPF_LINK_TYPE_ITER 23 NetNsType = sys.BPF_LINK_TYPE_NETNS 24 XDPType = sys.BPF_LINK_TYPE_XDP 25 PerfEventType = sys.BPF_LINK_TYPE_PERF_EVENT 26 ) 27 28 var haveProgAttach = internal.FeatureTest("BPF_PROG_ATTACH", "4.10", func() error { 29 prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ 30 Type: ebpf.CGroupSKB, 31 License: "MIT", 32 Instructions: asm.Instructions{ 33 asm.Mov.Imm(asm.R0, 0), 34 asm.Return(), 35 }, 36 }) 37 if err != nil { 38 return internal.ErrNotSupported 39 } 40 41 // BPF_PROG_ATTACH was introduced at the same time as CGgroupSKB, 42 // so being able to load the program is enough to infer that we 43 // have the syscall. 44 prog.Close() 45 return nil 46 }) 47 48 var haveProgAttachReplace = internal.FeatureTest("BPF_PROG_ATTACH atomic replacement", "5.5", func() error { 49 if err := haveProgAttach(); err != nil { 50 return err 51 } 52 53 prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ 54 Type: ebpf.CGroupSKB, 55 AttachType: ebpf.AttachCGroupInetIngress, 56 License: "MIT", 57 Instructions: asm.Instructions{ 58 asm.Mov.Imm(asm.R0, 0), 59 asm.Return(), 60 }, 61 }) 62 if err != nil { 63 return internal.ErrNotSupported 64 } 65 defer prog.Close() 66 67 // We know that we have BPF_PROG_ATTACH since we can load CGroupSKB programs. 68 // If passing BPF_F_REPLACE gives us EINVAL we know that the feature isn't 69 // present. 70 attr := sys.ProgAttachAttr{ 71 // We rely on this being checked after attachFlags. 72 TargetFd: ^uint32(0), 73 AttachBpfFd: uint32(prog.FD()), 74 AttachType: uint32(ebpf.AttachCGroupInetIngress), 75 AttachFlags: uint32(flagReplace), 76 } 77 78 err = sys.ProgAttach(&attr) 79 if errors.Is(err, unix.EINVAL) { 80 return internal.ErrNotSupported 81 } 82 if errors.Is(err, unix.EBADF) { 83 return nil 84 } 85 return err 86 }) 87 88 var haveBPFLink = internal.FeatureTest("bpf_link", "5.7", func() error { 89 attr := sys.LinkCreateAttr{ 90 // This is a hopefully invalid file descriptor, which triggers EBADF. 91 TargetFd: ^uint32(0), 92 ProgFd: ^uint32(0), 93 AttachType: sys.AttachType(ebpf.AttachCGroupInetIngress), 94 } 95 _, err := sys.LinkCreate(&attr) 96 if errors.Is(err, unix.EINVAL) { 97 return internal.ErrNotSupported 98 } 99 if errors.Is(err, unix.EBADF) { 100 return nil 101 } 102 return err 103 })