FFPF comes with a few constructs to build complex graphs out of
individual filters. While the constructs can be used by means of a
library, they are also supported by a simple command-line tool called
ffpf-flow
. For example, pronouncing the construct `->
'
as 'connects to' and '|
' as 'in parallel with', the command
below captures two different flows:
./ffpf-flow \ "(device,eth0) | (device,eth1) -> (sampler,2,4) -> (FPL-2,"...") | (BPF,"...") -> (bytecount,,8)" "(device, eth0) -> (sampler,2,4) ->(BPF,"...") -> (packetcount,,8)"
The top flow specification indicates that the grabber should capture
packets from devices eth0
and eth1
, and pass them to a
sampler that captures one in two packets and requires four bytes of
. Next, sampled packets are sent both to an FPL-2 filter and to a
BPF filter. These filters execute user-specified filter expressions
(indicated by `'), and in this example require no
. All
packets that pass these filters are sent to a bytecount `filter'
which stores the byte count statistic in in
in an eight byte
counter. The counter can be read directly from userspace, while the
packets themselves are not passed to the monitoring application. The
second flow has a prefic of two `filters' in common with the first
expression (devices are treated as filters in FFPF), but now the
packets are forwarded to a different BPF filter, and from there to a
packet counter.
As a by-product, FFPF generates a graphical representation of the entire filter-graph. A graph for the two flows above is shown in Figure 3. For illustration purposes, the graph shows few details. We just show (a) the configuration of the filter graph as instantiated by the users (the ovals at the top of the figure), (b) the filter instantiations to which each of the component filters corresponds (circles), and (c) the filter classes upon which each of the instantiations is based (squares). Note that there is only one instantiation of the sampler, even though it is used in two different flows. On the other hand, there are two instantiations of the BPF filter class. The reason is that the filter expressions in the two flows are different.
The ability to load and interconnect high-speed packet handlers in the kernel was also explored by Wallach et al., with an eye on integrating layer processing and reducing copying [33]. Similarly, Click allows programmers to load packet processing functions consisting of a configuration of simple elements that push (pull) data to (from) each other [28]. The same model was used in the Corral, but with support for third parties that may add and remove elements at runtime [9]. The filter concatenation and support for a hierarchy that includes IXP1200s resembles paths in the Scout project [4]. Scout was not designed for monitoring per se and, hence, does not directly provide some of FFPF's features such as new languages or flow groups. Mono-lingual kernel-programming projects that also do not support these features include FLAME [1] and our own Open Kernel Environment [7]) which provide high speed processing by loading native code (compiled Cyclone) in the kernel.