bpfilter - BPF-Based Linux Packet Filtering Cheatsheet
bpfilter is a daemon that converts familiar firewall rules into optimized BPF programs. The long-standing problem it addresses: iptables has well-understood syntax but a performance ceiling from sequential rule evaluation, while raw eBPF/XDP is fast but requires writing and maintaining BPF code. bpfilter bridges them — you express rules in a familiar way, and it compiles them into efficient BPF attached at the right hook (including XDP, which processes packets before they enter the network stack).
Firewall changes can lock you out of a remote host. Test on a console-accessible system and keep a rollback path.
Requirements
- Modern Linux kernel with BPF support (6.4+ recommended)
- Root privileges (loads BPF programs)
libbpf available
Installation
| Method | How |
|---|
| From source | git clone https://github.com/facebook/bpfilter && make && sudo make install |
| Distro package | Available in some newer distributions |
| Start daemon | sudo bpfilter (or via systemd) |
| Verify | bpfilter --version |
Architecture
| Piece | Role |
|---|
bpfilter daemon | Receives rules, generates and loads BPF |
bfcli | Native CLI for expressing rules |
| iptables/nftables front end | Translate existing rules into bpfilter |
| BPF programs | The compiled filter attached to a hook |
Attach Hooks
| Hook | Where packets are processed |
|---|
| XDP | Earliest — in the driver, before the stack (fastest) |
| TC (traffic control) | After basic parsing, ingress/egress |
| cgroup | Per-cgroup socket filtering |
| Netfilter | Compatible placement in the classic path |
Choosing XDP gives the largest performance win, particularly for dropping unwanted traffic (DDoS mitigation), because rejected packets never traverse the stack.
Defining Rules with bfcli
# Conceptual ruleset: default drop, allow SSH and established traffic
sudo bfcli ruleset set --from-str '
chain BF_HOOK_XDP policy DROP
rule
ip4.proto tcp
tcp.dport 22
ACCEPT
rule
ip4.saddr 10.0.0.0/8
ACCEPT
'
| Command | Description |
|---|
bfcli ruleset set --from-file F | Load rules from a file |
bfcli ruleset get | Show the active ruleset |
bfcli ruleset flush | Remove all rules |
bfcli chain set | Manage a single chain |
Matchers
| Matcher | Matches |
|---|
ip4.saddr / ip4.daddr | Source/destination IPv4 (CIDR supported) |
ip6.saddr / ip6.daddr | IPv6 addresses |
ip4.proto | Protocol (tcp, udp, icmp) |
tcp.dport / tcp.sport | TCP ports |
udp.dport / udp.sport | UDP ports |
tcp.flags | TCP flag combinations |
meta.ifindex | Interface |
Verdicts
| Verdict | Effect |
|---|
ACCEPT | Allow the packet |
DROP | Discard silently |
CONTINUE | Fall through to the next rule |
Using Existing iptables Rules
bpfilter ships translation front ends so you can keep existing tooling:
# Point the iptables-compatible front end at bpfilter
sudo iptables-bpfilter -A INPUT -p tcp --dport 22 -j ACCEPT
This is the migration path: keep your rule syntax and management scripts, gain BPF execution underneath.
Verifying
| Check | Command |
|---|
| Active ruleset | sudo bfcli ruleset get |
| Loaded BPF programs | sudo bpftool prog list |
| Attached XDP | ip link show <iface> |
| Counters | Rule counters in bfcli ruleset get |
| Overhead | sudo bpftop to see program cost |
bpfilter vs Alternatives
| Aspect | bpfilter | iptables | nftables | raw XDP/eBPF |
|---|
| Performance | High (BPF/XDP) | Lower (sequential) | Better than iptables | Highest |
| Syntax | Familiar or bfcli | Familiar | Modern, unified | Write BPF code |
| Maturity | Newer | Very mature | Mature | Depends on you |
| Best for | BPF speed with familiar rules | Legacy compatibility | Modern netfilter | Custom datapaths |
Inspect its runtime cost with bpftop; compare with iptables for the classic path.
Resources