summaryrefslogtreecommitdiff
path: root/vendor/github.com/cilium/ebpf/link/cgroup.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/cilium/ebpf/link/cgroup.go')
-rw-r--r--vendor/github.com/cilium/ebpf/link/cgroup.go169
1 files changed, 169 insertions, 0 deletions
diff --git a/vendor/github.com/cilium/ebpf/link/cgroup.go b/vendor/github.com/cilium/ebpf/link/cgroup.go
new file mode 100644
index 000000000..16a943930
--- /dev/null
+++ b/vendor/github.com/cilium/ebpf/link/cgroup.go
@@ -0,0 +1,169 @@
+package link
+
+import (
+ "errors"
+ "fmt"
+ "os"
+
+ "github.com/cilium/ebpf"
+)
+
+type cgroupAttachFlags uint32
+
+// cgroup attach flags
+const (
+ flagAllowOverride cgroupAttachFlags = 1 << iota
+ flagAllowMulti
+ flagReplace
+)
+
+type CgroupOptions struct {
+ // Path to a cgroupv2 folder.
+ Path string
+ // One of the AttachCgroup* constants
+ Attach ebpf.AttachType
+ // Program must be of type CGroup*, and the attach type must match Attach.
+ Program *ebpf.Program
+}
+
+// AttachCgroup links a BPF program to a cgroup.
+func AttachCgroup(opts CgroupOptions) (Link, error) {
+ cgroup, err := os.Open(opts.Path)
+ if err != nil {
+ return nil, fmt.Errorf("can't open cgroup: %s", err)
+ }
+
+ clone, err := opts.Program.Clone()
+ if err != nil {
+ cgroup.Close()
+ return nil, err
+ }
+
+ var cg Link
+ cg, err = newLinkCgroup(cgroup, opts.Attach, clone)
+ if errors.Is(err, ErrNotSupported) {
+ cg, err = newProgAttachCgroup(cgroup, opts.Attach, clone, flagAllowMulti)
+ }
+ if errors.Is(err, ErrNotSupported) {
+ cg, err = newProgAttachCgroup(cgroup, opts.Attach, clone, flagAllowOverride)
+ }
+ if err != nil {
+ cgroup.Close()
+ clone.Close()
+ return nil, err
+ }
+
+ return cg, nil
+}
+
+// LoadPinnedCgroup loads a pinned cgroup from a bpffs.
+func LoadPinnedCgroup(fileName string) (Link, error) {
+ link, err := LoadPinnedRawLink(fileName)
+ if err != nil {
+ return nil, err
+ }
+
+ return &linkCgroup{link}, nil
+}
+
+type progAttachCgroup struct {
+ cgroup *os.File
+ current *ebpf.Program
+ attachType ebpf.AttachType
+ flags cgroupAttachFlags
+}
+
+var _ Link = (*progAttachCgroup)(nil)
+
+func (cg *progAttachCgroup) isLink() {}
+
+func newProgAttachCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program, flags cgroupAttachFlags) (*progAttachCgroup, error) {
+ if flags&flagAllowMulti > 0 {
+ if err := haveProgAttachReplace(); err != nil {
+ return nil, fmt.Errorf("can't support multiple programs: %w", err)
+ }
+ }
+
+ err := RawAttachProgram(RawAttachProgramOptions{
+ Target: int(cgroup.Fd()),
+ Program: prog,
+ Flags: uint32(flags),
+ Attach: attach,
+ })
+ if err != nil {
+ return nil, fmt.Errorf("cgroup: %w", err)
+ }
+
+ return &progAttachCgroup{cgroup, prog, attach, flags}, nil
+}
+
+func (cg *progAttachCgroup) Close() error {
+ defer cg.cgroup.Close()
+ defer cg.current.Close()
+
+ err := RawDetachProgram(RawDetachProgramOptions{
+ Target: int(cg.cgroup.Fd()),
+ Program: cg.current,
+ Attach: cg.attachType,
+ })
+ if err != nil {
+ return fmt.Errorf("close cgroup: %s", err)
+ }
+ return nil
+}
+
+func (cg *progAttachCgroup) Update(prog *ebpf.Program) error {
+ new, err := prog.Clone()
+ if err != nil {
+ return err
+ }
+
+ args := RawAttachProgramOptions{
+ Target: int(cg.cgroup.Fd()),
+ Program: prog,
+ Attach: cg.attachType,
+ Flags: uint32(cg.flags),
+ }
+
+ if cg.flags&flagAllowMulti > 0 {
+ // Atomically replacing multiple programs requires at least
+ // 5.5 (commit 7dd68b3279f17921 "bpf: Support replacing cgroup-bpf
+ // program in MULTI mode")
+ args.Flags |= uint32(flagReplace)
+ args.Replace = cg.current
+ }
+
+ if err := RawAttachProgram(args); err != nil {
+ new.Close()
+ return fmt.Errorf("can't update cgroup: %s", err)
+ }
+
+ cg.current.Close()
+ cg.current = new
+ return nil
+}
+
+func (cg *progAttachCgroup) Pin(string) error {
+ return fmt.Errorf("can't pin cgroup: %w", ErrNotSupported)
+}
+
+type linkCgroup struct {
+ *RawLink
+}
+
+var _ Link = (*linkCgroup)(nil)
+
+func (cg *linkCgroup) isLink() {}
+
+func newLinkCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program) (*linkCgroup, error) {
+ link, err := AttachRawLink(RawLinkOptions{
+ Target: int(cgroup.Fd()),
+ Program: prog,
+ Attach: attach,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return &linkCgroup{link}, err
+}