Copyright © (C) 2021, Oskar Mazerath
Authors: Oskar Mazerath (moskar.drummer@gmail.com).
eBPF instructions generation.
The functions in this module don't do what they names imply, they generate eBPF instructions implementing the implied (and documented) semantics.
Instructions generating functions in this module return either a single instruction or a list of instructions ordered by the order of execution. You can always uselists:flatten/1
to make this
difference transperent, as in
Instructions = lists:flatten([ ebpf_kern:stack_printk("Hey ebpf"), ebpf_kern:exit_insn() ]), {ok, XdpGreetProg} = ebpf_user:load(xdp, ebpf_asm:assemble(Instructions)).
Notice that we don't have to worry about whether stack_printk/1
or exit_insn/0
returns a list of instructions or a single instruction
as it is handled by lists:flatten/1
.
This module is not tied to running only in eBPF enabled environments,
you can use ebpf_kern
on any system to create eBPF programs which
can later run on other nodes, e.g. via ebpf_user:load/2
on a
Linux sytem.
alu32_imm/3 |
Dst = (Src band 16#FFFFFFF) Op (Imm band 16#FFFFFFF) |
alu32_reg/3 |
Dst = (Src band 16#FFFFFFF) Op (Dst band 16#FFFFFFF) |
alu64_imm/3 |
Dst = Imm Op Dst |
alu64_reg/3 |
Dst = Src Op Dst |
branch/5 |
if Src Op Dst: goto Bt, else goto Bf |
call_helper/1 |
r0 = Helper(r1,r2,r3,r4,r5) |
emit_call/1 |
r0 = Func(r1,r2,r3,r4,r5) |
exit_insn/0 |
return r0 |
jmp32_imm/4 |
if ((Imm band 16#FFFFFFF) Op (Dst band 16#FFFFFFF)) skip Off instructions |
jmp32_reg/4 |
if ((Src band 16#FFFFFFF) Op (Dst band 16#FFFFFFF)) skip Off instructions |
jmp64_imm/4 |
if (Imm Op Dst) skip Off instructions |
jmp64_reg/4 |
if (Src Op Dst) skip Off instructions |
jmp_a/1 |
skip Off instructions |
ld_abs/2 |
r0 = *(r6 + imm32) |
ld_imm64_raw_full/6 |
Dst = (Imm1 bsl 32) bor Imm2 |
ld_ind/3 |
r0 = *(r6 + Src + imm32) |
ld_map_fd/2 |
Dst = &Map |
ldx_mem/4 |
Dst = *(Src + Off) |
mov32_imm/2 |
Dst = Imm band 16#FFFFFFF |
mov32_reg/2 |
Dst = Src band 16#FFFFFFF |
mov64_imm/2 |
Dst = Imm |
mov64_reg/2 |
Dst = Src |
push_binary/1 | Same as push_binary/2, with StackHead set to 0. |
push_binary/2 |
push Bin at StackHead |
push_string/1 | Same as push_string/2, with StackHead set to 0. |
push_string/2 |
push String at StackHead |
return/1 |
return Src |
st_mem/4 |
*(Dst + Off) = Imm |
stack_printk/1 | Same as stack_printk/2, with StackHead set to 0. |
stack_printk/2 |
push String at StackHead, r1 = &String, r2 = byte_size(String), trace_printk(r1, r2). |
stx_mem/4 |
*(Dst + Off) = Src |
stx_xadd/4 |
*(Dst + Off) += Src |
alu32_imm(Op::bpf_alu_op(), Dst::bpf_reg(), Imm::bpf_imm()) -> bpf_instruction()
Dst = (Src band 16#FFFFFFF) Op (Imm band 16#FFFFFFF)
alu32_reg(Op::bpf_alu_op(), Dst::bpf_reg(), Src::bpf_reg()) -> bpf_instruction()
Dst = (Src band 16#FFFFFFF) Op (Dst band 16#FFFFFFF)
alu64_imm(Op::bpf_alu_op(), Dst::bpf_reg(), Imm::bpf_imm()) -> bpf_instruction()
Dst = Imm Op Dst
alu64_reg(Op::bpf_alu_op(), Dst::bpf_reg(), Src::bpf_reg()) -> bpf_instruction()
Dst = Src Op Dst
branch(Op::bpf_jmp_op(), Dst::bpf_reg(), Src::bpf_imm() | bpf_reg(), BranchTrue::bpf_instructions(), BranchFalse::bpf_instructions()) -> bpf_instructions()
if Src Op Dst: goto Bt, else goto Bf
call_helper(Helper::bpf_helper()) -> bpf_instruction()
r0 = Helper(r1,r2,r3,r4,r5)
emit_call(Func::integer()) -> bpf_instruction()
r0 = Func(r1,r2,r3,r4,r5)
exit_insn() -> bpf_instruction()
return r0
jmp32_imm(Op::bpf_jmp_op(), Dst::bpf_reg(), Imm::bpf_imm(), Off::bpf_off()) -> bpf_instruction()
if ((Imm band 16#FFFFFFF) Op (Dst band 16#FFFFFFF)) skip Off instructions
jmp32_reg(Op::bpf_jmp_op(), Dst::bpf_reg(), Src::bpf_reg(), Off::bpf_off()) -> bpf_instruction()
if ((Src band 16#FFFFFFF) Op (Dst band 16#FFFFFFF)) skip Off instructions
jmp64_imm(Op::bpf_jmp_op(), Dst::bpf_reg(), Imm::bpf_imm(), Off::bpf_off()) -> bpf_instruction()
if (Imm Op Dst) skip Off instructions
jmp64_reg(Op::bpf_jmp_op(), Dst::bpf_reg(), Src::bpf_reg(), Off::bpf_off()) -> bpf_instruction()
if (Src Op Dst) skip Off instructions
jmp_a(Off::bpf_off()) -> bpf_instruction()
skip Off instructions
ld_abs(Size::bpf_size(), Imm::bpf_imm()) -> bpf_instruction()
r0 = *(r6 + imm32)
ld_imm64_raw_full(Dst::bpf_reg(), Src::bpf_reg(), Off1::bpf_off(), Off2::bpf_off(), Imm1::bpf_imm(), Imm2::bpf_imm()) -> [bpf_instruction()]
Dst = (Imm1 bsl 32) bor Imm2
ld_ind(Size::bpf_size(), Src::bpf_reg(), Imm::bpf_imm()) -> bpf_instruction()
r0 = *(r6 + Src + imm32)
ld_map_fd(Dst::bpf_reg(), Map::bpf_imm()) -> [bpf_instruction()]
Dst = &Map
ldx_mem(Size::bpf_size(), Dst::bpf_reg(), Src::bpf_reg(), Off::bpf_off()) -> bpf_instruction()
Dst = *(Src + Off)
mov32_imm(Dst::bpf_reg(), Imm::bpf_imm()) -> bpf_instruction()
Dst = Imm band 16#FFFFFFF
mov32_reg(Dst::bpf_reg(), Src::bpf_reg()) -> bpf_instruction()
Dst = Src band 16#FFFFFFF
mov64_imm(Dst::bpf_reg(), Imm::bpf_imm()) -> bpf_instruction()
Dst = Imm
mov64_reg(Dst::bpf_reg(), Src::bpf_reg()) -> bpf_instruction()
Dst = Src
push_binary(Bin::binary()) -> {[bpf_instruction()], integer()}
Same as push_binary/2, with StackHead set to 0.
push_binary(Bin::binary(), Head::integer()) -> {[bpf_instruction()], integer()}
push Bin at StackHead
push_string(String::string()) -> {[bpf_instruction()], integer()}
Same as push_string/2, with StackHead set to 0.
push_string(String::string(), StackHead::integer()) -> {[bpf_instruction()], integer()}
push String at StackHead
return(Src::bpf_imm() | bpf_reg()) -> [bpf_instruction()]
return Src
st_mem(Size::bpf_size(), Dst::bpf_reg(), Off::bpf_off(), Imm::bpf_imm()) -> bpf_instruction()
*(Dst + Off) = Imm
stack_printk(String::string()) -> [bpf_instruction()]
Same as stack_printk/2, with StackHead set to 0.
stack_printk(String::string(), StackHead::integer()) -> [bpf_instruction()]
push String at StackHead, r1 = &String, r2 = byte_size(String), trace_printk(r1, r2).
stx_mem(Size::bpf_size(), Dst::bpf_reg(), Src::bpf_reg(), Off::bpf_off()) -> bpf_instruction()
*(Dst + Off) = Src
stx_xadd(Size::bpf_size(), Dst::bpf_reg(), Src::bpf_reg(), Off::bpf_off()) -> bpf_instruction()
*(Dst + Off) += Src
Generated by EDoc