Codebase list golang-github-cilium-ebpf / 6a3c314
internal: export BPFProgLoad syscall wrapper Signed-off-by: Robin Gögge <r.goegge@gmail.com> Robin Gögge authored 2 years ago Timo Beckers committed 2 years ago
3 changed file(s) with 72 addition(s) and 71 deletion(s). Raw diff Collapse all Expand all
00 package internal
11
22 import (
3 "errors"
34 "fmt"
45 "path/filepath"
56 "runtime"
6768 return r1, err
6869 }
6970
71 type BPFProgLoadAttr struct {
72 ProgType uint32
73 InsCount uint32
74 Instructions Pointer
75 License Pointer
76 LogLevel uint32
77 LogSize uint32
78 LogBuf Pointer
79 KernelVersion uint32 // since 4.1 2541517c32be
80 ProgFlags uint32 // since 4.11 e07b98d9bffe
81 ProgName BPFObjName // since 4.15 067cae47771c
82 ProgIfIndex uint32 // since 4.15 1f6f4cb7ba21
83 ExpectedAttachType uint32 // since 4.17 5e43f899b03a
84 ProgBTFFd uint32
85 FuncInfoRecSize uint32
86 FuncInfo Pointer
87 FuncInfoCnt uint32
88 LineInfoRecSize uint32
89 LineInfo Pointer
90 LineInfoCnt uint32
91 AttachBTFID uint32
92 AttachProgFd uint32
93 }
94
95 // BPFProgLoad wraps BPF_PROG_LOAD.
96 func BPFProgLoad(attr *BPFProgLoadAttr) (*FD, error) {
97 for {
98 fd, err := BPF(BPF_PROG_LOAD, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
99 // As of ~4.20 the verifier can be interrupted by a signal,
100 // and returns EAGAIN in that case.
101 if errors.Is(err, unix.EAGAIN) {
102 continue
103 }
104
105 if err != nil {
106 return nil, err
107 }
108
109 return NewFD(uint32(fd)), nil
110 }
111 }
112
70113 type BPFProgAttachAttr struct {
71114 TargetFd uint32
72115 AttachBpfFd uint32
170170 kv = v.Kernel()
171171 }
172172
173 attr := &bpfProgLoadAttr{
174 progType: spec.Type,
175 progFlags: spec.Flags,
176 expectedAttachType: spec.AttachType,
177 license: internal.NewStringPointer(spec.License),
178 kernelVersion: kv,
173 attr := &internal.BPFProgLoadAttr{
174 ProgType: uint32(spec.Type),
175 ProgFlags: spec.Flags,
176 ExpectedAttachType: uint32(spec.AttachType),
177 License: internal.NewStringPointer(spec.License),
178 KernelVersion: kv,
179179 }
180180
181181 if haveObjName() == nil {
182 attr.progName = internal.NewBPFObjName(spec.Name)
182 attr.ProgName = internal.NewBPFObjName(spec.Name)
183183 }
184184
185185 var err error
206206 }
207207
208208 if handle != nil {
209 attr.progBTFFd = uint32(handle.FD())
209 attr.ProgBTFFd = uint32(handle.FD())
210210
211211 recSize, bytes, err := btf.ProgramLineInfos(spec.BTF)
212212 if err != nil {
213213 return nil, fmt.Errorf("get BTF line infos: %w", err)
214214 }
215 attr.lineInfoRecSize = recSize
216 attr.lineInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
217 attr.lineInfo = internal.NewSlicePointer(bytes)
215 attr.LineInfoRecSize = recSize
216 attr.LineInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
217 attr.LineInfo = internal.NewSlicePointer(bytes)
218218
219219 recSize, bytes, err = btf.ProgramFuncInfos(spec.BTF)
220220 if err != nil {
221221 return nil, fmt.Errorf("get BTF function infos: %w", err)
222222 }
223 attr.funcInfoRecSize = recSize
224 attr.funcInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
225 attr.funcInfo = internal.NewSlicePointer(bytes)
223 attr.FuncInfoRecSize = recSize
224 attr.FuncInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
225 attr.FuncInfo = internal.NewSlicePointer(bytes)
226226 }
227227 }
228228
242242 }
243243
244244 bytecode := buf.Bytes()
245 attr.instructions = internal.NewSlicePointer(bytecode)
246 attr.insCount = uint32(len(bytecode) / asm.InstructionSize)
245 attr.Instructions = internal.NewSlicePointer(bytecode)
246 attr.InsCount = uint32(len(bytecode) / asm.InstructionSize)
247247
248248 if spec.AttachTo != "" {
249249 if spec.AttachTarget != nil {
272272 return nil, err
273273 }
274274 if target != nil {
275 attr.attachBTFID = target.ID()
275 attr.AttachBTFID = uint32(target.ID())
276276 }
277277 if spec.AttachTarget != nil {
278 attr.attachProgFd = uint32(spec.AttachTarget.FD())
278 attr.AttachProgFd = uint32(spec.AttachTarget.FD())
279279 }
280280 }
281281
287287 var logBuf []byte
288288 if opts.LogLevel > 0 {
289289 logBuf = make([]byte, logSize)
290 attr.logLevel = opts.LogLevel
291 attr.logSize = uint32(len(logBuf))
292 attr.logBuf = internal.NewSlicePointer(logBuf)
293 }
294
295 fd, err := bpfProgLoad(attr)
290 attr.LogLevel = opts.LogLevel
291 attr.LogSize = uint32(len(logBuf))
292 attr.LogBuf = internal.NewSlicePointer(logBuf)
293 }
294
295 fd, err := internal.BPFProgLoad(attr)
296296 if err == nil {
297297 return &Program{internal.CString(logBuf), fd, spec.Name, "", spec.Type}, nil
298298 }
301301 if opts.LogLevel == 0 && opts.LogSize >= 0 {
302302 // Re-run with the verifier enabled to get better error messages.
303303 logBuf = make([]byte, logSize)
304 attr.logLevel = 1
305 attr.logSize = uint32(len(logBuf))
306 attr.logBuf = internal.NewSlicePointer(logBuf)
307
308 _, logErr = bpfProgLoad(attr)
304 attr.LogLevel = 1
305 attr.LogSize = uint32(len(logBuf))
306 attr.LogBuf = internal.NewSlicePointer(logBuf)
307
308 _, logErr = internal.BPFProgLoad(attr)
309309 }
310310
311311 if errors.Is(logErr, unix.EPERM) && logBuf[0] == 0 {
66 "unsafe"
77
88 "github.com/cilium/ebpf/internal"
9 "github.com/cilium/ebpf/internal/btf"
109 "github.com/cilium/ebpf/internal/unix"
1110 )
1211
7069 btf_id uint32 // since 4.18 78958fca7ead
7170 btf_key_type_id uint32 // since 4.18 9b2cf328b2ec
7271 btf_value_type_id uint32
73 }
74
75 type bpfProgLoadAttr struct {
76 progType ProgramType
77 insCount uint32
78 instructions internal.Pointer
79 license internal.Pointer
80 logLevel uint32
81 logSize uint32
82 logBuf internal.Pointer
83 kernelVersion uint32 // since 4.1 2541517c32be
84 progFlags uint32 // since 4.11 e07b98d9bffe
85 progName internal.BPFObjName // since 4.15 067cae47771c
86 progIfIndex uint32 // since 4.15 1f6f4cb7ba21
87 expectedAttachType AttachType // since 4.17 5e43f899b03a
88 progBTFFd uint32
89 funcInfoRecSize uint32
90 funcInfo internal.Pointer
91 funcInfoCnt uint32
92 lineInfoRecSize uint32
93 lineInfo internal.Pointer
94 lineInfoCnt uint32
95 attachBTFID btf.TypeID
96 attachProgFd uint32
9772 }
9873
9974 type bpfProgInfo struct {
154129 openFlags uint32
155130 }
156131
157 func bpfProgLoad(attr *bpfProgLoadAttr) (*internal.FD, error) {
158 for {
159 fd, err := internal.BPF(internal.BPF_PROG_LOAD, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
160 // As of ~4.20 the verifier can be interrupted by a signal,
161 // and returns EAGAIN in that case.
162 if errors.Is(err, unix.EAGAIN) {
163 continue
164 }
165
166 if err != nil {
167 return nil, err
168 }
169
170 return internal.NewFD(uint32(fd)), nil
171 }
172 }
173
174132 func bpfProgTestRun(attr *bpfProgTestRunAttr) error {
175133 _, err := internal.BPF(internal.BPF_PROG_TEST_RUN, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
176134 return err