table of contents
|PFIL(9)||Kernel Developer's Manual||PFIL(9)|
pfil_wunlock — packet filter
typedef int (*pfil_func_t)(void *arg, struct mbuf **mp, struct ifnet *, int dir, struct inpcb);
pfil_head_register(struct pfil_head *head);
struct pfil_head *
af, u_long dlt);
struct pfil_head *);
struct pfil_head *);
pfil_head *head, struct
mbuf **mp, struct ifnet
*, int dir,
struct inpcb *);
pfil_head *, struct
pfil_head *, struct
pfil framework allows for a specified
function to be invoked for every incoming or outgoing packet for a
particular network I/O stream. These hooks may be used to implement a
firewall or perform packet transformations.
Packet filtering points are registered
Filtering points are identified by a key (void *) and
a data link type (int) in the
pfil_head structure. Packet filters use the key and
data link type to look up the filtering point with which they register
themselves. The key is unique to the filtering point. The data link type is
a bpf(4) DLT constant indicating what kind of header is
present on the packet at the filtering point. Each filtering point uses
common per-VNET rmlock by default. This can be changed by specifying
PFIL_FLAG_PRIVATE_LOCK as flags
field in the pfil_head structure. Note that specifying
private lock can break filters sharing the same ruleset and/or state between
different data link types. Filtering points may be unregistered with the
Packet filters register/unregister themselves
with a filtering point with the
functions, respectively. The head is looked up using the
function, which takes the key and data link type that the packet filter
expects. Filters may provide an argument to be passed to the filter when
invoked on a packet.
When a filter is invoked, the packet appears just as if it
“came off the wire”. That is, all protocol fields are in
network byte order. The filter is called with its specified argument, the
pointer to the pointer to the mbuf containing the
packet, the pointer to the network interface that the packet is traversing,
and the direction (
PFIL_OUT) that the packet is traveling. The filter
may change which mbuf the mbuf ** argument
references. The filter returns an error (errno) if the packet processing is
to stop, or 0 if the processing is to continue. If the packet processing is
to stop, it is the responsibility of the filter to free the packet.
Every filter hook is called with
pfil read lock held. All heads uses the same lock
within the same VNET instance. Packet filter can use this lock instead of
own locking model to improve performance. Since
require struct rm_priotracker to be passed as
argument. Filter can acquire and release writer lock via
functions. See rmlock(9) for more details.
Currently, filtering points are implemented for the following link types:
- IPv4 packets.
- IPv6 packets.
- Link-layer packets.
pfil_head_get() returns the
pfil_head structure for the given key/dlt. The
pfil_remove_hook() functions return 0 if successful.
If called with flag
pfil_remove_hook() is expected to always
pfil_head_unregister() function might
pfil interface first appeared in
NetBSD 1.3. The
and output lists were originally implemented as
LIST structures; however this was changed in
NetBSD 1.4 to
structures. This change was to allow the input and output filters to be
processed in reverse order, to allow the same path to be taken, in or out of
pfil interface was changed in 1.4T to
accept a 3rd parameter to both
pfil_remove_hook(), introducing the capability of
per-protocol filtering. This was done primarily in order to support
filtering of IPv6.
In 1.5K, the
pfil framework was changed to
work with an arbitrary number of filtering points, as well as be less
Fine-grained locking was added in FreeBSD
pfil lock export was added in
When a pfil_head is being modified, no
traffic is diverted (to avoid deadlock). This means that traffic may be
dropped unconditionally for a short period of time.
pfil_run_hooks() will return
ENOBUFS to indicate this.
|August 23, 2013||Debian|