Erlang interface to eBPF

Overview

ebpf

Erlang CI

Erlang eBPF library

Overview

ebpf facilitates basic interaction with the Linux eBPF system from Erlang. Three modules are currently included:

  • ebpf_user contains NIFs that wrap the Linux native API to eBPF, ultimately calling the bpf(2) syscall
  • ebpf_kern contains functions that generate eBPF instructions according to different parameters
  • ebpf_asm contains eBPF assembly and disassembly routines

Status

This library is not yet feature complete nor is it extensively tested.

The current API should remain pretty stable, while it is planned to be expanded to expose more eBPF functionalities and perhaps also include a higher lever interface a la gen_bpf.

Documentation

$ rebar3 edoc

The documentation for the latest version can be browsed at https://oskardrums.github.io/ebpf/

Build

$ rebar3 compile

Test

$ rebar3 do ct, proper

Usage

Checkout the examples.

A minimal example is given below:

BinProg = ebpf_asm:assemble([
                % Drop all packets
                ebpf_kern:mov64_imm(0, 0), % r0 = 0
                ebpf_kern:exit_insn()      % return r0
            ]),

{ok, FilterProg} = ebpf_user:load(socket_filter, BinProg),
{ok, Sock} = socket:open(inet, stream, {raw, 0}),
ok = ebpf_user:attach_socket_filter(Sock, FilterProg), % All new input to Sock is
ok = ebpf_user:detach_socket_filter(Sock), % Sock is back to normal and FilterProg can be
ok = ebpf_user:close(FilterProg), % FilterProg is unloaded from the kernel

{ok, XdpProg} = ebpf_user:load(xdp, BinProg),
ok = ebpf_user:attach_xdp("lo", XdpProg), % Try pinging 127.0.0.1, go ahead
ok = ebpf_user:detach_xdp("lo"), % Now, that's better :)
ok = ebpf_user:close(XdpProg).

For projects that build with rebar3, add ebpf as a dependency in rebar.config:

{deps, [{ebpf, {git, "https://github.com/oskardrums/ebpf.git", "main"}}]}.

Contributions

Are welcome :)

Fill free to open an issue or a PR if you encounter any problem or have an idea for an improvement.

