1package netlink
2
3import (
4	"unsafe"
5
6	"golang.org/x/sys/unix"
7)
8
9type BpfProgType uint32
10
11const (
12	BPF_PROG_TYPE_UNSPEC BpfProgType = iota
13	BPF_PROG_TYPE_SOCKET_FILTER
14	BPF_PROG_TYPE_KPROBE
15	BPF_PROG_TYPE_SCHED_CLS
16	BPF_PROG_TYPE_SCHED_ACT
17	BPF_PROG_TYPE_TRACEPOINT
18	BPF_PROG_TYPE_XDP
19)
20
21type BPFAttr struct {
22	ProgType    uint32
23	InsnCnt     uint32
24	Insns       uintptr
25	License     uintptr
26	LogLevel    uint32
27	LogSize     uint32
28	LogBuf      uintptr
29	KernVersion uint32
30}
31
32// loadSimpleBpf loads a trivial bpf program for testing purposes.
33func loadSimpleBpf(progType BpfProgType, ret uint32) (int, error) {
34	insns := []uint64{
35		0x00000000000000b7 | (uint64(ret) << 32),
36		0x0000000000000095,
37	}
38	license := []byte{'A', 'S', 'L', '2', '\x00'}
39	attr := BPFAttr{
40		ProgType: uint32(progType),
41		InsnCnt:  uint32(len(insns)),
42		Insns:    uintptr(unsafe.Pointer(&insns[0])),
43		License:  uintptr(unsafe.Pointer(&license[0])),
44	}
45	fd, _, errno := unix.Syscall(unix.SYS_BPF,
46		5, /* bpf cmd */
47		uintptr(unsafe.Pointer(&attr)),
48		unsafe.Sizeof(attr))
49	if errno != 0 {
50		return 0, errno
51	}
52	return int(fd), nil
53}
54