Skip to content

Commit

Permalink
link: add Info() method to all link types
Browse files Browse the repository at this point in the history
Signed-off-by: Robin Gögge <[email protected]>
  • Loading branch information
rgo3 committed May 23, 2024
1 parent 79b6759 commit f508e58
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 108 deletions.
19 changes: 19 additions & 0 deletions link/cgroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"

"github.com/cilium/ebpf"
"github.com/cilium/ebpf/internal/sys"
)

type cgroupAttachFlags uint32
Expand Down Expand Up @@ -187,3 +188,21 @@ func newLinkCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program)

return &linkCgroup{*link}, err
}

func (cg *linkCgroup) Info() (*Info, error) {
var info sys.CgroupLinkInfo
if err := sys.ObjInfo(cg.fd, &info); err != nil {
return nil, fmt.Errorf("cgroup link info: %s", err)
}
extra := &CgroupInfo{
CgroupId: info.CgroupId,
AttachType: info.AttachType,
}

return &Info{
info.Type,
info.Id,
ebpf.ProgramID(info.ProgId),
extra,
}, nil
}
19 changes: 19 additions & 0 deletions link/kprobe_multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,25 @@ func (kml *kprobeMultiLink) Unpin() error {
return fmt.Errorf("unpin kprobe_multi: %w", ErrNotSupported)
}

func (kml *kprobeMultiLink) Info() (*Info, error) {
var info sys.KprobeMultiLinkInfo
if err := sys.ObjInfo(kml.fd, &info); err != nil {
return nil, fmt.Errorf("kprobe multi link info: %s", err)
}
extra := &KprobeMultiInfo{
count: info.Count,
flags: info.Flags,
missed: info.Missed,
}

return &Info{
info.Type,
info.Id,
ebpf.ProgramID(info.ProgId),
extra,
}, nil
}

