...
1 package link
2
3 import (
4 "fmt"
5
6 "github.com/cilium/ebpf"
7 "github.com/cilium/ebpf/btf"
8 "github.com/cilium/ebpf/internal/sys"
9 )
10
11 type tracing struct {
12 RawLink
13 }
14
15 func (f *tracing) Update(new *ebpf.Program) error {
16 return fmt.Errorf("tracing update: %w", ErrNotSupported)
17 }
18
19
20
21
22
23
24
25
26
27
28 func AttachFreplace(targetProg *ebpf.Program, name string, prog *ebpf.Program) (Link, error) {
29 if (name == "") != (targetProg == nil) {
30 return nil, fmt.Errorf("must provide both or neither of name and targetProg: %w", errInvalidInput)
31 }
32 if prog == nil {
33 return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput)
34 }
35 if prog.Type() != ebpf.Extension {
36 return nil, fmt.Errorf("eBPF program type %s is not an Extension: %w", prog.Type(), errInvalidInput)
37 }
38
39 var (
40 target int
41 typeID btf.TypeID
42 )
43 if targetProg != nil {
44 btfHandle, err := targetProg.Handle()
45 if err != nil {
46 return nil, err
47 }
48 defer btfHandle.Close()
49
50 spec, err := btfHandle.Spec(nil)
51 if err != nil {
52 return nil, err
53 }
54
55 var function *btf.Func
56 if err := spec.TypeByName(name, &function); err != nil {
57 return nil, err
58 }
59
60 target = targetProg.FD()
61 typeID, err = spec.TypeID(function)
62 if err != nil {
63 return nil, err
64 }
65 }
66
67 link, err := AttachRawLink(RawLinkOptions{
68 Target: target,
69 Program: prog,
70 Attach: ebpf.AttachNone,
71 BTF: typeID,
72 })
73 if err != nil {
74 return nil, err
75 }
76
77 return &tracing{*link}, nil
78 }
79
80 type TracingOptions struct {
81
82
83
84 Program *ebpf.Program
85 }
86
87 type LSMOptions struct {
88
89
90 Program *ebpf.Program
91 }
92
93
94 func attachBTFID(program *ebpf.Program) (Link, error) {
95 if program.FD() < 0 {
96 return nil, fmt.Errorf("invalid program %w", sys.ErrClosedFd)
97 }
98
99 fd, err := sys.RawTracepointOpen(&sys.RawTracepointOpenAttr{
100 ProgFd: uint32(program.FD()),
101 })
102 if err != nil {
103 return nil, err
104 }
105
106 raw := RawLink{fd: fd}
107 info, err := raw.Info()
108 if err != nil {
109 raw.Close()
110 return nil, err
111 }
112
113 if info.Type == RawTracepointType {
114
115
116 return &rawTracepoint{raw}, nil
117 }
118
119 return &tracing{RawLink: RawLink{fd: fd}}, nil
120 }
121
122
123
124
125 func AttachTracing(opts TracingOptions) (Link, error) {
126 if t := opts.Program.Type(); t != ebpf.Tracing {
127 return nil, fmt.Errorf("invalid program type %s, expected Tracing", t)
128 }
129
130 return attachBTFID(opts.Program)
131 }
132
133
134
135 func AttachLSM(opts LSMOptions) (Link, error) {
136 if t := opts.Program.Type(); t != ebpf.LSM {
137 return nil, fmt.Errorf("invalid program type %s, expected LSM", t)
138 }
139
140 return attachBTFID(opts.Program)
141 }
142
View as plain text