syscall.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package sys
  2. import (
  3. "runtime"
  4. "syscall"
  5. "unsafe"
  6. "github.com/cilium/ebpf/internal/unix"
  7. )
  8. // BPF wraps SYS_BPF.
  9. //
  10. // Any pointers contained in attr must use the Pointer type from this package.
  11. func BPF(cmd Cmd, attr unsafe.Pointer, size uintptr) (uintptr, error) {
  12. for {
  13. r1, _, errNo := unix.Syscall(unix.SYS_BPF, uintptr(cmd), uintptr(attr), size)
  14. runtime.KeepAlive(attr)
  15. // As of ~4.20 the verifier can be interrupted by a signal,
  16. // and returns EAGAIN in that case.
  17. if errNo == unix.EAGAIN && cmd == BPF_PROG_LOAD {
  18. continue
  19. }
  20. var err error
  21. if errNo != 0 {
  22. err = wrappedErrno{errNo}
  23. }
  24. return r1, err
  25. }
  26. }
  27. // Info is implemented by all structs that can be passed to the ObjInfo syscall.
  28. //
  29. // MapInfo
  30. // ProgInfo
  31. // LinkInfo
  32. // BtfInfo
  33. type Info interface {
  34. info() (unsafe.Pointer, uint32)
  35. }
  36. var _ Info = (*MapInfo)(nil)
  37. func (i *MapInfo) info() (unsafe.Pointer, uint32) {
  38. return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i))
  39. }
  40. var _ Info = (*ProgInfo)(nil)
  41. func (i *ProgInfo) info() (unsafe.Pointer, uint32) {
  42. return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i))
  43. }
  44. var _ Info = (*LinkInfo)(nil)
  45. func (i *LinkInfo) info() (unsafe.Pointer, uint32) {
  46. return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i))
  47. }
  48. var _ Info = (*BtfInfo)(nil)
  49. func (i *BtfInfo) info() (unsafe.Pointer, uint32) {
  50. return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i))
  51. }
  52. // ObjInfo retrieves information about a BPF Fd.
  53. //
  54. // info may be one of MapInfo, ProgInfo, LinkInfo and BtfInfo.
  55. func ObjInfo(fd *FD, info Info) error {
  56. ptr, len := info.info()
  57. err := ObjGetInfoByFd(&ObjGetInfoByFdAttr{
  58. BpfFd: fd.Uint(),
  59. InfoLen: len,
  60. Info: NewPointer(ptr),
  61. })
  62. runtime.KeepAlive(fd)
  63. return err
  64. }
  65. // BPFObjName is a null-terminated string made up of
  66. // 'A-Za-z0-9_' characters.
  67. type ObjName [unix.BPF_OBJ_NAME_LEN]byte
  68. // NewObjName truncates the result if it is too long.
  69. func NewObjName(name string) ObjName {
  70. var result ObjName
  71. copy(result[:unix.BPF_OBJ_NAME_LEN-1], name)
  72. return result
  73. }
  74. // LinkID uniquely identifies a bpf_link.
  75. type LinkID uint32
  76. // BTFID uniquely identifies a BTF blob loaded into the kernel.
  77. type BTFID uint32
  78. // wrappedErrno wraps syscall.Errno to prevent direct comparisons with
  79. // syscall.E* or unix.E* constants.
  80. //
  81. // You should never export an error of this type.
  82. type wrappedErrno struct {
  83. syscall.Errno
  84. }
  85. func (we wrappedErrno) Unwrap() error {
  86. return we.Errno
  87. }
  88. type syscallError struct {
  89. error
  90. errno syscall.Errno
  91. }
  92. func Error(err error, errno syscall.Errno) error {
  93. return &syscallError{err, errno}
  94. }
  95. func (se *syscallError) Is(target error) bool {
  96. return target == se.error
  97. }
  98. func (se *syscallError) Unwrap() error {
  99. return se.errno
  100. }