https://github.com/bpf-endeavor/servant
Servant combines uBPF and AF_XDP. Using it you can write eBPF packet processing programs that run in usersapce.
https://github.com/bpf-endeavor/servant
af-xdp ebpf ubpf
Last synced: 4 months ago
JSON representation
Servant combines uBPF and AF_XDP. Using it you can write eBPF packet processing programs that run in usersapce.
- Host: GitHub
- URL: https://github.com/bpf-endeavor/servant
- Owner: bpf-endeavor
- Created: 2021-11-15T14:07:31.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2025-02-03T09:23:54.000Z (over 1 year ago)
- Last Synced: 2025-04-10T01:11:14.196Z (about 1 year ago)
- Topics: af-xdp, ebpf, ubpf
- Language: C
- Homepage:
- Size: 366 KB
- Stars: 3
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Servant
Servant combines uBPF and AF\_XDP. Using it you can write eBPF packet
processing programs that run in usersapce.
## Compile
**Install the dependencies:**
* Tested on: Linux kernel 5.13
* uBPF (custom version)
* libbpf (commit: f9f6e92458899fee5d3d6c62c645755c25dd502d)
* llvm 13
You can look at `/setup.sh`
**Compile:**
use `make` at `/src/` to compile the Servant.
You can install Servant's header with `make install`.
## Usage
> Enable the Huge page size support.
*Servant Arguments:*
| Arg | Description |
|-----|-------------|
| ifname | name of the ethernet interface to attach |
| qid | queue index for attaching AF\_XDP |
| ebpf | path to the ebpf program binary to load |
| [map] | name of the in kernel map which eBPF program want to access you can also assign the map an index using "name:index". This index could be used with `lookup_fast` helper function.|
| [core] | pin the process to the given CPU core |
| [xdp-prog] | path to the XDP program. this program should have a map of type `BPF_MAP_TYPE_XSKMAP` named `xsks_map`|
| [busypoll] | run AF\_XDP in busy-polling mode |
| [...] | there are other options (to be complete) |
## Run an example program
There are some example programs at `/examples`.
```bash
# map incomming ipv4/udp traffic with destination port of 8080 to queue 2
sudo ethtool -U flow-type udp4 dst-port 8080 action 2
cd ./examples/dump_packet
make
# Run the eBPF program with an AF_XDP socket connected on queue 2
sudo ../../src/servant 2 ./ubpf.o
```
Generate traffic toward the uBPF program. The packets should be displayed on the
terminal.
On the other machine start a netcat and send UDP traffic.
```bash
nc -u 8080
hello
```
Out put of uBPF program should be like below
```
...
Packet size: 60
Src MAC: 3c:fd:fe:56:1:a2
Dest MAC: 3c:fd:fe:55:ff:42
Ether Type: 800
Src IP: c0a80102
Dst IP: c0a80101
Transport: UDP
Src PORT: 57300
Dst PORT: 8080
...
```
## Example eBPF Program
The structure of the program looks like below.
```c
#include
int bpf_prog(struct pktctx *ctx)
{
return DROP;
}
```
**struct pktctx:**
Each eBPF program will receive packets in the following form.
(look at `/src/include/packet_context.h`)
```c
struct pktctx {
void *data; // in: start of the packet
void *data_end; // in: end of the packet
uint32_t pkt_len; // inout: final length of packet
int32_t trim_head; // out: skip n bytes from the head before sending
};
```
**return codes:**
The eBPF program should return one of the following values.
1. `PASS`: Pass the packet to the network stack.
1. `DROP`: Drop the packet.
1. `SEND`: Send the packet on the attached ethernet interface.
> Currently destination of packets injected to the kernel (`PASS`) are hard-coded but this can be solved and is not a limitation.
> Look at `/src/udp_sock.c`
## eBPF Program Helpers
For list of helper functions defined look at `/src/include/servant_engine.h`
| Helper | Description |
|--------|-------------|
| `lookup` | lookup an in kernel map using name of the map |
| `lookup_fast` | lookup an in kernel map using index of the map (You can define index of each map when starting Servant) |
| `userspace_lookup` | lookup a userspace map |
| `userspace_update` | update a usersapce map |
| `ubpf_get_time_ns` | read clock MONOTONIC value |
| `ubpf_print` | print messages |