Berkeley Packet Filter

The Berkeley Packet Filter (BPF) provides on some Unix-like systems a raw interface to data link layers, permitting raw link-layer packets to be sent and received. In addition, if the driver for the network interface supports promiscuous mode, it allows the interface to be put into that mode so that all packets on the network can be received, even those destined to other hosts.

In addition, it supports "filtering" packets, so that only "interesting" packets will be supplied to the software using BPF; this can avoid copying "uninteresting" packets from the operating system kernel to software running in user mode, reducing the CPU requirement to capture packets and the buffer space required to avoid dropping packets.

Overview

BPF's filtering capabilities are implemented as an interpreter for a machine language for the BPF virtual machine; programs in that language can fetch data from the packet, perform arithmetic operations on data from the packet, and compare the results against constants or against data in the packet or test bits in the results, accepting or rejecting the packet based on the results of those tests. On some platforms, including FreeBSD and WinPcap, just-in-time compilation is used to convert virtual machine instructions into native code in order to further avoid overhead.

Kernel-mode interpreters for that same virtual machine language are used in raw data link layer mechanisms in other operating systems, such as Tru64 Unix, and for socket filters in the Linux kernel and in the WinPcap packet capture mechanism. Since version 3.18 of the Linux kernel mainline, possibilities of its embedded BPF virtual machine, referred to as extended BPF or eBPF for short, are extended to allow its use with non-networking parts of the kernel, such as by attaching eBPF programs to various tracepoints,[1][2][3] and since kernel version 3.19, to sockets.[4][5] When used with sockets, once the BPF program is loaded, it will be run on every packet that shows up on the given socket. This allows to launch programs that process traffic showing up on a socket, thus opening up the capability to implement traffic processing applications as the traffic is received. These traffic applications can be serialized, thus enabling the implementation of complex networking applications.

Another significant addition in the latest set of kernel patches set in kernel version 3.19 is the addition of "maps." A map is a simple key/value data store that can be shared between user space and BPF scripts and is persistent within the kernel. This allows for BPF programs to rely on these key/value pairs for storage in userspace of tables that can be used, for example, for networking applications.

A user-mode interpreter for it is provided with the libpcap/WinPcap implementation of the pcap application programming interface (API), so that, when capturing packets on systems without kernel-mode support for that filtering mechanism, packets can be filtered in user mode; code using the pcap API will work on both types of systems, although, on systems where the filtering is done in user mode, all packets, including those that will be filtered out, are copied from the kernel to user space. That interpreter can also be used when reading a file containing packets captured using pcap.

BPF is sometimes used to refer just to the filtering mechanism, rather than to the entire interface.

BSD kernels implement routines such as bpf_mtap() and bpf_tap(), with some wrapping them in macros such as BPF_MTAP() and BPF_TAP(), which are called by network interface drivers (and pseudo-drivers) to deliver incoming and outgoing packets to the BPF mechanism.

History

The original paper was written by Steven McCanne and Van Jacobson in 1992 while at Lawrence Berkeley Laboratory[6][7]

In August 2003, SCO Group publicly claimed that the Linux kernel was infringing Unix code which they owned. Programmers quickly discovered the code in question was the Berkeley Packet Filter. Clearly, SCO never owned the BPF code; however, SCO has not explained or acknowledged the mistake, although the ongoing legal action may eventually force an answer.

In 2007, Robert Watson and Christian Peron added zero-copy buffer extensions to the BPF implementation in the FreeBSD operating system,[8] allowing kernel packet capture in the device driver interrupt handler to write directly to user process memory in order to avoid the requirement for two copies for all packet data received via the BPF device. While one copy remains in the receipt path for user processes, this preserves the independence of different BPF device consumers, as well as allowing the packing of headers into the BPF buffer rather than copying complete packet data.[9]

Around the 3.0 kernel release, other features such as a JIT (just-in-time) compiler (allowing for real-time updates of the filters and associated actions over a running system) were added. Recently in versions 3.15 (June 2014) - 3.19 (Feb 2015), the Linux kernel’s BPF subsystem has received a major overhaul which drastically expands its applicability, adding a number of capabilities and performance improvements. BPF is now available for direct use from user space, and BPF programs can be attached to sockets and rely on userspace key/value stores called "maps".

See also

References

  1. "Linux kernel 3.18, Section 1.3. bpf() syscall for eBFP virtual machine programs". kernelnewbies.org. December 7, 2014. Retrieved January 19, 2015.
  2. Jonathan Corbet (September 24, 2014). "The BPF system call API, version 14". LWN.net. Retrieved January 19, 2015.
  3. Jonathan Corbet (July 2, 2014). "Extending extended BPF". LWN.net. Retrieved January 19, 2015.
  4. "Linux kernel 3.19, Section 11. Networking". kernelnewbies.org. February 8, 2015. Retrieved February 13, 2015.
  5. Jonathan Corbet (December 10, 2014). "Attaching eBPF programs to sockets". LWN.net. Retrieved February 13, 2015.
  6. McCanne, Steven; Jacobson, Van (1992-12-19). "The BSD Packet Filter: A New Architecture for User-level Packet Capture" (PDF).
  7. McCanne, Steven; Jacobson, Van (January 1993). "The BSD Packet Filter: A New Architecture for User-level Packet Capture". USENIX.
  8. "bpf(4) Berkeley Packet Filter". FreeBSD. 2010-06-15.
  9. Watson, Robert N. M.; Peron, Christian S. J. (2007-03-09). "Zero-Copy BPF" (PDF).

External links