The current eBPF code tries to parse the beginning of the DNS payload
to extract the qname for all UDP datagrams, which is not course
not working correctly for QUIC packets. I don't immediately see a way
to identify QUIC packets from our eBPF code, so for now this commit
disables the eBPF filtering feature on QUIC sockets.
}
#ifdef HAVE_EBPF
- if (g_defaultBPFFilter && !g_defaultBPFFilter->isExternal()) {
+ /* for now eBPF filtering is not enabled on QUIC sockets because the eBPF code tries
+ to parse the QNAME from the payload for all UDP datagrams, which obviously does not
+ work well for these. */
+ if (!isQUIC && g_defaultBPFFilter && !g_defaultBPFFilter->isExternal()) {
clientState.attachFilter(g_defaultBPFFilter, socket);
vinfolog("Attaching default BPF Filter to %s frontend %s", (!tcp ? std::string("UDP") : std::string("TCP")), addr.toStringWithPort());
}
.. note::
In addition to keeping the correct capability, large maps might require an increase of ``RLIMIT_MEMLOCK``, as mentioned below.
+.. warning::
+ As of 1.9.7, eBPF filtering is not supported for QUIC-based protocols, including DNS over QUIC and DNS over HTTP/3.
+
This feature allows dnsdist to ask the kernel to discard incoming packets in kernel-space instead of them being copied to userspace just to be dropped, thus being a lot of faster. The current implementation supports dropping UDP and TCP queries based on the source IP and UDP datagrams on exact DNS names. We have not been able to implement suffix matching yet, due to a limit on the maximum number of EBPF instructions.
The following figure show the CPU usage of dropping around 20k qps of traffic, first in userspace (34 to 36) then in kernel space with eBPF (37 to 39). The spikes are caused because the drops are triggered by dynamic rules, so the first spike is the abuse traffic before a rule is automatically inserted, and the second spike is because the rule expires automatically after 60s before being inserted again.