-
Notifications
You must be signed in to change notification settings - Fork 143
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
fmaurer-rh
wants to merge
17
commits into
xdp-project:master
Choose a base branch
from
fmaurer-rh:filterc
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Signed-off-by: Felix Maurer <[email protected]>
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]>
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]>
Signed-off-by: Felix Maurer <[email protected]>
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]>
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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.