Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce compiler for pcap filters/cBPF programs to XDP programs #356

Draft
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

fmaurer-rh
Copy link

pcap-filter strings, like you pass them to tcpdump, are a convenient way to match packets. But libpcap only compiles them into cBPF programs; to use them with XDP programs, we need them converted to eBPF.

This patchset provides a way to compile pcap-filter strings to cBPF (it just wraps libpcap for that) and then compile the cBPF program into an eBPF program. The eBPF program is designed to pass the verifier, i.e., all packet accesses are prefixed with guard instructions so the verifier knows it is safe to load from that that address. We emit a BPF object file (ELF format) that libbpf understands and can load without much effort. Optionally, the BPF object file can be created to be linkable into other XDP programs using bpf_linker from libbpf. This way, you can generate the packet matching component of your program from pcap-filter strings and write the rest of the program in C as usual.

We provide a tool (filterc) to compile the filters from the command line. The heavylifting is done by functions that should be easy to move into libxdp if that's desired. The implementation of the conversion is similar to the in-kernel implementation of such conversion but with added guards to packet accesses and removed special instructions that are not needed for simple packet matching. However, this required to have access to filter.h from the kernel. The patches include some simple tests that make sure filters can be compiled and loaded; compiled, linked and loaded; and pass some basic sanity tests with bpf_test_run.

Add a few helpful functions for error handling and to dump the program.

Signed-off-by: Felix Maurer <[email protected]>
Start with the arithmetic instructions and a simple conversion of jumps.
The jumps will be optimized in the future (if one of the branches goes to
the next instruction).

Signed-off-by: Felix Maurer <[email protected]>
The store instructions need to be guarded, i.e., checked that they only
access data within the packet, because we need to pass the verifier.

Linux supports legacy packet access instructions that were carried over
from cBPF. However, they are only supported for programs where the context
is an skb, not for XDP programs.  Therefore, rewrite legacy packet access
instructions to a series of eBPF instructions.

Document register usage for the future. We prefer caller-saved registers at
the moment because they don't need to be saved, i.e., pushed to the stack,
in the JITed function, and we don't call into other functions anyways.

Signed-off-by: Felix Maurer <[email protected]>
We can now write something that is a valid ELF file, although not
containing anything useful yet. The code and BTF information will be added
in the next commits.

Signed-off-by: Felix Maurer <[email protected]>
Only print the debug output if it is actually requested with the respective
command line option.

Signed-off-by: Felix Maurer <[email protected]>
The opcode of eBPF instructions has different meaning depending on the
instruction class. Respect that when dumping the program.

Signed-off-by: Felix Maurer <[email protected]>
Add write options in a struct that can be extended in the future. The
struct is ready to be used with the validation mechanisms of libbpf/libxdp
but they are not validated yet, because those mechanisms are internal to
the libraries at the moment.

Signed-off-by: Felix Maurer <[email protected]>
Add a basic test to check if a compiled filter can be loaded into the
kernel and does something similar to what we expect.

Signed-off-by: Felix Maurer <[email protected]>
Add an option to configure the program name in the BPF object file.

Signed-off-by: Felix Maurer <[email protected]>
If a BPF program should be linked into other programs, it requires some
differences in the ELF object file:
- The program needs to be in the text section

Add an option to set how the BPF object file should look like. Also add a
parameter to filterc to create linkable objects.

Signed-off-by: Felix Maurer <[email protected]>
Compile a bunch of programs and check if they pass/fail as expected.

Signed-off-by: Felix Maurer <[email protected]>
When one of the branches goes to the next insn, it is not necessary to emit
two eBPF insns. We can either leave out the second jump if the false case
is the next insn, or we can invert the condition and leave out the second
jump if the true case is the next insn.

Signed-off-by: Felix Maurer <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant