Skip to content

Commit

Permalink
Add ubpf support via UBPF_jll
Browse files Browse the repository at this point in the history
  • Loading branch information
jpsamaroo committed Jun 15, 2021
1 parent 742463b commit 1eb9b60
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 262 deletions.
261 changes: 0 additions & 261 deletions Manifest.toml

This file was deleted.

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

[compat]
CBinding = "1"
GPUCompiler = "0.11"
LLVM = "3.6"
Libbpf_jll = "0.3"
Preferences = "1"
UBPF_jll = "0.0.2"
julia = "1.6"

[extras]
Expand Down
6 changes: 6 additions & 0 deletions src/BPFnative.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ function enable_vmlinux(ans::Bool=true)
end
end

# ubpf VM
module UBPF
using UBPF_jll
include("ubpf.jl")
end

# Common API
module API
if !parse(Bool, get(ENV, "JULIA_BPFNATIVE_DISABLE_ARTIFACTS", "0"))
Expand Down
75 changes: 75 additions & 0 deletions src/ubpf.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
export call, verify, load_elf

struct ebpf_inst
opcode::UInt8
dst_src::UInt8
offset::Int16
imm::Int32
end
const ubpf_jit_fn = Ptr{Cvoid}
const ext_func = Ptr{Cvoid}
Base.@kwdef struct ubpf_vm
insts::Ptr{ebpf_inst}
num_insts::UInt16
jitted::ubpf_jit_fn = C_NULL
jitted_size::Csize_t = 0
ext_funcs::Ptr{ext_func} = C_NULL
ext_func_names::Ptr{Cstring} = C_NULL
bounds_check_enabled::Bool = true
end
ubpf_vm(exe::Vector{ebpf_inst}; kwargs...) =
ubpf_vm(pointer(exe), length(exe); kwargs...)
ubpf_vm(exe::Vector{UInt8}; kwargs...) =
ubpf_vm(reinterpret(Ptr{ebpf_inst}, pointer(exe)),
div(length(exe),sizeof(ebpf_inst));
kwargs...)

call(exe::Vector{UInt8}, mem::Vector{UInt8}; kwargs...) =
call(collect(reinterpret(ebpf_inst, exe)), mem; kwargs...)
function call(exe::Vector{ebpf_inst}, mem::Vector{UInt8}; kwargs...)
GC.@preserve exe mem begin
vm = ubpf_vm(exe; kwargs...)
if verify(vm) == 0
unsafe_call(vm, mem)
else
error("BPF verification failed")
end
end
end
function verify(vm::ubpf_vm)
vm_ref = Ref(vm)
GC.@preserve vm_ref begin
ccall((:ubpf_verify, libubpf), Cint, (Ptr{ubpf_vm},), vm_ref)
end
end
function unsafe_call(vm::ubpf_vm, mem::Union{<:Ptr,<:Integer}, mem_len::Integer)
vm_ref = Ref(vm)
mem = sizeof(mem) < sizeof(Ptr{Cvoid}) ? UInt(mem) : mem
GC.@preserve vm_ref mem begin
ccall((:ubpf_exec, libubpf), UInt64,
(Ptr{ubpf_vm}, Ptr{Cvoid}, Csize_t),
vm_ref, reinterpret(Ptr{Cvoid}, mem), mem_len)
end
end
function unsafe_call(vm::ubpf_vm, mem::Vector{UInt8})
vm_ref = Ref(vm)
GC.@preserve vm_ref mem begin
ccall((:ubpf_exec, libubpf), UInt64,
(Ptr{ubpf_vm}, Ptr{Cvoid}, Csize_t),
vm_ref, mem, length(mem))
end
end
function load_elf(vm::ubpf_vm, exe::Vector{UInt8})
vm_ref = Ref(vm)
errmsg = Ref{Cstring}()
ret = GC.@preserve vm_ref errmsg begin
ccall((:ubpf_load_elf, libubpf), Cint,
(Ptr{ubpf_vm}, Ptr{UInt8}, Csize_t, Ptr{Cstring}),
vm_ref, pointer(exe), length(exe), errmsg)
end
if ret != 0
error(unsafe_string(errmsg[]))
end
vm_ref[]
end
load_elf(path::String) = load_elf(read(path))
Loading

0 comments on commit 1eb9b60

Please sign in to comment.