Code Monkey home page Code Monkey logo

ebpf's Introduction

ebpf

Erlang CI

Erlang eBPF library

Overview

ebpf is an Erlang library for creating and interacting with eBPF programs. The following modules are currently included:

  • ebpf_user: load eBPF programs and use loaded programs
  • ebpf_kern: generate eBPF instructions according to different parameters
  • ebpf_asm: eBPF assembly and disassembly routines
  • ebpf_maps: userspace API to eBPF maps, mimics the Erlang/OTP maps interface with eBPF maps

Documentation

The documentation for the latest release can be browsed on hexdocs. Documentation for the main branch is also available here. ebpf is documented with edoc, the docs can be built locally with

$ rebar3 edoc

Usage

Checkout the examples.

A minimal example is given below:

% Drop all packets
BinProg = ebpf_asm:assemble(ebpf_kern:return(0)),

{ok, FilterProg} = ebpf_user:load(socket_filter, BinProg),
{ok, Sock} = socket:open(inet, stream, {raw, 0}),
ok = ebpf_user:attach(Sock, FilterProg), % All new input to Sock is dropped
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("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).

Add ebpf as a dependency in rebar.config:

% From hex
{deps, [ebpf]}.
% Or from github
{deps, [{ebpf, {git, "https://github.com/oskardrums/ebpf.git", "main"}}]}.

{error, eperm}

Most BPF operations require elevated permissions on most Linux systems. Lack of permissions usually manifests in ebpf in function calls failing with {error, eperm}.

To allow ebpf to run privileged operations, BEAM needs to be given permission to do so. The quickest way to do that for local testing is to run your program as super user, e.g.

$ sudo `which rebar3` shell

For production systems, Linux capabilities should be given to the user or to the BEAM executable. Most bpf(2) operations demand CAP_SYS_ADMIN capability, and some XDP operations demand CAP_NET_ADMIN.

Since Linux 4.4, socket_filter type eBPF programs can be loaded without elevated permissions under some conditions. For more information see the bpf(2) man page.

Build

$ rebar3 compile

ebpf uses NIFs to communicate with the Linux kernel eBPF system. You will need make, a C compiler and Linux headers for rebar3 to build the .so that contains those NIFs.

Test

$ rebar3 do ct, proper

Contributions

Are welcome :)

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

ebpf's People

Contributors

kzemek avatar oskardrums avatar tsloughter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

tsloughter kzemek

ebpf's Issues

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.

Expand README.md

  • Acknowledge ebpf_asm
  • Add portability section (ebpf_user only works on Linux by definition, the rest is fully portable)

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.

Better error reporting from ebpf_lib:verify/2

We should add an option to ebpf_lib:verify to choose the error buffer size, rather than arbitrarily setting it to 4096.
Also, when the error is not eacces (e.g. encoding problem) we should report the errno rather than an empty error report string.

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.

rely on libbpf

Is there any reason to do not link directly the libbpf?

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.

Better disassembly

ebpf_lib:disassemble/1 should return some semantic meaning bearing format, rather than the numeric value of eBPF opcodes.

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.

Consistent documentation

Make sure that the documentation is clear and consistent (it currently isn't), and add links between sections where needed

  • ebpf_user
  • ebpf_kern
  • ebpf_asm
  • overview page?

EDIT:
ebpf_user documentation was updated in #30
ebpf_kern was updated in #31

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

Expand test suite

  • ebpf_user - verify/2, verify/3, update_map_element/4, lookup_map_element/4, delete_map_element/2, get_map_next_key/2, attach_xdp/2
  • ebpf_kern
  • ebpf_asm (pretty much covered, rebar3 proper --cover has it at 100%)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.