...

Source file src/github.com/cilium/ebpf/internal/sys/syscall.go

Documentation: github.com/cilium/ebpf/internal/sys

     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  }
   127  

View as plain text