Comments
  • Allow ebpf_maps:close/1 to close iterators as well as maps

    Allow ebpf_maps:close/1 to close iterators as well as maps

    eBPF maps should be closed, whether used as ebpf_maps:ebpf_map()s or as ebpf_maps:iterator(), but currently close/1 only works for ebpf_map()s, so the original map needs to be kept around after calling iterator/1. This PR allows close/1 to close iterator()s directly.

    enhancement invalid 
    opened by oskardrums 0
  • Add ebpf_kern:branch/5 and ebpf_kern:return/1

    Add ebpf_kern:branch/5 and ebpf_kern:return/1

    This PR adds two functions to ebpf_kern:

    • branch/5 is a generic branching utility function. It takes a bpf_jmp_op(), two operands (one must be a register, the other can be either a register or an immediate value) and two instruction lists and generates instructions that branch to either list depending on the result of the comparison.
    • return/1 is a function for generating instructions that return from the eBPF program with a specific return value, given as either an immediate value or a register whose contents will be set as the return value of the program.

    Part of #53

    opened by oskardrums 0
  • Add ebpf_maps:take/2

    Add ebpf_maps:take/2

    stdlib has maps:take/2, we should have an equivalent ebpf_maps:take/2 for eBPF map. This can possibly be implemented by using the BPF_MAP_LOOKUP_AND_DELETE_ELEM command to bpf(2).

    Edit: it appears that Linux only supports BPF_MAP_LOOKUP_AND_DELETE_ELEM for queue and stack typed maps. We can use implement take/2 with get/2 and remove/2 for other types of maps

    enhancement good first issue 
    opened by oskardrums 0
  • Use atoms rather than integers to represent eBPF registers

    Use atoms rather than integers to represent eBPF registers

    Part of #41 .

    Using integers for registers, offsets and immediate values in ebpf_kern can lead to confusing calls, like

    ebpf_kern:mov64_imm(0, 1)
    

    The problem is that it's hard to tell by looking at the code whether that line means r0 = 1 or r1 = 0.

    This PR changes the bpf_reg() type the atoms r0, r1, ..., r10 instead of the numeric values of the registers. Hence, after this PR instead of mov64_imm(0, 1) we have

    ebpf_kern:mov64_imm(r0, 1)
    

    which does not suffer from the same ambiguity.

    opened by oskardrums 0
  • Add ebpf_user:attach/2

    Add ebpf_user:attach/2

    Part of #41 This PR merges the ebpf_user:attach_*/2 functions to a single ebpf_user:attach/2 API function. The type of the attach point is determined by the type of the given program.

    opened by oskardrums 0
  • Add ebpf_maps module and move related functions from ebpf_user

    Add ebpf_maps module and move related functions from ebpf_user

    Part of #41

    This PR adds the ebpf_maps module, an API for userspace interaction with eBPF maps that mimics the built-in maps module. Some functions that dealt with eBPF maps are moved from ebpf_user, which is dedicated to eBPF programs, to the new maps module.

    opened by oskardrums 0
  • Add ebpf_user:load/3

    Add ebpf_user:load/3

    Support specifying options to ebpf_user:load via an added Options arg.

    Edit: I went ahead and removed the redundant ebpf_user:verify/{2,3} functions while at it as we now get the same functionality with an option for load/3.

    Part of #41

    opened by oskardrums 0
  • Finalize API before releasing v0.2

    Finalize API before releasing v0.2

    The current (initial, v0.1) API is very familiar to those who know eBPF, but it isn't very idiomatic for Erlang programmers. For instance, interaction with eBPF maps could be made a lot more familiar for Erlangers if it was modeled after the OTP maps module.

    I want to fix that for v0.2. This library is meant to be used by Erlang programmers, so a familiar API is a priority. Of course, the API should also be as stable as possible, so whatever ends up in v0.2 should be future proof. Although it's still a minor version the goal is for v0.2 to implement a minimal API that will not break in later versions.

    opened by oskardrums 0
  • ebpf_user: Add test_program/4 function

    ebpf_user: Add test_program/4 function

    Add ebpf_user:test_program/4, which can be used to run a loaded eBPF program with an arbitrary binary() as the input, courtesy of BPF_PROG_TEST_RUN command to bpf(2). This can be generally useful and it's needed for properly testing ebpf_kern.

    opened by oskardrums 0
  • Handle file descriptors more transparently

    Handle file descriptors more transparently

    Currently it is the users responsibility to close(2) eBPF map and program file descriptors via ebpf_{maps,user}:close/1. It would be safer and more convenient if these FDs were to close automatically when no longer needed. There easiest solution would be to use Erlang NIF "resources" for maps/programs instead just passing an integer FD back to BEAM. NIF resources can have a destructor-like callback that is called from the garbage collector when the resource is no longer in use, which is where we can close the FD.

    Another path would be to drop the NIFs entirely and use an Erlang port driver to represent maps/programs. That would allow for closing the FDs when the owner Erlang process of the map/program dies.

    enhancement userspace 
    opened by oskardrums 0
  • Use a helper executable for privileged operations

    Use a helper executable for privileged operations

    Add a small binary executable that will be invoked to perform privileged operations, e.g. bpf(2), in behalf of BEAM. That way this helper executable can be given elevated capabilities instead of the BEAM executable, making things much safer in the long term.

    enhancement userspace 
    opened by oskardrums 0
  • Add a higher level API for constructing eBPF programs

    Add a higher level API for constructing eBPF programs

    Currently ebpf_kern allows you to write eBPF programs, but it doesn't make it particularly easy or Erlang-y. ebpf should supply some higher level API for constructing eBPF programs.

    I think that the best solution would be having a fun2bpf parse-transform that takes a literal Erlang fun and outputs a sequence of bpf_instructions, but there are a few steps to cross to get there. For starters it would be nice to have ebpf_kern functions for more common eBPF routines, like loading a value from a map to a specific register, or branching without having to count instructions for the jmp instruction.

    enhancement help wanted kernelspace 
    opened by oskardrums 0
  • Support eBPF tracing

    Support eBPF tracing

    This is a big one, so we should start with something small. At the very least ebpf_user:attach/2 needs to support kprobe and tracepoint program types.

    enhancement help wanted 
    opened by oskardrums 0
Releases(v0.2.3)
Owner
null
A tool for generating cross-language type declarations and interface bindings.

Djinni Djinni is a tool for generating cross-language type declarations and interface bindings. It's designed to connect C++ with either Java or Objec

Dropbox 2.8k Jan 3, 2023
A portable foreign-function interface library.

Status libffi-3.4 was released on TBD. Check the libffi web page for updates: URL:http://sourceware.org/libffi/. What is libffi? Compilers for high le

null 2.7k Jan 5, 2023
NIF interface from Erlang to LMDB databases