var haveBPFLinkKprobeMulti = internal.NewFeatureTest("bpf_link_kprobe_multi", "5.18", func() error {
prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
Name: "probe_kpm_link",
Expand Down
113 changes: 6 additions & 107 deletions link/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ func wrapRawLink(raw *RawLink) (_ Link, err error) {
return &netfilterLink{*raw}, nil
case NetkitType:
return &netkitLink{*raw}, nil
case XDPType:
return &xdpLink{*raw}, nil
default:
return raw, nil
}
Expand Down Expand Up @@ -438,124 +440,21 @@ func (l *RawLink) UpdateArgs(opts RawLinkUpdateOptions) error {
}

// Info returns metadata about the link.
//
// Linktype specific metadata is not included and can be retrieved
// via the linktype specific Info() method.
func (l *RawLink) Info() (*Info, error) {
var info sys.LinkInfo

if err := sys.ObjInfo(l.fd, &info); err != nil {
return nil, fmt.Errorf("link info: %s", err)
}

var extra interface{}
switch info.Type {
case CgroupType:
var cgroupInfo sys.CgroupLinkInfo
if err := sys.ObjInfo(l.fd, &cgroupInfo); err != nil {
return nil, fmt.Errorf("cgroup link info: %s", err)
}
extra = &CgroupInfo{
CgroupId: cgroupInfo.CgroupId,
AttachType: cgroupInfo.AttachType,
}
case NetNsType:
var netnsInfo sys.NetNsLinkInfo
if err := sys.ObjInfo(l.fd, &netnsInfo); err != nil {
return nil, fmt.Errorf("netns link info: %s", err)
}
extra = &NetNsInfo{
NetnsIno: netnsInfo.NetnsIno,
AttachType: netnsInfo.AttachType,
}
case TracingType:
var tracingInfo sys.TracingLinkInfo
if err := sys.ObjInfo(l.fd, &tracingInfo); err != nil {
return nil, fmt.Errorf("tracing link info: %s", err)
}
extra = &TracingInfo{
TargetObjId: tracingInfo.TargetObjId,
TargetBtfId: tracingInfo.TargetBtfId,
AttachType: tracingInfo.AttachType,
}
case XDPType:
var xdpInfo sys.XDPLinkInfo
if err := sys.ObjInfo(l.fd, &xdpInfo); err != nil {
return nil, fmt.Errorf("xdp link info: %s", err)
}
extra = &XDPInfo{
Ifindex: xdpInfo.Ifindex,
}
case RawTracepointType, IterType, UprobeMultiType:
// Extra metadata not supported.
case TCXType:
var tcxInfo sys.TcxLinkInfo
if err := sys.ObjInfo(l.fd, &tcxInfo); err != nil {
return nil, fmt.Errorf("tcx link info: %s", err)
}
extra = &TCXInfo{
Ifindex: tcxInfo.Ifindex,
AttachType: tcxInfo.AttachType,
}
case NetfilterType:
var netfilterInfo sys.NetfilterLinkInfo
if err := sys.ObjInfo(l.fd, &netfilterInfo); err != nil {
return nil, fmt.Errorf("netfilter link info: %s", err)
}
extra = &NetfilterInfo{
Pf: netfilterInfo.Pf,
Hooknum: netfilterInfo.Hooknum,
Priority: netfilterInfo.Priority,
Flags: netfilterInfo.Flags,
}
case NetkitType:
var netkitInfo sys.NetkitLinkInfo
if err := sys.ObjInfo(l.fd, &netkitInfo); err != nil {
return nil, fmt.Errorf("tcx link info: %s", err)
}
extra = &NetkitInfo{
Ifindex: netkitInfo.Ifindex,
AttachType: netkitInfo.AttachType,
}
case KprobeMultiType:
var kprobeMultiInfo sys.KprobeMultiLinkInfo
if err := sys.ObjInfo(l.fd, &kprobeMultiInfo); err != nil {
return nil, fmt.Errorf("kprobe multi link info: %s", err)
}
extra = &KprobeMultiInfo{
count: kprobeMultiInfo.Count,
flags: kprobeMultiInfo.Flags,
missed: kprobeMultiInfo.Missed,
}
case PerfEventType:
var perfEventInfo sys.PerfEventLinkInfo
if err := sys.ObjInfo(l.fd, &perfEventInfo); err != nil {
return nil, fmt.Errorf("perf event link info: %s", err)
}

var extra2 interface{}
switch perfEventInfo.PerfEventType {
case sys.BPF_PERF_EVENT_KPROBE, sys.BPF_PERF_EVENT_KRETPROBE:
var kprobeInfo sys.KprobeLinkInfo
if err := sys.ObjInfo(l.fd, &kprobeInfo); err != nil {
return nil, fmt.Errorf("kprobe multi link info: %s", err)
}
extra2 = &KprobeInfo{
address: kprobeInfo.Addr,
missed: kprobeInfo.Missed,
}
}

extra = &PerfEventInfo{
Type: perfEventInfo.PerfEventType,
extra: extra2,
}
default:
return nil, fmt.Errorf("unknown link info type: %d", info.Type)
}

return &Info{
info.Type,
info.Id,
ebpf.ProgramID(info.ProgId),
extra,
nil,
}, nil
}

Expand Down
20 changes: 20 additions & 0 deletions link/netfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,24 @@ func (*netfilterLink) Update(new *ebpf.Program) error {
return fmt.Errorf("netfilter update: %w", ErrNotSupported)
}

func (nf *netfilterLink) Info() (*Info, error) {
var info sys.NetfilterLinkInfo
if err := sys.ObjInfo(nf.fd, &info); err != nil {
return nil, fmt.Errorf("netfilter link info: %s", err)
}
extra := &NetfilterInfo{
Pf: info.Pf,
Hooknum: info.Hooknum,
Priority: info.Priority,
Flags: info.Flags,
}

return &Info{
info.Type,
info.Id,
ebpf.ProgramID(info.ProgId),
extra,
}, nil
}

var _ Link = (*netfilterLink)(nil)
18 changes: 18 additions & 0 deletions link/netkit.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,21 @@ type netkitLink struct {
}

var _ Link = (*netkitLink)(nil)

func (netkit *netkitLink) Info() (*Info, error) {
var info sys.NetkitLinkInfo
if err := sys.ObjInfo(netkit.fd, &info); err != nil {
return nil, fmt.Errorf("netkit link info: %s", err)
}
extra := &NetkitInfo{
Ifindex: info.Ifindex,
AttachType: info.AttachType,
}

return &Info{
info.Type,
info.Id,
ebpf.ProgramID(info.ProgId),
extra,
}, nil
}
19 changes: 19 additions & 0 deletions link/netns.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/cilium/ebpf"
"github.com/cilium/ebpf/internal/sys"
)

// NetNsLink is a program attached to a network namespace.
Expand Down Expand Up @@ -34,3 +35,21 @@ func AttachNetNs(ns int, prog *ebpf.Program) (*NetNsLink, error) {

return &NetNsLink{*link}, nil
}

func (ns *NetNsLink) Info() (*Info, error) {
var info sys.NetNsLinkInfo
if err := sys.ObjInfo(ns.fd, &info); err != nil {
return nil, fmt.Errorf("netns link info: %s", err)
}
extra := &NetNsInfo{
NetnsIno: info.NetnsIno,
AttachType: info.AttachType,
}

return &Info{
info.Type,
info.Id,
ebpf.ProgramID(info.ProgId),
extra,
}, nil
}
32 changes: 32 additions & 0 deletions link/perf_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,38 @@ func (pl *perfEventLink) PerfEvent() (*os.File, error) {
return fd.File("perf-event"), nil
}

func (pl *perfEventLink) Info() (*Info, error) {
var info sys.PerfEventLinkInfo
if err := sys.ObjInfo(pl.fd, &info); err != nil {
return nil, fmt.Errorf("perf event link info: %s", err)
}

var extra2 interface{}
switch info.PerfEventType {
case sys.BPF_PERF_EVENT_KPROBE, sys.BPF_PERF_EVENT_KRETPROBE:
var kprobeInfo sys.KprobeLinkInfo
if err := sys.ObjInfo(pl.fd, &kprobeInfo); err != nil {
return nil, fmt.Errorf("kprobe link info: %s", err)
}
extra2 = &KprobeInfo{
address: kprobeInfo.Addr,
missed: kprobeInfo.Missed,
}
}

extra := &PerfEventInfo{
Type: info.PerfEventType,
extra: extra2,
}

return &Info{
info.Type,
info.Id,
ebpf.ProgramID(info.ProgId),
extra,
}, nil
}

// perfEventIoctl implements Link and handles the perf event lifecycle
// via ioctl().
type perfEventIoctl struct {
Expand Down
18 changes: 18 additions & 0 deletions link/tcx.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,21 @@ type tcxLink struct {
}

var _ Link = (*tcxLink)(nil)

func (tcx *tcxLink) Info() (*Info, error) {
var info sys.TcxLinkInfo
if err := sys.ObjInfo(tcx.fd, &info); err != nil {
return nil, fmt.Errorf("tcx link info: %s", err)
}
extra := &TCXInfo{
Ifindex: info.Ifindex,
AttachType: info.AttachType,
}

return &Info{
info.Type,
info.Id,
ebpf.ProgramID(info.ProgId),
extra,
}, nil
}
19 changes: 19 additions & 0 deletions link/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,25 @@ func (f *tracing) Update(new *ebpf.Program) error {
return fmt.Errorf("tracing update: %w", ErrNotSupported)
}

func (f *tracing) Info() (*Info, error) {
var info sys.TracingLinkInfo
if err := sys.ObjInfo(f.fd, &info); err != nil {
return nil, fmt.Errorf("tracing link info: %s", err)
}
extra := &TracingInfo{
TargetObjId: info.TargetObjId,
TargetBtfId: info.TargetBtfId,
AttachType: info.AttachType,
}

return &Info{
info.Type,
info.Id,
ebpf.ProgramID(info.ProgId),
extra,
}, nil
}

// AttachFreplace attaches the given eBPF program to the function it replaces.
//
// The program and name can either be provided at link time, or can be provided
Expand Down
24 changes: 23 additions & 1 deletion link/xdp.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/cilium/ebpf"
"github.com/cilium/ebpf/internal/sys"
)

// XDPAttachFlags represents how XDP program will be attached to interface.
Expand Down Expand Up @@ -50,5 +51,26 @@ func AttachXDP(opts XDPOptions) (Link, error) {
Flags: uint32(opts.Flags),
})

return rawLink, err
return &xdpLink{*rawLink}, err
}

type xdpLink struct {
RawLink
}

func (xdp *xdpLink) Info() (*Info, error) {
var info sys.XDPLinkInfo
if err := sys.ObjInfo(xdp.fd, &info); err != nil {
return nil, fmt.Errorf("xdp link info: %s", err)
}
extra := &XDPInfo{
Ifindex: info.Ifindex,
}

return &Info{
info.Type,
info.Id,
ebpf.ProgramID(info.ProgId),
extra,
}, nil
}

0 comments on commit f508e58

Please sign in to comment.