github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/link/program.go (about) 1 package link 2 3 import ( 4 "fmt" 5 "runtime" 6 7 "github.com/cilium/ebpf" 8 "github.com/cilium/ebpf/internal/sys" 9 ) 10 11 type RawAttachProgramOptions struct { 12 // Target to query. This is usually a file descriptor but may refer to 13 // something else based on the attach type. 14 Target int 15 // Program to attach. 16 Program *ebpf.Program 17 // Attach must match the attach type of Program. 18 Attach ebpf.AttachType 19 // Attach relative to an anchor. Optional. 20 Anchor Anchor 21 // Flags control the attach behaviour. Specify an Anchor instead of 22 // F_LINK, F_ID, F_BEFORE, F_AFTER and F_REPLACE. Optional. 23 Flags uint32 24 // Only attach if the internal revision matches the given value. 25 ExpectedRevision uint64 26 } 27 28 // RawAttachProgram is a low level wrapper around BPF_PROG_ATTACH. 29 // 30 // You should use one of the higher level abstractions available in this 31 // package if possible. 32 func RawAttachProgram(opts RawAttachProgramOptions) error { 33 if opts.Flags&anchorFlags != 0 { 34 return fmt.Errorf("disallowed flags: use Anchor to specify attach target") 35 } 36 37 attr := sys.ProgAttachAttr{ 38 TargetFdOrIfindex: uint32(opts.Target), 39 AttachBpfFd: uint32(opts.Program.FD()), 40 AttachType: uint32(opts.Attach), 41 AttachFlags: uint32(opts.Flags), 42 ExpectedRevision: opts.ExpectedRevision, 43 } 44 45 if opts.Anchor != nil { 46 fdOrID, flags, err := opts.Anchor.anchor() 47 if err != nil { 48 return fmt.Errorf("attach program: %w", err) 49 } 50 51 if flags == sys.BPF_F_REPLACE { 52 // Ensure that replacing a program works on old kernels. 53 attr.ReplaceBpfFd = fdOrID 54 } else { 55 attr.RelativeFdOrId = fdOrID 56 attr.AttachFlags |= flags 57 } 58 } 59 60 if err := sys.ProgAttach(&attr); err != nil { 61 if haveFeatErr := haveProgAttach(); haveFeatErr != nil { 62 return haveFeatErr 63 } 64 return fmt.Errorf("attach program: %w", err) 65 } 66 runtime.KeepAlive(opts.Program) 67 68 return nil 69 } 70 71 type RawDetachProgramOptions RawAttachProgramOptions 72 73 // RawDetachProgram is a low level wrapper around BPF_PROG_DETACH. 74 // 75 // You should use one of the higher level abstractions available in this 76 // package if possible. 77 func RawDetachProgram(opts RawDetachProgramOptions) error { 78 if opts.Flags&anchorFlags != 0 { 79 return fmt.Errorf("disallowed flags: use Anchor to specify attach target") 80 } 81 82 attr := sys.ProgDetachAttr{ 83 TargetFdOrIfindex: uint32(opts.Target), 84 AttachBpfFd: uint32(opts.Program.FD()), 85 AttachType: uint32(opts.Attach), 86 ExpectedRevision: opts.ExpectedRevision, 87 } 88 89 if opts.Anchor != nil { 90 fdOrID, flags, err := opts.Anchor.anchor() 91 if err != nil { 92 return fmt.Errorf("detach program: %w", err) 93 } 94 95 attr.RelativeFdOrId = fdOrID 96 attr.AttachFlags |= flags 97 } 98 99 if err := sys.ProgDetach(&attr); err != nil { 100 if haveFeatErr := haveProgAttach(); haveFeatErr != nil { 101 return haveFeatErr 102 } 103 return fmt.Errorf("can't detach program: %w", err) 104 } 105 106 return nil 107 }