forked from cloudflare/cbpfc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ebpf_example_test.go
68 lines (56 loc) · 1.62 KB
/
ebpf_example_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package cbpfc
import (
"github.com/cilium/ebpf/asm"
"github.com/pkg/errors"
"golang.org/x/net/bpf"
)
// ExampleToEBPF demonstrates how to use ToEBPF() to embed a cBPF filter
// in an eBPF assembly program.
func ExampleToEBPF() {
// simple cBPF filter that matches all packets
filter := []bpf.Instruction{
bpf.RetConstant{Val: 1},
}
prog, err := buildEBPF(filter)
if err != nil {
panic(err)
}
// Prog can be loaded directly using cilium/ebpf,
// or converted to a '[]struct bpf_insn' for libbpf
_ = prog
}
// buildEBPF compiles a cBPF filter to eBPF, and embeds it an eBPF program.
// The XDP program XDP_DROP's incoming packets that match the filter.
// Returns the eBPF program instructions
func buildEBPF(filter []bpf.Instruction) (asm.Instructions, error) {
ebpfFilter, err := ToEBPF(filter, EBPFOpts{
// Pass packet start and end pointers in these registers
PacketStart: asm.R2,
PacketEnd: asm.R3,
// Result of filter
Result: asm.R4,
ResultLabel: "result",
// Registers used by generated code
Working: [4]asm.Register{asm.R4, asm.R5, asm.R6, asm.R7},
LabelPrefix: "filter",
})
if err != nil {
return nil, errors.Wrap(err, "converting filter to eBPF")
}
prog := asm.Instructions{
// R1 holds XDP context
// Packet start
asm.LoadMem(asm.R2, asm.R1, 0, asm.Word),
// Packet end
asm.LoadMem(asm.R3, asm.R1, 4, asm.Word),
// Fall through to filter
}
prog = append(prog, ebpfFilter...)
prog = append(prog,
asm.Mov.Imm(asm.R0, 2).Sym("result"), // XDP_PASS
asm.JEq.Imm(asm.R4, 0, "return"),
asm.Mov.Imm(asm.R0, 1), // XDP_DROP
asm.Return().Sym("return"),
)
return prog, nil
}