iter.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package link
  2. import (
  3. "fmt"
  4. "io"
  5. "github.com/cilium/ebpf"
  6. )
  7. type IterOptions struct {
  8. // Program must be of type Tracing with attach type
  9. // AttachTraceIter. The kind of iterator to attach to is
  10. // determined at load time via the AttachTo field.
  11. //
  12. // AttachTo requires the kernel to include BTF of itself,
  13. // and it to be compiled with a recent pahole (>= 1.16).
  14. Program *ebpf.Program
  15. }
  16. // AttachIter attaches a BPF seq_file iterator.
  17. func AttachIter(opts IterOptions) (*Iter, error) {
  18. link, err := AttachRawLink(RawLinkOptions{
  19. Program: opts.Program,
  20. Attach: ebpf.AttachTraceIter,
  21. })
  22. if err != nil {
  23. return nil, fmt.Errorf("can't link iterator: %w", err)
  24. }
  25. return &Iter{link}, err
  26. }
  27. // LoadPinnedIter loads a pinned iterator from a bpffs.
  28. func LoadPinnedIter(fileName string) (*Iter, error) {
  29. link, err := LoadPinnedRawLink(fileName)
  30. if err != nil {
  31. return nil, err
  32. }
  33. return &Iter{link}, err
  34. }
  35. // Iter represents an attached bpf_iter.
  36. type Iter struct {
  37. link *RawLink
  38. }
  39. var _ Link = (*Iter)(nil)
  40. func (it *Iter) isLink() {}
  41. // FD returns the underlying file descriptor.
  42. func (it *Iter) FD() int {
  43. return it.link.FD()
  44. }
  45. // Close implements Link.
  46. func (it *Iter) Close() error {
  47. return it.link.Close()
  48. }
  49. // Pin implements Link.
  50. func (it *Iter) Pin(fileName string) error {
  51. return it.link.Pin(fileName)
  52. }
  53. // Update implements Link.
  54. func (it *Iter) Update(new *ebpf.Program) error {
  55. return it.link.Update(new)
  56. }
  57. // Open creates a new instance of the iterator.
  58. //
  59. // Reading from the returned reader triggers the BPF program.
  60. func (it *Iter) Open() (io.ReadCloser, error) {
  61. linkFd, err := it.link.fd.Value()
  62. if err != nil {
  63. return nil, err
  64. }
  65. attr := &bpfIterCreateAttr{
  66. linkFd: linkFd,
  67. }
  68. fd, err := bpfIterCreate(attr)
  69. if err != nil {
  70. return nil, fmt.Errorf("can't create iterator: %w", err)
  71. }
  72. return fd.File("bpf_iter"), nil
  73. }