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