The current ebpf/Makefile.am have the problem that clang compile
errors still result in an ELF .bpf output file. This is obviously
problematic as the problem is first seen runtime when loading
the bpf-prog. This is caused by the uses of a pipe from
clang to llc.
To address this problem, split up the clang and llc invocations
up into two separate commands, to get proper reaction based on
the compiler exit code. The clang compiler is used as a
frontend (+ optimizer) and instructed (via -S -emit-llvm) to
generate LLVM IR (Intermediate Representation) with suffix .ll.
The LLVM llc command is used as a compiler backend taking IR and
producing BPF machine bytecode, and storing this into a ELF
object. In the last step the IR .ll suffix code it removed.
The official documentation of the IR language:
http://llvm.org/docs/LangRef.html
Also fix the previous make portability warning:
'%-style pattern rules are a GNU make extension'
I instead use some static pattern rules:
https://www.gnu.org/software/make/manual/html_node/Static-Usage.html
Signed-off-by: Jesper Dangaard Brouer <netoptimizer@brouer.com>
Enable compiling eBPF programs with clang -target bpf.
This is mostly to workaround a bug in libbpf, where clang > ver 4.0.0
generates some ELF sections (.eh_frame) when -target bpf is NOT specified,
and libbpf fails loading such files.
Notice libbpf is provided by the kernel, and in kernel v4.16 the library
will contain the needed function for attaching to the XDP hook.
Kernel commit 949abbe88436 ("libbpf: add function to setup XDP")
https://git.kernel.org/torvalds/c/949abbe88436
The library fix has reached kernel v4.16 but the workaround for Suricata
is interesting anyway in case people use a kernel v4.15.
Signed-off-by: Jesper Dangaard Brouer <netoptimizer@brouer.com>
This patch prepares code before enabling the clang -target bpf.
The clang compiler does not like #include <stdint.h> when
using '-target bpf' it will fail with:
fatal error: 'gnu/stubs-32.h' file not found
This is because using clang -target bpf, then clang will have '__bpf__'
defined instead of '__x86_64__' hence the gnu/stubs-32.h include
attempt as /usr/include/gnu/stubs.h contains, on x86_64:
#if !defined __x86_64__
# include <gnu/stubs-32.h>
#endif
#if defined __x86_64__ && defined __LP64__
# include <gnu/stubs-64.h>
#endif
#if defined __x86_64__ && defined __ILP32__
# include <gnu/stubs-x32.h>
#endif
This can be worked around by installing the 32-bit version of
glibc-devel.i686 on your distribution.
But the BPF programs does not really need to include stdint.h,
if converting:
uint64_t -> __u64
uint32_t -> __u32
uint16_t -> __u16
uint8_t -> __u8
This patch does this type syntax conversion.
The build of a ebpf files had an issue for system like Debian
because they don't have a asm/types.h in the include path if the
architecture is not defined which is the case due to target bpf.
This results in:
clang-5.0 -Wall -Iinclude -O2 \
-D__KERNEL__ -D__ASM_SYSREG_H \
-target bpf -S -emit-llvm vlan_filter.c -o vlan_filter.ll
In file included from vlan_filter.c:19:
In file included from include/linux/bpf.h:11:
/usr/include/linux/types.h:5:10: fatal error: 'asm/types.h' file not
found
#include <asm/types.h>
^~~~~~~~~~~~~
1 error generated.
Makefile:523: recipe for target 'vlan_filter.bpf' failed
This patch fixes the issue by adding a include path setting the
architecture to the one of the builder.
Signed-off-by: Jesper Dangaard Brouer <netoptimizer@brouer.com>
Sidned-off-by: Eric Leblond <eric@regit.org>
The XDP CPU destination array/set, configured via xdp-cpu-redirect,
will always be fairly small. My different benchmarking showed that
the current modulo hashing into the CPU array can easily result in bad
distribution, expecially if the number of CPU is an even number.
This patch uses a proper hashing function on the input key. The key
used for hashing is inspired by the ippair hashing code in
src/tmqh-flow.c, and is based on the IP src + dst.
An important property is that the hashing is flow symmetric, meaning
that if the source and destintation gets swapped then the selected CPU
will remain the same. This is important for Suricate.
That hashing INITVAL (15485863 the 10^6th prime number) was fairly
arbitrary choosen, but experiments with kernel tree pktgen scripts
(pktgen_sample04_many_flows.sh +pktgen_sample05_flow_per_thread.sh)
showed this improved the distribution.
Signed-off-by: Jesper Dangaard Brouer <netoptimizer@brouer.com>
Adjusted function call API to take an initval. This allow the API
user to set the initial value, as a seed. This could also be used for
inputting the previous hash.
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
This patch adds a boolean option "xdp-cpu-redirect" to af-packet
interface configuration. If set, then the XDP filter will load
balance the skb creation on specified CPUs instead of doing the
creation on the CPU handling the packet. In the case of a card
with asymetric hashing this will allow to avoid saturating the
single CPU handling the trafic.
The XDP filter must contains a set of map allowing load balancing.
This is the case of xdp_filter.bpf.
Fixed-by: Jesper Dangaard Brouer <netoptimizer@brouer.com>
eBPF has a data type which is a per CPU array. By adding one element
to the array it is in fact added to all per CPU arrays in the kernel.
This allows to have a lockless structure in the kernel even when doing
counter update.
In userspace, we need to update the flow bypass code to fetch all
elements of the per CPU arrays.
This patch implements bypass capability for af-packet.
The filter only bypass TCP and UDP in IPv4 and IPv6. It don't
don't bypass IPv6 with extended headers.
This patch also introduces a bypassed flow manager that takes
care of timeouting the bypassed flows. It uses a 60 sec
timeout on flow. As they are supposed to be active we can
try that. If they are not active then we don't care to get them
back in Suricata.
This patch introduces the ebpf cluster mode. This mode is using
an extended BPF function that is loaded into the kernel and
provide the load balancing.
An example of cluster function is provided in the ebpf
subdirectory and provide ippair load balancing function.
This is a function which uses the same method as
the one used in autofp ippair to provide a symetrical
load balancing based on IP addresses.
A simple filter example allowing to drop IPv6 is added to the
source.
This patch also prepares the infrastructure to be able to load
and use map inside eBPF files. This will be used later for flow
bypass.