Skip to content

Commit 1eb9b60

Browse files
committed
Add ubpf support via UBPF_jll
1 parent 742463b commit 1eb9b60

File tree

5 files changed

+132
-262
lines changed

5 files changed

+132
-262
lines changed

Manifest.toml

Lines changed: 0 additions & 261 deletions
This file was deleted.

Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ Libbpf_jll = "02f9a84d-9555-5f1a-8c3c-42027521038d"
1212
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
1313
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
1414
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
15+
UBPF_jll = "502467ad-4a4a-57e4-9860-6b433130b33f"
1516

1617
[compat]
1718
CBinding = "1"
1819
GPUCompiler = "0.11"
1920
LLVM = "3.6"
2021
Libbpf_jll = "0.3"
2122
Preferences = "1"
23+
UBPF_jll = "0.0.2"
2224
julia = "1.6"
2325

2426
[extras]

src/BPFnative.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ function enable_vmlinux(ans::Bool=true)
3030
end
3131
end
3232

33+
# ubpf VM
34+
module UBPF
35+
using UBPF_jll
36+
include("ubpf.jl")
37+
end
38+
3339
# Common API
3440
module API
3541
if !parse(Bool, get(ENV, "JULIA_BPFNATIVE_DISABLE_ARTIFACTS", "0"))

src/ubpf.jl

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
export call, verify, load_elf
2+
3+
struct ebpf_inst
4+
opcode::UInt8
5+
dst_src::UInt8
6+
offset::Int16
7+
imm::Int32
8+
end
9+
const ubpf_jit_fn = Ptr{Cvoid}
10+
const ext_func = Ptr{Cvoid}
11+
Base.@kwdef struct ubpf_vm
12+
insts::Ptr{ebpf_inst}
13+
num_insts::UInt16
14+
jitted::ubpf_jit_fn = C_NULL
15+
jitted_size::Csize_t = 0
16+
ext_funcs::Ptr{ext_func} = C_NULL
17+
ext_func_names::Ptr{Cstring} = C_NULL
18+
bounds_check_enabled::Bool = true
19+
end
20+
ubpf_vm(exe::Vector{ebpf_inst}; kwargs...) =
21+
ubpf_vm(pointer(exe), length(exe); kwargs...)
22+
ubpf_vm(exe::Vector{UInt8}; kwargs...) =
23+
ubpf_vm(reinterpret(Ptr{ebpf_inst}, pointer(exe)),
24+
div(length(exe),sizeof(ebpf_inst));
25+
kwargs...)
26+
27+
call(exe::Vector{UInt8}, mem::Vector{UInt8}; kwargs...) =
28+
call(collect(reinterpret(ebpf_inst, exe)), mem; kwargs...)
29+
function call(exe::Vector{ebpf_inst}, mem::Vector{UInt8}; kwargs...)
30+
GC.@preserve exe mem begin
31+
vm = ubpf_vm(exe; kwargs...)
32+
if verify(vm) == 0
33+
unsafe_call(vm, mem)
34+
else
35+
error("BPF verification failed")
36+
end
37+
end
38+
end
39+
function verify(vm::ubpf_vm)
40+
vm_ref = Ref(vm)
41+
GC.@preserve vm_ref begin
42+
ccall((:ubpf_verify, libubpf), Cint, (Ptr{ubpf_vm},), vm_ref)
43+
end
44+
end
45+
function unsafe_call(vm::ubpf_vm, mem::Union{<:Ptr,<:Integer}, mem_len::Integer)
46+
vm_ref = Ref(vm)
47+
mem = sizeof(mem) < sizeof(Ptr{Cvoid}) ? UInt(mem) : mem
48+
GC.@preserve vm_ref mem begin
49+
ccall((:ubpf_exec, libubpf), UInt64,
50+
(Ptr{ubpf_vm}, Ptr{Cvoid}, Csize_t),
51+
vm_ref, reinterpret(Ptr{Cvoid}, mem), mem_len)
52+
end
53+
end
54+
function unsafe_call(vm::ubpf_vm, mem::Vector{UInt8})
55+
vm_ref = Ref(vm)
56+
GC.@preserve vm_ref mem begin
57+
ccall((:ubpf_exec, libubpf), UInt64,
58+
(Ptr{ubpf_vm}, Ptr{Cvoid}, Csize_t),
59+
vm_ref, mem, length(mem))
60+
end
61+
end
62+
function load_elf(vm::ubpf_vm, exe::Vector{UInt8})
63+
vm_ref = Ref(vm)
64+
errmsg = Ref{Cstring}()
65+
ret = GC.@preserve vm_ref errmsg begin
66+
ccall((:ubpf_load_elf, libubpf), Cint,
67+
(Ptr{ubpf_vm}, Ptr{UInt8}, Csize_t, Ptr{Cstring}),
68+
vm_ref, pointer(exe), length(exe), errmsg)
69+
end
70+
if ret != 0
71+
error(unsafe_string(errmsg[]))
72+
end
73+
vm_ref[]
74+
end
75+
load_elf(path::String) = load_elf(read(path))

0 commit comments

Comments
 (0)