summaryrefslogtreecommitdiff
path: root/vendor/github.com/cilium/ebpf/link/link.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/cilium/ebpf/link/link.go')
-rw-r--r--vendor/github.com/cilium/ebpf/link/link.go214
1 files changed, 214 insertions, 0 deletions
diff --git a/vendor/github.com/cilium/ebpf/link/link.go b/vendor/github.com/cilium/ebpf/link/link.go
new file mode 100644
index 000000000..48f1a5529
--- /dev/null
+++ b/vendor/github.com/cilium/ebpf/link/link.go
@@ -0,0 +1,214 @@
+package link
+
+import (
+ "fmt"
+ "unsafe"
+
+ "github.com/cilium/ebpf"
+ "github.com/cilium/ebpf/internal"
+)
+
+var ErrNotSupported = internal.ErrNotSupported
+
+// Link represents a Program attached to a BPF hook.
+type Link interface {
+ // Replace the current program with a new program.
+ //
+ // Passing a nil program is an error. May return an error wrapping ErrNotSupported.
+ Update(*ebpf.Program) error
+
+ // Persist a link by pinning it into a bpffs.
+ //
+ // May return an error wrapping ErrNotSupported.
+ Pin(string) error
+
+ // Close frees resources.
+ //
+ // The link will be broken unless it has been pinned. A link
+ // may continue past the lifetime of the process if Close is
+ // not called.
+ Close() error
+
+ // Prevent external users from implementing this interface.
+ isLink()
+}
+
+// ID uniquely identifies a BPF link.
+type ID uint32
+
+// RawLinkOptions control the creation of a raw link.
+type RawLinkOptions struct {
+ // File descriptor to attach to. This differs for each attach type.
+ Target int
+ // Program to attach.
+ Program *ebpf.Program
+ // Attach must match the attach type of Program.
+ Attach ebpf.AttachType
+}
+
+// RawLinkInfo contains metadata on a link.
+type RawLinkInfo struct {
+ Type Type
+ ID ID
+ Program ebpf.ProgramID
+}
+
+// RawLink is the low-level API to bpf_link.
+//
+// You should consider using the higher level interfaces in this
+// package instead.
+type RawLink struct {
+ fd *internal.FD
+}
+
+// AttachRawLink creates a raw link.
+func AttachRawLink(opts RawLinkOptions) (*RawLink, error) {
+ if err := haveBPFLink(); err != nil {
+ return nil, err
+ }
+
+ if opts.Target < 0 {
+ return nil, fmt.Errorf("invalid target: %s", internal.ErrClosedFd)
+ }
+
+ progFd := opts.Program.FD()
+ if progFd < 0 {
+ return nil, fmt.Errorf("invalid program: %s", internal.ErrClosedFd)
+ }
+
+ attr := bpfLinkCreateAttr{
+ targetFd: uint32(opts.Target),
+ progFd: uint32(progFd),
+ attachType: opts.Attach,
+ }
+ fd, err := bpfLinkCreate(&attr)
+ if err != nil {
+ return nil, fmt.Errorf("can't create link: %s", err)
+ }
+
+ return &RawLink{fd}, nil
+}
+
+// LoadPinnedRawLink loads a persisted link from a bpffs.
+func LoadPinnedRawLink(fileName string) (*RawLink, error) {
+ return loadPinnedRawLink(fileName, UnspecifiedType)
+}
+
+func loadPinnedRawLink(fileName string, typ Type) (*RawLink, error) {
+ fd, err := internal.BPFObjGet(fileName)
+ if err != nil {
+ return nil, fmt.Errorf("load pinned link: %s", err)
+ }
+
+ link := &RawLink{fd}
+ if typ == UnspecifiedType {
+ return link, nil
+ }
+
+ info, err := link.Info()
+ if err != nil {
+ link.Close()
+ return nil, fmt.Errorf("get pinned link info: %s", err)
+ }
+
+ if info.Type != typ {
+ link.Close()
+ return nil, fmt.Errorf("link type %v doesn't match %v", info.Type, typ)
+ }
+
+ return link, nil
+}
+
+func (l *RawLink) isLink() {}
+
+// FD returns the raw file descriptor.
+func (l *RawLink) FD() int {
+ fd, err := l.fd.Value()
+ if err != nil {
+ return -1
+ }
+ return int(fd)
+}
+
+// Close breaks the link.
+//
+// Use Pin if you want to make the link persistent.
+func (l *RawLink) Close() error {
+ return l.fd.Close()
+}
+
+// Pin persists a link past the lifetime of the process.
+//
+// Calling Close on a pinned Link will not break the link
+// until the pin is removed.
+func (l *RawLink) Pin(fileName string) error {
+ if err := internal.BPFObjPin(fileName, l.fd); err != nil {
+ return fmt.Errorf("can't pin link: %s", err)
+ }
+ return nil
+}
+
+// Update implements Link.
+func (l *RawLink) Update(new *ebpf.Program) error {
+ return l.UpdateArgs(RawLinkUpdateOptions{
+ New: new,
+ })
+}
+
+// RawLinkUpdateOptions control the behaviour of RawLink.UpdateArgs.
+type RawLinkUpdateOptions struct {
+ New *ebpf.Program
+ Old *ebpf.Program
+ Flags uint32
+}
+
+// UpdateArgs updates a link based on args.
+func (l *RawLink) UpdateArgs(opts RawLinkUpdateOptions) error {
+ newFd := opts.New.FD()
+ if newFd < 0 {
+ return fmt.Errorf("invalid program: %s", internal.ErrClosedFd)
+ }
+
+ var oldFd int
+ if opts.Old != nil {
+ oldFd = opts.Old.FD()
+ if oldFd < 0 {
+ return fmt.Errorf("invalid replacement program: %s", internal.ErrClosedFd)
+ }
+ }
+
+ linkFd, err := l.fd.Value()
+ if err != nil {
+ return fmt.Errorf("can't update link: %s", err)
+ }
+
+ attr := bpfLinkUpdateAttr{
+ linkFd: linkFd,
+ newProgFd: uint32(newFd),
+ oldProgFd: uint32(oldFd),
+ flags: opts.Flags,
+ }
+ return bpfLinkUpdate(&attr)
+}
+
+// struct bpf_link_info
+type bpfLinkInfo struct {
+ typ uint32
+ id uint32
+ prog_id uint32
+}
+
+// Info returns metadata about the link.
+func (l *RawLink) Info() (*RawLinkInfo, error) {
+ var info bpfLinkInfo
+ err := internal.BPFObjGetInfoByFD(l.fd, unsafe.Pointer(&info), unsafe.Sizeof(info))
+ if err != nil {
+ return nil, fmt.Errorf("link info: %s", err)
+ }
+
+ return &RawLinkInfo{
+ Type(info.typ),
+ ID(info.id),
+ ebpf.ProgramID(info.prog_id),
+ }, nil
+}