syscall.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package internal
  2. import (
  3. "fmt"
  4. "path/filepath"
  5. "runtime"
  6. "unsafe"
  7. "github.com/cilium/ebpf/internal/unix"
  8. )
  9. //go:generate stringer -output syscall_string.go -type=BPFCmd
  10. // BPFCmd identifies a subcommand of the bpf syscall.
  11. type BPFCmd int
  12. // Well known BPF commands.
  13. const (
  14. BPF_MAP_CREATE BPFCmd = iota
  15. BPF_MAP_LOOKUP_ELEM
  16. BPF_MAP_UPDATE_ELEM
  17. BPF_MAP_DELETE_ELEM
  18. BPF_MAP_GET_NEXT_KEY
  19. BPF_PROG_LOAD
  20. BPF_OBJ_PIN
  21. BPF_OBJ_GET
  22. BPF_PROG_ATTACH
  23. BPF_PROG_DETACH
  24. BPF_PROG_TEST_RUN
  25. BPF_PROG_GET_NEXT_ID
  26. BPF_MAP_GET_NEXT_ID
  27. BPF_PROG_GET_FD_BY_ID
  28. BPF_MAP_GET_FD_BY_ID
  29. BPF_OBJ_GET_INFO_BY_FD
  30. BPF_PROG_QUERY
  31. BPF_RAW_TRACEPOINT_OPEN
  32. BPF_BTF_LOAD
  33. BPF_BTF_GET_FD_BY_ID
  34. BPF_TASK_FD_QUERY
  35. BPF_MAP_LOOKUP_AND_DELETE_ELEM
  36. BPF_MAP_FREEZE
  37. BPF_BTF_GET_NEXT_ID
  38. BPF_MAP_LOOKUP_BATCH
  39. BPF_MAP_LOOKUP_AND_DELETE_BATCH
  40. BPF_MAP_UPDATE_BATCH
  41. BPF_MAP_DELETE_BATCH
  42. BPF_LINK_CREATE
  43. BPF_LINK_UPDATE
  44. BPF_LINK_GET_FD_BY_ID
  45. BPF_LINK_GET_NEXT_ID
  46. BPF_ENABLE_STATS
  47. BPF_ITER_CREATE
  48. )
  49. // BPF wraps SYS_BPF.
  50. //
  51. // Any pointers contained in attr must use the Pointer type from this package.
  52. func BPF(cmd BPFCmd, attr unsafe.Pointer, size uintptr) (uintptr, error) {
  53. r1, _, errNo := unix.Syscall(unix.SYS_BPF, uintptr(cmd), uintptr(attr), size)
  54. runtime.KeepAlive(attr)
  55. var err error
  56. if errNo != 0 {
  57. err = errNo
  58. }
  59. return r1, err
  60. }
  61. type BPFProgAttachAttr struct {
  62. TargetFd uint32
  63. AttachBpfFd uint32
  64. AttachType uint32
  65. AttachFlags uint32
  66. ReplaceBpfFd uint32
  67. }
  68. func BPFProgAttach(attr *BPFProgAttachAttr) error {
  69. _, err := BPF(BPF_PROG_ATTACH, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
  70. return err
  71. }
  72. type BPFProgDetachAttr struct {
  73. TargetFd uint32
  74. AttachBpfFd uint32
  75. AttachType uint32
  76. }
  77. func BPFProgDetach(attr *BPFProgDetachAttr) error {
  78. _, err := BPF(BPF_PROG_DETACH, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
  79. return err
  80. }
  81. type bpfObjAttr struct {
  82. fileName Pointer
  83. fd uint32
  84. fileFlags uint32
  85. }
  86. const bpfFSType = 0xcafe4a11
  87. // BPFObjPin wraps BPF_OBJ_PIN.
  88. func BPFObjPin(fileName string, fd *FD) error {
  89. dirName := filepath.Dir(fileName)
  90. var statfs unix.Statfs_t
  91. if err := unix.Statfs(dirName, &statfs); err != nil {
  92. return err
  93. }
  94. if uint64(statfs.Type) != bpfFSType {
  95. return fmt.Errorf("%s is not on a bpf filesystem", fileName)
  96. }
  97. value, err := fd.Value()
  98. if err != nil {
  99. return err
  100. }
  101. attr := bpfObjAttr{
  102. fileName: NewStringPointer(fileName),
  103. fd: value,
  104. }
  105. _, err = BPF(BPF_OBJ_PIN, unsafe.Pointer(&attr), unsafe.Sizeof(attr))
  106. if err != nil {
  107. return fmt.Errorf("pin object %s: %w", fileName, err)
  108. }
  109. return nil
  110. }
  111. // BPFObjGet wraps BPF_OBJ_GET.
  112. func BPFObjGet(fileName string) (*FD, error) {
  113. attr := bpfObjAttr{
  114. fileName: NewStringPointer(fileName),
  115. }
  116. ptr, err := BPF(BPF_OBJ_GET, unsafe.Pointer(&attr), unsafe.Sizeof(attr))
  117. if err != nil {
  118. return nil, fmt.Errorf("get object %s: %w", fileName, err)
  119. }
  120. return NewFD(uint32(ptr)), nil
  121. }