Elmdb, an Erlang NIF for LMDB This is an Erlang NIF for OpenLDAP's Lightning Memory-Mapped Database (LMDB) database library. LMDB is a fast, compact k

null 3 Sep 27, 2021
Legion Low Level Rendering Interface provides a graphics API agnostic rendering interface with minimal CPU overhead and low level access to verbose GPU operations.

Legion-LLRI Legion-LLRI, or “Legion Low Level Rendering Interface” is a rendering API that aims to provide a graphics API agnostic approach to graphic

Rythe Interactive 25 Dec 6, 2022
Example program using eBPF to log data being based in using shell pipes

Example program using eBPF to log data being based in using shell pipes (|)

pat_h/to/file 35 Oct 21, 2022
libsinsp, libscap, the kernel module driver, and the eBPF driver sources

falcosecurity/libs As per the OSS Libraries Contribution Plan, this repository has been chosen to be the new home for libsinsp, libscap, the kernel mo

Falco 133 Dec 29, 2022
Basic eBPF examples in Golang using libbpfgo

libbpfgo-beginners Basic eBPF examples in Golang using libbpfgo. Accompanying slides from my talk at GOTOpia 2021 called Beginner's Guide to eBPF Prog

Liz Rice 166 Dec 28, 2022
Linux Application Level Firewall based on eBPF and NFQUEUE.

eBPFSnitch eBPFSnitch is a Linux Application Level Firewall based on eBPF and NFQUEUE. It is inspired by OpenSnitch, and Douane, but utilizing modern

Harpo Roeder 665 Dec 29, 2022
In-kernel cache based on eBPF.

BMC BMC (BPF Memory Cache) is an in-kernel cache for memcached. It enables runtime, crash-safe extension of the Linux kernel to process specific memca

Orange 383 Dec 16, 2022
eBPF bytecode assembler and compiler

An eBPF bytecode assembler and compiler that * Assembles the bytecode to object code. * Compiles the bytecode to C macro preprocessors. Symbolic

Emil Masoumi 6 Jan 23, 2022
Example how to run eBPF probes without a usermode process using fentry

Pinning eBPF Probes Simple example to demonstrate how to pin kernel function and syscall probes. Overview From my reading of the kernel code, KProbe a

pat_h/to/file 3 Jun 7, 2021
A Rust crate that simplifies the integration of Rust and eBPF programs written in C.

This crate simplifies the compilation of eBPF programs written in C integrating clang with Rust and the cargo build system with functions that can be

Simone Margaritelli 19 Mar 16, 2022
eBPF implementation that runs on top of Windows

eBPF for Windows eBPF is a well-known technology for providing programmability and agility, especially for extending an OS kernel, for use cases such

Microsoft 1.7k Jan 9, 2023
ebpfkit-monitor is a tool that detects and protects against eBPF powered rootkits

ebpfkit-monitor ebpfkit-monitor is an utility that you can use to statically analyse eBPF bytecode or monitor suspicious eBPF activity at runtime. It

Guillaume Fournier 79 Dec 18, 2022
A very basic eBPF Load Balancer in a few lines of C

An eBPF Load Balancer from scratch As seen at eBPF Summit 2021. This is not production ready :-) This uses libbpf as a git submodule. If you clone thi

Liz Rice 168 Jan 8, 2023
skbtracer on ebpf

skbtracer skbtracer 基于 ebpf 技术的 skb 网络包路径追踪利器, 实现代码基于 BCC (required Linux Kernel 4.15+) 使用样例 skbtracer.py # trace

DavadDi 54 Dec 30, 2022
some experiments with ebpf

Learning eBPF and some kernel tracing, probe DNS + TCP connection with portable bpf prog. DevEnv Ubuntu 20.04 Install go Install make, clang, llvm Ins

null 11 Aug 4, 2022
Small utility that leverages eBPF to dump the traffic of a unix domain socket

UnixDump UnixDump is a small eBPF powered utility that can be used to dump unix socket traffic. System requirements This project was developed on a Ub

Guillaume Fournier 8 Nov 19, 2022
Tool for Preventing Data Exfiltration with eBPF

bouheki: Tool for Preventing Data Exfiltration with eBPF bouheki is a KSRI implementation using LSM Hook by eBPF. Flexibility to apply restricted netw

mrtc0 54 Jan 3, 2023
The Beginner's Guide to eBPF Programming for Networking

The Beginner's Guide to eBPF Programming for Networking As seen at Cloud Native eBPF Day 2021. Setup Create a container that we can issue curl request

Liz Rice 79 Dec 23, 2022