| package link |
| |
| import ( |
| "fmt" |
| "io" |
| "unsafe" |
| |
| "github.com/cilium/ebpf" |
| "github.com/cilium/ebpf/internal/sys" |
| ) |
| |
| type IterOptions struct { |
| // Program must be of type Tracing with attach type |
| // AttachTraceIter. The kind of iterator to attach to is |
| // determined at load time via the AttachTo field. |
| // |
| // AttachTo requires the kernel to include BTF of itself, |
| // and it to be compiled with a recent pahole (>= 1.16). |
| Program *ebpf.Program |
| |
| // Map specifies the target map for bpf_map_elem and sockmap iterators. |
| // It may be nil. |
| Map *ebpf.Map |
| } |
| |
| // AttachIter attaches a BPF seq_file iterator. |
| func AttachIter(opts IterOptions) (*Iter, error) { |
| if err := haveBPFLink(); err != nil { |
| return nil, err |
| } |
| |
| progFd := opts.Program.FD() |
| if progFd < 0 { |
| return nil, fmt.Errorf("invalid program: %s", sys.ErrClosedFd) |
| } |
| |
| var info bpfIterLinkInfoMap |
| if opts.Map != nil { |
| mapFd := opts.Map.FD() |
| if mapFd < 0 { |
| return nil, fmt.Errorf("invalid map: %w", sys.ErrClosedFd) |
| } |
| info.map_fd = uint32(mapFd) |
| } |
| |
| attr := sys.LinkCreateIterAttr{ |
| ProgFd: uint32(progFd), |
| AttachType: sys.AttachType(ebpf.AttachTraceIter), |
| IterInfo: sys.NewPointer(unsafe.Pointer(&info)), |
| IterInfoLen: uint32(unsafe.Sizeof(info)), |
| } |
| |
| fd, err := sys.LinkCreateIter(&attr) |
| if err != nil { |
| return nil, fmt.Errorf("can't link iterator: %w", err) |
| } |
| |
| return &Iter{RawLink{fd, ""}}, err |
| } |
| |
| // Iter represents an attached bpf_iter. |
| type Iter struct { |
| RawLink |
| } |
| |
| // Open creates a new instance of the iterator. |
| // |
| // Reading from the returned reader triggers the BPF program. |
| func (it *Iter) Open() (io.ReadCloser, error) { |
| attr := &sys.IterCreateAttr{ |
| LinkFd: it.fd.Uint(), |
| } |
| |
| fd, err := sys.IterCreate(attr) |
| if err != nil { |
| return nil, fmt.Errorf("can't create iterator: %w", err) |
| } |
| |
| return fd.File("bpf_iter"), nil |
| } |
| |
| // union bpf_iter_link_info.map |
| type bpfIterLinkInfoMap struct { |
| map_fd uint32 |
| } |