- Notifications
You must be signed in to change notification settings - Fork7
A Rust library to write and load bpf programs built on top of libbpf (no bcc dependency).
License
rebpf/rebpf
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
rebpf is a Rust library built on top of libbpf (no bcc dependency) that allows to write and load bpf program, in details this library provides:
- A raw binding of libbpf provide bylibbpf-sys.
- A safe wrapper of libbpf.
- High level ebpf api built on top of libbpf wrapper.
- Parse packets in bpf programs usingpdu, for more details seepacket_parser.
For more details seerebpf.
To create your first ebpf program with rebpf library you can copy and rename anempty_project template and edit it changing <your_project_name>/src/kern.rs and <your_project_name>/src/user.rs files.
Copy this content in <your_project_name>/src/kern.rs:
#![no_std]use rebpf::{LICENSE,VERSION, rebpf_macro::{sec}, libbpf::{XdpAction,XdpMd},};#[sec("license")]pubstatic _license:[u8;4] =LICENSE;#[sec("version")]pubstatic _version:u32 =VERSION;#[sec("xdp_drop")]pubfn_xdp_drop(ctx:&XdpMd) ->XdpAction{XdpAction::DROP}
Note: this ebpf program drop every packets received.
Copy this content in <your_project_name>/src/user.rs:
use rebpf::{libbpf, interface, erroras rebpf_error};use clap::{Arg,App};use std::path::Path;constDEFAULT_FILENAME:&str ="kern.o";constDEFAULT_DEV:&str ="wlan0";fnload_bpf(interface:&interface::Interface,bpf_program_path:&Path,xdp_flags: libbpf::XdpFlags) ->Result<(), rebpf_error::Error>{let(_bpf_object, bpf_fd) = libbpf::bpf_prog_load(bpf_program_path, libbpf::BpfProgType::XDP)?; libbpf::bpf_set_link_xdp_fd(&interface,Some(&bpf_fd), xdp_flags)?;let info = libbpf::bpf_obj_get_info_by_fd(&bpf_fd)?;println!("Success Loading\n XDP prog name: {}, id {} on device: {}", info.name()?, info.id(), interface.ifindex());Ok(())}fnunload_bpf(interface:&interface::Interface,xdp_flags: libbpf::XdpFlags) ->Result<(), rebpf_error::Error>{ libbpf::bpf_set_link_xdp_fd(&interface,None, xdp_flags)?;println!("Success Unloading.");Ok(())}fnrun(bpf_program_path:&Path,interface_name:&str,unload_program:bool) ->Result<(), rebpf_error::Error>{let interface = interface::get_interface(interface_name)?;let xdp_flags = libbpf::XdpFlags::UPDATE_IF_NOEXIST | libbpf::XdpFlags::SKB_MODE;if unload_program ==false{load_bpf(&interface, bpf_program_path, xdp_flags)}else{unload_bpf(&interface, xdp_flags)}}fnmain(){let bpf_program_path =Path::new(DEFAULT_FILENAME);let unload_program =false;matchrun(&bpf_program_path,DEFAULT_DEV, unload_program){Err(err) =>println!("{:?}", err),Ok(_) =>{}};}
Move into <your_project_name> folder and run the script build.sh:
cd <your_project_name>./build.sh
cd <your_project_name>/ebpf_outputsudo user
Expected output:
Success Loading XDP prog name: _xdp_drop, id 33 on device: 2
empty_project template allows to write bpf programs and bpf userspace loader in a single Rust project and compile both withbuild.sh script but it is also possible does two different project and compile both apart:
- To compile bpf userspace loader project it is possible use "cargo build --release".
- Because Rust compiler doesn't allow to emit bpf bytecode, to compile bpf project the only way is emit llvm-bytecode with Rust compiler and convert it with llc into bpf bytecode (llvm allows to compile llvm-bytecode into bpf-bytecode).
link.
link.
To allows that bpf verifier accept your Rust bpf program you must be sure that in your source code all functions are inline and that you check all array access explicity with a if condition (you must check the array pointer address and not the slice length). Besides there are some Rust core/std functions that internally call #inline(never) functions (i.e.SliceIndex) and there isn't away to force Rust compiler to compile these functions inline, so to fix this problem i have made a bash scriptsbuild.sh andremove_undefined_functions.sh that automatically remove these functions from llvm-bytecode before compile to bpf-bytecode and then allow you to use Rust core functions writing bpf programs in Rust.
- A recentlinux kernel
- LLVM 9
- libelf
- zlib
Roadmap is composed from all issues with label "roadmap". If you want contribute to this repo to avoid future conflicts you can describe what are you implementing in a new issue with label "roadmap".
Licensed under The MIT License (MIT)https://mit-license.org/.