Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

link: add Info() method to all link types #1435

Merged
merged 1 commit into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:
rgo3 marked this conversation as resolved.
Show resolved Hide resolved
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{}
rgo3 marked this conversation as resolved.
Show resolved Hide resolved
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
rgo3 marked this conversation as resolved.
Show resolved Hide resolved
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
}
Loading