123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- package sys
- import (
- "runtime"
- "syscall"
- "unsafe"
- "github.com/cilium/ebpf/internal/unix"
- )
- // ENOTSUPP is a Linux internal error code that has leaked into UAPI.
- //
- // It is not the same as ENOTSUP or EOPNOTSUPP.
- var ENOTSUPP = syscall.Errno(524)
- // BPF wraps SYS_BPF.
- //
- // Any pointers contained in attr must use the Pointer type from this package.
- func BPF(cmd Cmd, attr unsafe.Pointer, size uintptr) (uintptr, error) {
- // Prevent the Go profiler from repeatedly interrupting the verifier,
- // which could otherwise lead to a livelock due to receiving EAGAIN.
- if cmd == BPF_PROG_LOAD || cmd == BPF_PROG_RUN {
- maskProfilerSignal()
- defer unmaskProfilerSignal()
- }
- for {
- r1, _, errNo := unix.Syscall(unix.SYS_BPF, uintptr(cmd), uintptr(attr), size)
- runtime.KeepAlive(attr)
- // As of ~4.20 the verifier can be interrupted by a signal,
- // and returns EAGAIN in that case.
- if errNo == unix.EAGAIN && cmd == BPF_PROG_LOAD {
- continue
- }
- var err error
- if errNo != 0 {
- err = wrappedErrno{errNo}
- }
- return r1, err
- }
- }
- // Info is implemented by all structs that can be passed to the ObjInfo syscall.
- //
- // MapInfo
- // ProgInfo
- // LinkInfo
- // BtfInfo
- type Info interface {
- info() (unsafe.Pointer, uint32)
- }
- var _ Info = (*MapInfo)(nil)
- func (i *MapInfo) info() (unsafe.Pointer, uint32) {
- return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i))
- }
- var _ Info = (*ProgInfo)(nil)
- func (i *ProgInfo) info() (unsafe.Pointer, uint32) {
- return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i))
- }
- var _ Info = (*LinkInfo)(nil)
- func (i *LinkInfo) info() (unsafe.Pointer, uint32) {
- return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i))
- }
- var _ Info = (*BtfInfo)(nil)
- func (i *BtfInfo) info() (unsafe.Pointer, uint32) {
- return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i))
- }
- // ObjInfo retrieves information about a BPF Fd.
- //
- // info may be one of MapInfo, ProgInfo, LinkInfo and BtfInfo.
- func ObjInfo(fd *FD, info Info) error {
- ptr, len := info.info()
- err := ObjGetInfoByFd(&ObjGetInfoByFdAttr{
- BpfFd: fd.Uint(),
- InfoLen: len,
- Info: NewPointer(ptr),
- })
- runtime.KeepAlive(fd)
- return err
- }
- // BPFObjName is a null-terminated string made up of
- // 'A-Za-z0-9_' characters.
- type ObjName [unix.BPF_OBJ_NAME_LEN]byte
- // NewObjName truncates the result if it is too long.
- func NewObjName(name string) ObjName {
- var result ObjName
- copy(result[:unix.BPF_OBJ_NAME_LEN-1], name)
- return result
- }
- // LogLevel controls the verbosity of the kernel's eBPF program verifier.
- type LogLevel uint32
- const (
- BPF_LOG_LEVEL1 LogLevel = 1 << iota
- BPF_LOG_LEVEL2
- BPF_LOG_STATS
- )
- // LinkID uniquely identifies a bpf_link.
- type LinkID uint32
- // BTFID uniquely identifies a BTF blob loaded into the kernel.
- type BTFID uint32
- // TypeID identifies a type in a BTF blob.
- type TypeID uint32
- // MapFlags control map behaviour.
- type MapFlags uint32
- //go:generate stringer -type MapFlags
- const (
- BPF_F_NO_PREALLOC MapFlags = 1 << iota
- BPF_F_NO_COMMON_LRU
- BPF_F_NUMA_NODE
- BPF_F_RDONLY
- BPF_F_WRONLY
- BPF_F_STACK_BUILD_ID
- BPF_F_ZERO_SEED
- BPF_F_RDONLY_PROG
- BPF_F_WRONLY_PROG
- BPF_F_CLONE
- BPF_F_MMAPABLE
- BPF_F_PRESERVE_ELEMS
- BPF_F_INNER_MAP
- )
- // wrappedErrno wraps syscall.Errno to prevent direct comparisons with
- // syscall.E* or unix.E* constants.
- //
- // You should never export an error of this type.
- type wrappedErrno struct {
- syscall.Errno
- }
- func (we wrappedErrno) Unwrap() error {
- return we.Errno
- }
- func (we wrappedErrno) Error() string {
- if we.Errno == ENOTSUPP {
- return "operation not supported"
- }
- return we.Errno.Error()
- }
- type syscallError struct {
- error
- errno syscall.Errno
- }
- func Error(err error, errno syscall.Errno) error {
- return &syscallError{err, errno}
- }
- func (se *syscallError) Is(target error) bool {
- return target == se.error
- }
- func (se *syscallError) Unwrap() error {
- return se.errno
- }
|