ebpf_exporter
64 строки · 1.6 Кб
1package exporter
2
3/*
4#include <stdlib.h>
5#include <bpf/libbpf.h>
6
7extern int attachXDPCallback(const struct bpf_program *prog,
8long cookie,
9struct bpf_link **link);
10*/
11import "C"
12
13import (
14"fmt"
15"net"
16"strings"
17"syscall"
18"unsafe"
19
20"github.com/aquasecurity/libbpfgo"
21"golang.org/x/sys/unix"
22)
23
24var libbpfXDPHandlers []int
25
26func registerXDPHandler() error {
27if libbpfXDPHandlers != nil {
28return nil
29}
30
31name := C.CString("xdp/")
32defer C.free(unsafe.Pointer(name))
33
34opts := C.struct_libbpf_prog_handler_opts{}
35opts.sz = C.sizeof_struct_libbpf_prog_handler_opts
36opts.prog_attach_fn = C.libbpf_prog_attach_fn_t(C.attachXDPCallback)
37
38handler := C.libbpf_register_prog_handler(name, uint32(libbpfgo.BPFProgTypeXdp), uint32(libbpfgo.BPFAttachTypeXDP), &opts)
39if handler < 0 {
40return fmt.Errorf("error registering prog handler: %s", unix.ErrnoName(syscall.Errno(handler)))
41}
42
43libbpfXDPHandlers = append(libbpfXDPHandlers, int(handler))
44
45return nil
46}
47
48func attachXDP(prog *C.struct_bpf_program) ([]*C.struct_bpf_link, error) {
49name := C.GoString(C.bpf_program__name(prog))
50section := C.GoString(C.bpf_program__section_name(prog))
51device := strings.TrimPrefix(section, "xdp/")
52
53iface, err := net.InterfaceByName(device)
54if err != nil {
55return nil, fmt.Errorf("failed to find device %q for program %q: %v", device, name, err)
56}
57
58link, err := C.bpf_program__attach_xdp(prog, C.int(iface.Index))
59if link == nil {
60return nil, fmt.Errorf("failed to attach xdp on device %q for program %s: %v", device, name, err)
61}
62
63return []*C.struct_bpf_link{link}, nil
64}
65