github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/link/iter.go (about) 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 // Program must be of type Tracing with attach type 14 // AttachTraceIter. The kind of iterator to attach to is 15 // determined at load time via the AttachTo field. 16 // 17 // AttachTo requires the kernel to include BTF of itself, 18 // and it to be compiled with a recent pahole (>= 1.16). 19 Program *ebpf.Program 20 21 // Map specifies the target map for bpf_map_elem and sockmap iterators. 22 // It may be nil. 23 Map *ebpf.Map 24 } 25 26 // AttachIter attaches a BPF seq_file iterator. 27 func AttachIter(opts IterOptions) (*Iter, error) { 28 progFd := opts.Program.FD() 29 if progFd < 0 { 30 return nil, fmt.Errorf("invalid program: %s", sys.ErrClosedFd) 31 } 32 33 var info bpfIterLinkInfoMap 34 if opts.Map != nil { 35 mapFd := opts.Map.FD() 36 if mapFd < 0 { 37 return nil, fmt.Errorf("invalid map: %w", sys.ErrClosedFd) 38 } 39 info.map_fd = uint32(mapFd) 40 } 41 42 attr := sys.LinkCreateIterAttr{ 43 ProgFd: uint32(progFd), 44 AttachType: sys.AttachType(ebpf.AttachTraceIter), 45 IterInfo: sys.NewPointer(unsafe.Pointer(&info)), 46 IterInfoLen: uint32(unsafe.Sizeof(info)), 47 } 48 49 fd, err := sys.LinkCreateIter(&attr) 50 if err != nil { 51 if haveFeatErr := haveBPFLink(); haveFeatErr != nil { 52 return nil, haveFeatErr 53 } 54 return nil, fmt.Errorf("can't link iterator: %w", err) 55 } 56 57 return &Iter{RawLink{fd, ""}}, err 58 } 59 60 // Iter represents an attached bpf_iter. 61 type Iter struct { 62 RawLink 63 } 64 65 // Open creates a new instance of the iterator. 66 // 67 // Reading from the returned reader triggers the BPF program. 68 func (it *Iter) Open() (io.ReadCloser, error) { 69 attr := &sys.IterCreateAttr{ 70 LinkFd: it.fd.Uint(), 71 } 72 73 fd, err := sys.IterCreate(attr) 74 if err != nil { 75 return nil, fmt.Errorf("can't create iterator: %w", err) 76 } 77 78 return fd.File("bpf_iter"), nil 79 } 80 81 // union bpf_iter_link_info.map 82 type bpfIterLinkInfoMap struct { 83 map_fd uint32 84 }