mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
b79dec8138
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
88 lines
2.2 KiB
Go
88 lines
2.2 KiB
Go
package link
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/cilium/ebpf"
|
|
"github.com/cilium/ebpf/internal/btf"
|
|
)
|
|
|
|
type FreplaceLink struct {
|
|
RawLink
|
|
}
|
|
|
|
// 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
|
|
// at program load time. If they were provided at load time, they should be nil
|
|
// and empty respectively here, as they will be ignored by the kernel.
|
|
// Examples:
|
|
//
|
|
// AttachFreplace(dispatcher, "function", replacement)
|
|
// AttachFreplace(nil, "", replacement)
|
|
func AttachFreplace(targetProg *ebpf.Program, name string, prog *ebpf.Program) (*FreplaceLink, error) {
|
|
if (name == "") != (targetProg == nil) {
|
|
return nil, fmt.Errorf("must provide both or neither of name and targetProg: %w", errInvalidInput)
|
|
}
|
|
if prog == nil {
|
|
return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput)
|
|
}
|
|
if prog.Type() != ebpf.Extension {
|
|
return nil, fmt.Errorf("eBPF program type %s is not an Extension: %w", prog.Type(), errInvalidInput)
|
|
}
|
|
|
|
var (
|
|
target int
|
|
typeID btf.TypeID
|
|
)
|
|
if targetProg != nil {
|
|
info, err := targetProg.Info()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
btfID, ok := info.BTFID()
|
|
if !ok {
|
|
return nil, fmt.Errorf("could not get BTF ID for program %s: %w", info.Name, errInvalidInput)
|
|
}
|
|
btfHandle, err := btf.NewHandleFromID(btfID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer btfHandle.Close()
|
|
|
|
var function *btf.Func
|
|
if err := btfHandle.Spec().FindType(name, &function); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
target = targetProg.FD()
|
|
typeID = function.ID()
|
|
}
|
|
|
|
link, err := AttachRawLink(RawLinkOptions{
|
|
Target: target,
|
|
Program: prog,
|
|
Attach: ebpf.AttachNone,
|
|
BTF: typeID,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &FreplaceLink{*link}, nil
|
|
}
|
|
|
|
// Update implements the Link interface.
|
|
func (f *FreplaceLink) Update(new *ebpf.Program) error {
|
|
return fmt.Errorf("freplace update: %w", ErrNotSupported)
|
|
}
|
|
|
|
// LoadPinnedFreplace loads a pinned iterator from a bpffs.
|
|
func LoadPinnedFreplace(fileName string, opts *ebpf.LoadPinOptions) (*FreplaceLink, error) {
|
|
link, err := LoadPinnedRawLink(fileName, TracingType, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &FreplaceLink{*link}, err
|
|
}
|