6 minutes
An Introduction to the bpftool
The bpftool
bpftool
is a command-line utility in Linux for interacting with eBPF programs and maps
. It allows you to perform various operations such as loading and attaching programs, manipulating maps, and retrieving information about eBPF objects.
Here are some common use cases of bpftool
:
-
Listing BPF Programs and Maps: View a list of loaded eBPF programs and maps on your system. It provides information such as program IDs, names, types, and associated maps.
-
Loading and Unloading BPF Programs: It allows you to load eBPF programs into the kernel. You can specify the program type, source code file, and associated maps. It also provides options to unload and detach programs from the kernel.
-
Inspecting BPF Objects: Provides detailed information about eBPF programs, maps, and other BPF objects. It allows you to retrieve attributes, statistics, and configuration parameters of these objects.
-
Managing BPF Maps: Provides functionality to create, update, and delete eBPF maps. You can specify the map type, key size, value size, and other relevant parameters while creating or modifying a map.
-
Debugging and Tracing: Offers features for debugging and tracing eBPF programs. It enables you to attach to programs and monitor their execution, including printing debug output and tracing events.
These are just a few examples of what we can do with bpftool
.
For more information on using bpftool
, you can refer to the official documentation or run man bpftool in your terminal.
Installation
To install bpftool
on Ubuntu, follow these steps:
-
Update your system:
sudo apt update && sudo apt upgrade
-
Install
bpftool
:sudo apt install linux-tools-common linux-tools-generic linux-tools-$(uname -r)
-
Verify the installation:
bpftool -V
The bpftool in Action
Let’s go over a few examples to showcase how the bpftool
can be used.
I use
flat
as the program name to comply with the eBPF program we’re developing. Althoughflat
usestc
and examples below areXDP
. This is just for demonstration purposes.
Show Commands
-
show all the eBPF programs loaded into the kernel at present:
sudo bpftool prog list
-
Get information about a specific eBPF program; either with
id
,name
ortag
:sudo bpftool prog show id 72 sudo bpftool prog show name flat sudo bpftool prog show tag f1db4e564ad5219a
-
show the bytecode instructions for eBPF programs:
sudo bpftool prog dump xlated name flat
-
show a specific eBPF program based on its name. For instance,
flat
:sudo bpftool prog show name flat
-
Display all the network-related eBPF programs by running the following command:
sudo bpftool net list
The output should be similar to:
xdp: lo(1) generic id 93 tc: flow_dissector:
-
You can also use the
ip
command to see that the program is attached to the lo interface:ip a show dev lo
The output is similar to:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric/id:135 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever
Notice that in the first line of output you see
xdpgeneric/id:135
where135
is the eBPF program ID. -
show information of a
map
:sudo bpftool map show id $MAP_ID
-
show the value that corresponds to a particular key in a
map
:Note that you have to specify each of the 8 bytes of the key individually, starting with the least significant. You can use hex notation if you prefer, so all of the following are equivalent:
sudo bpftool map lookup id $MAP_ID key 100 0 0 0 0 0 0 0 # or sudo bpftool map lookup id $MAP_ID key 100 0 0 0 0 0 0 0 sudo bpftool map lookup id $MAP_ID key 0x64 0 0 0 0 0 0 0 sudo bpftool map lookup id $MAP_ID key hex 64 0 0 0 0 0 0 0
-
Here’s the command to run to see any tracing being generated by any eBPF programs:
(useful if we do not have a frontend program to do it for us)
sudo bpftool prog trace log
eBPF tracing output gets sent to a pseudofile at
/sys/kernel/debug/tracing/trace_pipe
- an alternative to using bpftool is simply to use cat on this file. Notice that all tracing gets generated to this single location, which is why you would probably use a map to extract output to user space for production applications.
TC Specific Show Commands
-
Show
qdisc
s associated with an interface, loopback (lo) in this case:sudo tc qdisc show dev lo
-
show qdisc
filters
attached to an interface, loopback (lo) in this case:sudo tc filter show dev lo
Load and Attach eBPF TC programs
-
Create a
qdisc
for an interface, loopback (lo) in this case:sudo tc qdisc add dev lo clsact
-
Attach the eBPF program to
ingress
,egress
or both traffic directions:sudo tc filter add dev lo ingress bpf direct-action obj flat.o sec tc sudo tc filter add dev lo egress bpf direct-action obj flat.o sec tc
TC Hardware Offload
Similar to XDP
, tc
programs can also be offloaded to the NIC (if the NIC supports hardware offload).
-
Install ethtool:
sudo apt install ethtool
-
Enable hardware offloading on a NIC:
ethtool -K eth0 hw-tc-offload on
-
Create a
qdisc
for an interface,eth0
in this case:sudo tc qdisc add dev eth0 clsact
-
Attach the eBPF program to
ingress
,egress
or both traffic directions and offload to NIC usingskip_sw
:sudo tc filter add dev eth0 ingress bpf skip_sw direct-action obj flat.o sec tc sudo tc filter add dev eth0 egress bpf skip_sw direct-action obj flat.o sec tc
Load and Attach eBPF XDP programs
-
Load the eBPF byte code into the kernel and link it to the filesystem so that it may be identified as
/sys/fs/bpf/flat
:sudo bpftool prog load flat.o /sys/fs/bpf/flat
-
At this point the program is not associated with any events that would trigger it. Associate or attach eBPF program to
lo
network interface:sudo bpftool net attach xdp name flat dev lo
-
Additionally, we can also use the
ip
command to load our eBPF command:sudo ip link set dev lo xdp obj flat.o sec xdp
Update Commands
Update a map
:
sudo bpftool map update id $MAP_ID key 5 0 0 0 0 0 0 0 value 0 0 0 0 0 0 0 1
Unload and Detach eBPF TC programs
-
Detach the eBPF program:
sudo tc filter del dev lo ingress sudo tc filter del dev lo egress
-
Delete the
qdisc
:sudo tc qdisc del dev lo clsact
Deleting a qdisc
will remove its filters as well.
Unload and Detach eBPF XDP programs
-
Unload the eBPF program:
sudo rm /sys/fs/bpf/flat
-
Detach the eBPF program:
sudo bpftool net detach xdp dev lo