syscalls.go 2.6 KB

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