github.com/cilium/ebpf@v0.10.0/link/query.go (about) 1 package link 2 3 import ( 4 "fmt" 5 "os" 6 "unsafe" 7 8 "github.com/cilium/ebpf" 9 "github.com/cilium/ebpf/internal/sys" 10 ) 11 12 // QueryOptions defines additional parameters when querying for programs. 13 type QueryOptions struct { 14 // Path can be a path to a cgroup, netns or LIRC2 device 15 Path string 16 // Attach specifies the AttachType of the programs queried for 17 Attach ebpf.AttachType 18 // QueryFlags are flags for BPF_PROG_QUERY, e.g. BPF_F_QUERY_EFFECTIVE 19 QueryFlags uint32 20 } 21 22 // QueryPrograms retrieves ProgramIDs associated with the AttachType. 23 // 24 // It only returns IDs of programs that were attached using PROG_ATTACH and not bpf_link. 25 // Returns (nil, nil) if there are no programs attached to the queried kernel resource. 26 // Calling QueryPrograms on a kernel missing PROG_QUERY will result in ErrNotSupported. 27 func QueryPrograms(opts QueryOptions) ([]ebpf.ProgramID, error) { 28 if haveProgQuery() != nil { 29 return nil, fmt.Errorf("can't query program IDs: %w", ErrNotSupported) 30 } 31 32 f, err := os.Open(opts.Path) 33 if err != nil { 34 return nil, fmt.Errorf("can't open file: %s", err) 35 } 36 defer f.Close() 37 38 // query the number of programs to allocate correct slice size 39 attr := sys.ProgQueryAttr{ 40 TargetFd: uint32(f.Fd()), 41 AttachType: sys.AttachType(opts.Attach), 42 QueryFlags: opts.QueryFlags, 43 } 44 if err := sys.ProgQuery(&attr); err != nil { 45 return nil, fmt.Errorf("can't query program count: %w", err) 46 } 47 48 // return nil if no progs are attached 49 if attr.ProgCount == 0 { 50 return nil, nil 51 } 52 53 // we have at least one prog, so we query again 54 progIds := make([]ebpf.ProgramID, attr.ProgCount) 55 attr.ProgIds = sys.NewPointer(unsafe.Pointer(&progIds[0])) 56 attr.ProgCount = uint32(len(progIds)) 57 if err := sys.ProgQuery(&attr); err != nil { 58 return nil, fmt.Errorf("can't query program IDs: %w", err) 59 } 60 61 return progIds, nil 62 63 }