123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- package internal
- import (
- "fmt"
- "path/filepath"
- "runtime"
- "unsafe"
- "github.com/cilium/ebpf/internal/unix"
- )
- //go:generate stringer -output syscall_string.go -type=BPFCmd
- // BPFCmd identifies a subcommand of the bpf syscall.
- type BPFCmd int
- // Well known BPF commands.
- const (
- BPF_MAP_CREATE BPFCmd = iota
- BPF_MAP_LOOKUP_ELEM
- BPF_MAP_UPDATE_ELEM
- BPF_MAP_DELETE_ELEM
- BPF_MAP_GET_NEXT_KEY
- BPF_PROG_LOAD
- BPF_OBJ_PIN
- BPF_OBJ_GET
- BPF_PROG_ATTACH
- BPF_PROG_DETACH
- BPF_PROG_TEST_RUN
- BPF_PROG_GET_NEXT_ID
- BPF_MAP_GET_NEXT_ID
- BPF_PROG_GET_FD_BY_ID
- BPF_MAP_GET_FD_BY_ID
- BPF_OBJ_GET_INFO_BY_FD
- BPF_PROG_QUERY
- BPF_RAW_TRACEPOINT_OPEN
- BPF_BTF_LOAD
- BPF_BTF_GET_FD_BY_ID
- BPF_TASK_FD_QUERY
- BPF_MAP_LOOKUP_AND_DELETE_ELEM
- BPF_MAP_FREEZE
- BPF_BTF_GET_NEXT_ID
- BPF_MAP_LOOKUP_BATCH
- BPF_MAP_LOOKUP_AND_DELETE_BATCH
- BPF_MAP_UPDATE_BATCH
- BPF_MAP_DELETE_BATCH
- BPF_LINK_CREATE
- BPF_LINK_UPDATE
- BPF_LINK_GET_FD_BY_ID
- BPF_LINK_GET_NEXT_ID
- BPF_ENABLE_STATS
- BPF_ITER_CREATE
- )
- // BPF wraps SYS_BPF.
- //
- // Any pointers contained in attr must use the Pointer type from this package.
- func BPF(cmd BPFCmd, attr unsafe.Pointer, size uintptr) (uintptr, error) {
- r1, _, errNo := unix.Syscall(unix.SYS_BPF, uintptr(cmd), uintptr(attr), size)
- runtime.KeepAlive(attr)
- var err error
- if errNo != 0 {
- err = errNo
- }
- return r1, err
- }
- type BPFProgAttachAttr struct {
- TargetFd uint32
- AttachBpfFd uint32
- AttachType uint32
- AttachFlags uint32
- ReplaceBpfFd uint32
- }
- func BPFProgAttach(attr *BPFProgAttachAttr) error {
- _, err := BPF(BPF_PROG_ATTACH, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
- return err
- }
- type BPFProgDetachAttr struct {
- TargetFd uint32
- AttachBpfFd uint32
- AttachType uint32
- }
- func BPFProgDetach(attr *BPFProgDetachAttr) error {
- _, err := BPF(BPF_PROG_DETACH, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
- return err
- }
- type BPFEnableStatsAttr struct {
- StatsType uint32
- }
- func BPFEnableStats(attr *BPFEnableStatsAttr) (*FD, error) {
- ptr, err := BPF(BPF_ENABLE_STATS, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
- if err != nil {
- return nil, fmt.Errorf("enable stats: %w", err)
- }
- return NewFD(uint32(ptr)), nil
- }
- type bpfObjAttr struct {
- fileName Pointer
- fd uint32
- fileFlags uint32
- }
- const bpfFSType = 0xcafe4a11
- // BPFObjPin wraps BPF_OBJ_PIN.
- func BPFObjPin(fileName string, fd *FD) error {
- dirName := filepath.Dir(fileName)
- var statfs unix.Statfs_t
- if err := unix.Statfs(dirName, &statfs); err != nil {
- return err
- }
- if uint64(statfs.Type) != bpfFSType {
- return fmt.Errorf("%s is not on a bpf filesystem", fileName)
- }
- value, err := fd.Value()
- if err != nil {
- return err
- }
- attr := bpfObjAttr{
- fileName: NewStringPointer(fileName),
- fd: value,
- }
- _, err = BPF(BPF_OBJ_PIN, unsafe.Pointer(&attr), unsafe.Sizeof(attr))
- if err != nil {
- return fmt.Errorf("pin object %s: %w", fileName, err)
- }
- return nil
- }
- // BPFObjGet wraps BPF_OBJ_GET.
- func BPFObjGet(fileName string) (*FD, error) {
- attr := bpfObjAttr{
- fileName: NewStringPointer(fileName),
- }
- ptr, err := BPF(BPF_OBJ_GET, unsafe.Pointer(&attr), unsafe.Sizeof(attr))
- if err != nil {
- return nil, fmt.Errorf("get object %s: %w", fileName, err)
- }
- return NewFD(uint32(ptr)), nil
- }
- type bpfObjGetInfoByFDAttr struct {
- fd uint32
- infoLen uint32
- info Pointer
- }
- // BPFObjGetInfoByFD wraps BPF_OBJ_GET_INFO_BY_FD.
- //
- // Available from 4.13.
- func BPFObjGetInfoByFD(fd *FD, info unsafe.Pointer, size uintptr) error {
- value, err := fd.Value()
- if err != nil {
- return err
- }
- attr := bpfObjGetInfoByFDAttr{
- fd: value,
- infoLen: uint32(size),
- info: NewPointer(info),
- }
- _, err = BPF(BPF_OBJ_GET_INFO_BY_FD, unsafe.Pointer(&attr), unsafe.Sizeof(attr))
- if err != nil {
- return fmt.Errorf("fd %v: %w", fd, err)
- }
- return nil
- }
|