-
Notifications
You must be signed in to change notification settings - Fork 5
Using the linux rex module
To work with regular expressions in the eBPF these 3 components are required:
- Patched Linux kernel
- Hyperscan userspace tools or library
- Hyperscan kernel module
See the Installation page for more details about kernel patches and installation steps.
When loaded, xdp_rex.ko exposes two helpers to XDP programs:
#include "rex.h"
int bpf_scan_bytes(const void *buf, __u32 buf__sz,
struct rex_scan_attr *scan_attr);
int bpf_xdp_scan_bytes(struct xdp_md *xdp_md, __u32 offset, __u32 len,
struct rex_scan_attr *scan_attr);The bpf_scan_bytes receives any linear buffer to scan through the pointer.
Unfortunately eBPF verifier cannot prove safety of variable-sized packet memory access.
To trick around this limitation we provide a second helper bpf_xdp_scan_bytes that takes XDP context and packet offsets.
Both forms take input/output attributes:
-
rex_scan_attr->database_id: an identifier of a pattern compiled and loaded into the module usingconfigfs, we will cover this below. -
rex_scan_attr->handler_flags:match_callback's behaviour flags. Currently the only option isREX_SINGLE_SHOT, when engine stops on the very first match.
Other struct rex_scan_attr fields are filled with match results.
Return values:
-
-errnoin case of failures, -
0if the whole buffer was scanned -
1if scanning was terminated eagerly.
Note, that programs linked with that helpers won't load without
xdp_rexmodule.
#include "rex.h"
SEC("xdp")
int dummy(struct xdp_md *xdp)
{
struct rex_scan_attr attr = {};
attr.database_id = 1234;
__u32 len = xdp->data_end - xdp->data;
return bpf_xdp_scan_bytes(xdp, 0, len, &attr);
}Before the XPD program can use regular expressions, they must be compiled and loaded to the module via configfs interface.
The resulting regex identifier must be passed to the eBPF program to use the compiled database.
To load a new database to the module, a user can create a new knob in the configfs directory - /sys/kernel/config/rex/<pattern_name>.
The name of the knob may be any, but we recommend to use meaningful names.
Every knob has entities:
- id (rw): unique identifier of a regular expression. May be set by a user or dynamically generated by the module (default).
- database (rw): a regular expression compilled by the Hyperscan tools
- epoch (ro): update counter of the database. Zero after knob creation, non-zero after setting the database
- note (rw): an auxiliary text string. We recommend to put a text representation of the database (before compilation), to review, what is loaded.
Insert the module first.
modprobe xdp_rex.koCreate a file, that contains all the regular expressions that should be evaluated simultaneously for the same buffer.
echo '101:/foobar/' > patterns.txt
echo '201:/a{3,10}/' >> patterns.txtCompile regular expressions:
rm -rf out/ && mkdir out
hscollider -e patterns.txt -ao out/ -n1Load the patterns into the kernel module:
mkdir /sys/kernel/config/rex/foobar
dd if=$(echo out/``.db) of=/sys/kernel/config/rex/foobar/database
cat patterns.txt > /sys/kernel/config/rex/foobar/noteOptionally verify the loaded database:
cat /sys/kernel/config/rex/hello/epoch # -> 1
diff /sys/kernel/config/rex/hello/database out/``.db
cat /sys/kernel/config/rex/foobar/noteA user-defined identifier can be used for the regular expression.
cat 1234 > /sys/kernel/config/rex/hello/idVerify the examples for the correctness of the loaded generation:
bpftool prog load dummy.o /sys/fs/bpf/dummy
echo 'xxx foobar yyy' > data.txt
bpftool prog run pinned /sys/fs/bpf/dummy data_in data.txt repeat 1The following conditions must be met before the module can be unloaded:
- All the regular expression databases are removed, and the
/sys/kernel/config/rexis empty, - No eBPF programs linked with helper left loaded.