The BSD Packet Filter: A New Architecture for User-level Packet Capture

S. McCanne and V. Jacobson (LBL), 1993

Summary. The authors present a new packet filter that uses a novel register-based filter mechanism more suited to modern RISC architectures and a buffer model that allows filtering before copying to save time in the common case.


The paper uses the popular (at that time) CMU/Stanford Packet Filter (CSPF) -- an adaptation of the Xerox Alto packet filter to a Unix kernel completed in 1980 -- for comparitive purposes.

Packet filters consist of

  1. network tap/buffer model
  2. packet filter

Because there are only a few microseconds between packet arrivals, there is not time to do a read() system call for each packet. Rather, the tap must copy the data into a buffer where the application can read it some time later.

Performance issues. "Assuming one uses reasonable care in the design of the buffering model [not STREAMS], it will be the dominant cost of packets you accept while the packet filter computation will be the dominant cost of packets you reject. Since most applications of packet capture reject far more packets than they accept...good performance of the packet filter is critical to good overall performance." Is this still the case in switched networks?

Buffer model. BPF filters packets before copying. CSPF has to copy because the filter is a STREAM module and (apparently) the data has to be copied to a STREAM buffer before it can be manipulated by the filter STREAM module. (At least one copy is necessary if the packet matches the filter because packets must be copied across the user-kernel boundary.) This saves a tremendous amount of time in the common case -- when a packet doesn't match the filter predicate -- because needless copying is avoided.

The authors show two graphs for mean overhead per packet by packet size. One graph shows the case where all packets are accepted; the other all packets rejected. When all packets are accepted (and therefore must be copied so the bad buffer model doesn't make as much difference, CSPF shows about a 85usec overhead which increases with packet size due to misaligned bcopy() copying. BFP takes care to do aligned copies.) The second graph shows the overhead caused by CSPF's mandatory copying; CSPF's overhead grows (starting at 136usec) with packet size even when the packet is rejected whereas BPF's remainsc constant at about 4.6us.

Filter model.There exists a mismatch between CSPF and present-day (1993) architectures. CSPF was designed for use on a pdp-11 which had stack hardware and, therefore, used a tree computational model which is evaluated using a stack algorithm. On machines with no stack hardware, the stack must be simulated requiring the following:

Further, the tree model does redundant computations whereas in the BPF representation (see below), it is always possible to reorder the graph such that at most one packet header parse is done for any layer.

BPF uses a Control Flow Graph (CFG) model which is more suitable for register-based architectures. The authors created a pseudo machine and an accompanying code optimizer. Although the tree and CFG models are computationally equivalent, the CFG can be executed much more efficiently on modern RISC, register-based machines.

Applications. Arpwatch watches the use of a single IP address by more than one physical host. Netload graphs real time network stats on X display. Several others.


Note: These is a humorous footnote regarding the choice of an efficient buffer model: As opposed to, for example, the AT&T STREAMS buffer model used by NIT which has enough options to be Turing complete but appears to be a poor match to any practical problem.