admin-plugins author calendar category facebook post rss search twitter star star-half star-empty

Tidy Repo

The best & most reliable WordPress plugins

BPF Filter: Berkeley Packet Filter vs eBPF and Network Filtering Alternatives

BPF Filter: Berkeley Packet Filter vs eBPF and Network Filtering Alternatives

Ethan Martinez

September 18, 2026

Blog

Use classic BPF for simple packet capture filters, and use eBPF when you need programmable filtering inside the Linux kernel without writing a kernel module. That is the practical split. Berkeley Packet Filter is the small, sharp tool behind commands like tcpdump. eBPF is the wider platform used for observability, firewalling, load balancing, tracing, and high-speed packet decisions.

TLDR: Classic BPF is best for capture rules such as tcp port 443 and host 10.0.0.5, while eBPF is better for policy, telemetry, and fast packet handling at scale. A small SaaS team might use BPF to debug one noisy customer connection, then use eBPF to drop abusive traffic before it reaches NGINX. In real systems, XDP-based eBPF filtering can cut unwanted packets near the driver layer, often reducing CPU use by 30% or more during floods. If you only need a firewall rule, though, nftables may be simpler and less annoying to operate.

What “BPF filter” usually means

The phrase BPF filter can mean two different things, and that causes confusion. In older networking tools, it usually means a classic Berkeley Packet Filter expression. You type a compact rule, and the packet capture tool compiles it into bytecode.

For example:

tcpdump -i eth0 'tcp port 443 and src net 192.168.1.0/24'

This filter says: capture TCP packets on port 443 from that subnet. It is readable, quick, and widely supported. Security teams, network engineers, and developers use it because it works almost everywhere.

Classic BPF, often called cBPF, was designed to avoid copying every packet from kernel space to user space. Instead, the kernel checks the packet first. Only matching packets are passed to the capture program. That saves time and memory, especially on busy links.

Where Berkeley Packet Filter shines

Classic BPF is still excellent for packet capture. It is small, predictable, and easy to paste into a terminal at 2 a.m. when production is misbehaving.

  • Debugging TLS traffic: Capture only port 443 traffic from one host.
  • Investigating DNS issues: Filter for UDP port 53.
  • Finding noisy clients: Capture traffic from a suspect subnet.
  • Reducing capture size: Save only packets that matter.

It drives me crazy when packet captures balloon into multi-gigabyte files just because someone forgot a filter. A tight BPF expression can turn a messy 12 GB capture into a 300 MB file that opens quickly in Wireshark.

But classic BPF has a narrow job. It inspects packets and decides whether they should be accepted by the capture path. It is not meant to run rich programs, maintain complex state, or power modern observability stacks.

What eBPF changed

eBPF stands for extended Berkeley Packet Filter. The name sounds like a minor upgrade. It is not. eBPF turned a packet filtering idea into a general kernel execution engine.

With eBPF, small programs can run safely in selected kernel hooks. These hooks exist in networking, tracing, security, and scheduling. For networking, eBPF programs can run at several points, including sockets, traffic control, and XDP.

XDP, or Express Data Path, is one of the fastest options. It runs very early, often before the kernel builds a full network stack object for the packet. That makes it useful for denial-of-service mitigation, early packet drops, and simple load balancing.

The safety story matters. eBPF programs are checked by a verifier before loading. The verifier rejects unsafe code, such as programs with invalid memory access or unbounded loops. This is why eBPF can run in the kernel without the usual danger of loading a custom kernel module.

Berkeley Packet Filter vs eBPF

The two tools share roots, but they serve different needs.

Feature Classic BPF eBPF
Main use Packet capture filtering Kernel networking, tracing, security, observability
Complexity Low Medium to high
State handling Very limited Maps, counters, connection data, shared state
Performance role Reduces capture overhead Can process or drop packets very early
Typical tools tcpdump, libpcap, Wireshark Cilium, bcc, bpftrace, Katran, custom loaders

Classic BPF answers, “Should this packet be captured?” eBPF can answer, “Should this packet be dropped, redirected, counted, traced, rate limited, or passed to a service?”

When eBPF is the better choice

Use eBPF when packet filtering is only part of the job. It fits cases where you need speed, programmable logic, and kernel-level visibility.

  • DDoS filtering: Drop bad packets near the network driver with XDP.
  • Kubernetes networking: Enforce service policy without relying only on iptables chains.
  • Load balancing: Forward traffic with less overhead than some user-space paths.
  • Security monitoring: Detect suspicious connections and process activity together.
  • Latency analysis: Count drops, retransmits, and queue delays close to the source.

The catch is that eBPF tooling can feel rough. Kernel versions matter. Verifier errors can be cryptic. A program that loads fine on one distribution may fail on another because helper functions or map types differ. Expect to waste time on small compatibility problems, especially if the fleet is old or mixed.

Network filtering alternatives

eBPF is powerful, but it is not the right answer for every filtering problem. Sometimes the boring tool is the better tool.

nftables

nftables is the modern Linux packet filtering framework. It replaced much of the old iptables, ip6tables, arptables, and ebtables stack. For standard firewalling, NAT, port blocking, and rule sets, nftables is often the best first pick.

It is easier to audit than custom eBPF code. It also has strong distribution support. If your goal is “block this subnet” or “allow only these ports,” start here.

iptables

iptables is older but still common. Many scripts, appliances, and legacy systems depend on it. It can still do useful work, but large rule chains can become slow and painful to manage. On Kubernetes nodes, massive iptables rule sets have been a source of real latency and debugging pain.

tc filters

tc, the Linux traffic control system, can classify, shape, police, and redirect traffic. It can also attach eBPF programs. This makes it useful for bandwidth control and advanced packet handling after a packet has entered the kernel networking stack.

DPDK

DPDK moves packet processing into user space for very high throughput. It is common in telecom, virtual routers, and packet appliances. The trade-off is complexity. You often dedicate CPU cores and bypass parts of the normal kernel network stack.

Hardware ACLs and smart NICs

For very large networks, filtering can happen in switches, routers, or smart NICs. Hardware ACLs can drop traffic before it reaches the server. This is fast and efficient, but less flexible than software. Rule limits and vendor quirks can bite hard.

How to choose

Pick based on the job, not the hype.

  • Need a packet capture? Use classic BPF with tcpdump or Wireshark.
  • Need normal firewall rules? Use nftables.
  • Need Kubernetes network policy at scale? Consider an eBPF-based CNI such as Cilium.
  • Need early packet drops under attack? Look at XDP with eBPF.
  • Need carrier-grade packet processing? Consider DPDK or hardware offload.

A practical stack often uses several of these. A team may use nftables for baseline firewall rules, eBPF for service-aware filtering, and classic BPF for incident packet captures. That mix is normal. Clean separation avoids turning one tool into a tangled mess.

Final take

Berkeley Packet Filter is still the cleanest way to capture only the packets you care about. eBPF is a strong choice when filtering needs logic, speed, state, and deep Linux integration. Alternatives like nftables, tc, DPDK, and hardware ACLs are not obsolete. They solve different problems.

The smartest move is simple: use the smallest tool that solves the problem. Classic BPF for captures. nftables for common firewalling. eBPF when kernel-level programmability will truly pay off.