Project Home
Project Home
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
wiki1656: Filtering_wiki_page (Version 7)

Packet Filtering, Traffic Shaping and Firewalling#

(Derived from the NetBSD Documentation)

Packet Filters#

In principle there are two pseudo devices involved with packet filtering. pf is involved in filtering network traffic and bpf is an interface to capture and access raw network traffic. These be discussed briefly from the point of view of their attachment to rest of the stack.

pf is implemented using pfil hooks, while bpf is implemented as a tap in all the network drivers.

Packet Filter Interface#

pfil is a purely in-stack interface to support packet filtering hooks. Packet filters can register hooks which should be called when packet processing taken place; in it's essence pfil is a list of callbacks for certain events. In addition to being able to register a filter for incoming and outgoing packets, pfil provides support for interface attach/detach and address change notifications. pfil is described on the pfil(9) manual page and is used Packet Filter (pf) to hook to the packet stream for implementing firewalls and NAT.

pf#

pf, found in sys/dist/pf/net, provides roughly the same functionality as ipfilter. Its operation is also very similar. Some relevant manual pages describing pf are pf(4), pf.conf(5) and pfctl(8).

pf is started using the tool pfctl, which issues a DIOCSTART ioctl. This causes pf to call pf_pfil_attach, which runs the necessary pfil attachment routines. The key routines after this are pf_test and pf_test6, which are called for IPv4 and IPv6 packets, respectively, to test and see if the packets should be allowed to be sent, received or dropped. The packet filter hooks, and therefore the whole of pf, are disabled with the DIOCSTOP ioctl, usually issued with pfctl.

Berkeley Packet Filter#

The Berkeley Packet Filter (BPF) (sys/net/bpf.c) provides link layer access to data available on the network through interfaces attached to the system. BPF is used by opening a device node, /dev/bpf and issuing ioctl's to control the operation of the device. A popular example of a tool using BPF is tcpdump.

The device /dev/bpf is a cloning device, meaning it can be opened multiple times. It is in principle similar to a cloning interface, except BPF provides no network interface, only a method to open the same device multiple times.

To capture network traffic, a BPF device must be attached to an interface. The traffic on this interface is then passed to BPF for evaluation. For attaching an interface to an open BPF device, the ioctl BIOCSETIF is used. The interface is identified by passing a struct ifreq, which contains the interface name in ASCII encoding. This is used to find the interface from the kernel tables. BPF registers itself to the interfaces struct ifnet field if_bpf to inform the system that it is interested about traffic on this particular interface. The listener can also pass a set of filtering rules to capture only certain packets, for example ones matching a given host and port combination.

BPF captures packets by supplying a tapping interface, bpf_tap-functions, to link layer drivers and relying on the drivers to always pass packets to it. Drivers honor this request and commonly have code which, along both the input and output paths, does:

#if NBPFILTER > 0
	if (ifp->if_bpf)
		bpf_mtap(ifp->if_bpf, m0);
#endif

This passes the mbuf to the BPF for inspection. BPF inspects the data and decides is anyone listening to this particular interface is interested in it. The filter inspecting the data is highly optimized to minimize time spent inspecting each packet. If the filter matches, the packet is copied to await being read from the device.

The BPF tapping feature looks very much like the interfaces provided by pfil, so a valid question is are both required? Even though they provide similar services, their functionality is disjoint. The BPF mtap wants to access packets right off the wire without any alteration and possibly copy it for further use. Callers linking into pfil want to modify and possibly drop packets. The "pfil" interface is more analgous to io-net's filter interface.

For those of you currently using something like the "nfm-nraw" interface in io-net, BPF provides the equivalent functionality, with some extra complexity involved in setting things up, but with much more versatility in configuration. A good description of what the BPF instruction set and examples can be found here.

PF and Traffic Shaping#

PF and Firewalling#