...
1 package link
2
3 import (
4 "fmt"
5 "io"
6 "unsafe"
7
8 "github.com/cilium/ebpf"
9 "github.com/cilium/ebpf/internal/sys"
10 )
11
12 type IterOptions struct {
13
14
15
16
17
18
19 Program *ebpf.Program
20
21
22
23 Map *ebpf.Map
24 }
25
26
27 func AttachIter(opts IterOptions) (*Iter, error) {
28 if err := haveBPFLink(); err != nil {
29 return nil, err
30 }
31
32 progFd := opts.Program.FD()
33 if progFd < 0 {
34 return nil, fmt.Errorf("invalid program: %s", sys.ErrClosedFd)
35 }
36
37 var info bpfIterLinkInfoMap
38 if opts.Map != nil {
39 mapFd := opts.Map.FD()
40 if mapFd < 0 {
41 return nil, fmt.Errorf("invalid map: %w", sys.ErrClosedFd)
42 }
43 info.map_fd = uint32(mapFd)
44 }
45
46 attr := sys.LinkCreateIterAttr{
47 ProgFd: uint32(progFd),
48 AttachType: sys.AttachType(ebpf.AttachTraceIter),
49 IterInfo: sys.NewPointer(unsafe.Pointer(&info)),
50 IterInfoLen: uint32(unsafe.Sizeof(info)),
51 }
52
53 fd, err := sys.LinkCreateIter(&attr)
54 if err != nil {
55 return nil, fmt.Errorf("can't link iterator: %w", err)
56 }
57
58 return &Iter{RawLink{fd, ""}}, err
59 }
60
61
62 type Iter struct {
63 RawLink
64 }
65
66
67
68
69 func (it *Iter) Open() (io.ReadCloser, error) {
70 attr := &sys.IterCreateAttr{
71 LinkFd: it.fd.Uint(),
72 }
73
74 fd, err := sys.IterCreate(attr)
75 if err != nil {
76 return nil, fmt.Errorf("can't create iterator: %w", err)
77 }
78
79 return fd.File("bpf_iter"), nil
80 }
81
82
83 type bpfIterLinkInfoMap struct {
84 map_fd uint32
85 }
86
View as plain text