| PFIL(9) | Kernel Developer's Manual | PFIL(9) | 
pfil, pfil_head_create,
  pfil_head_destroy,
  pfil_head_get, pfil_hook_get,
  pfil_add_hook,
  pfil_remove_hook,
  pfil_run_hooks,
  pfil_add_ihook,
  pfil_remove_ihook,
  pfil_run_addrhooks,
  pfil_run_ifhooks —
#include <sys/param.h>
#include <sys/mbuf.h>
#include <net/if.h>
#include <net/pfil.h>
pfil_head_t *
  
  pfil_head_create(int
    type, void
  *key);
int
  
  pfil_head_destroy(pfil_head_t
    *ph);
pfil_head_t *
  
  pfil_head_get(int
    type, void
  *key);
struct packet_filter_hook *
  
  pfil_hook_get(int
    dir, pfil_head_t
    *ph);
int
  
  pfil_add_hook(pfil_func_t
    func, void *arg,
    int flags,
    pfil_head_t *ph);
int
  
  pfil_remove_hook(pfil_func_t
    func, void *arg,
    int flags,
    pfil_head_t *ph);
int
  
  (*func)(void
    *arg, struct mbuf
    **mp, struct ifnet
    *, int dir);
int
  
  pfil_run_hooks(pfil_head_t
    *ph, struct mbuf
    **mp, struct ifnet
    *ifp, int dir);
int
  
  pfil_add_ihook(pfil_ifunc_t
    ifunc, void *arg,
    int flags,
    pfil_head_t *ph);
int
  
  pfil_remove_ihook(pfil_ifunc_t
    ifunc, void *arg,
    int flags,
    pfil_head_t *ph);
void
  
  (*ifunc)(void
    *arg, unsigned long
    cmd, void
  *ptr);
void
  
  pfil_run_addrhooks(pfil_head_t
    *ph, unsigned long,
    struct ifaddr *ifa);
void
  
  pfil_run_ifhooks(pfil_head_t
    *ph, unsigned long,
    struct ifnet *ifp);
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 created with
    pfil_head_create(). Filtering points are identified
    by a data link (int) type and a
    (void *) key. If a packet
    filtering point already exists for that data link type
    and key then the
    pfil_head_create() function returns
    NULL. Packet filters use the
    pfil_head_get() function specifying the data link
    type and the key 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_type constant indicating
    what kind of header is present on the packet at the filtering point.
    Filtering points may be destroyed with the
    pfil_head_destroy() function.
Packet filters register/unregister themselves with a filtering
    point with the pfil_add_hook() and
    pfil_remove_hook() functions, respectively. The head
    is looked up using the pfil_head_get() function,
    which takes the data link type and the
    key 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 (either
    PFIL_IN or PFIL_OUT, see
    also below) that the packet is traveling. The filter may change which mbuf
    the mbuf ** argument references. The filter returns an
    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.
The flags parameter, used in the
    pfil_add_hook() and
    pfil_remove_hook() functions, indicates when the
    filter should be called. The flags are:
By the same token, event handlers register/unregister themselves
    with the pfil_add_ihook() and
    pfil_remove_ihook() functions, respectively. The
    event handler is called with its specified argument, the event id (either
    PFIL_IFNET_ATTACH or
    PFIL_IFNET_DETACH, see also below) or ioctl number,
    and the pointer to the network interface or the pointer to the ifaddr.
The flags parameter, used in the
    pfil_add_ihook() and
    pfil_remove_ihook() functions, indicates when the
    filter should be called. The flags are:
PFIL_IFADDRPFIL_IFNETPFIL_IFNET_ATTACH or
      PFIL_IFNET_DETACH)pfil interface first appeared in
  NetBSD 1.3. The pfil input and
  output lists were originally implemented as
  <sys/queue.h>
  LIST structures; however this was changed in
  NetBSD 1.4 to TAILQ
  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
  the kernel.
The pfil interface was changed in 1.4T to
    accept a 3rd parameter to both pfil_add_hook() and
    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
    IP-centric.
pfil_add_ihook() and
    pfil_remove_ihook() were added in
    NetBSD 8.0.
pfil interface was designed and implemented by
  Matthew R. Green, with help from
  Darren Reed, Jason R. Thorpe,
  and Charles M. Hannum. Darren
  Reed added support for IPv6 in addition to IPv4. Jason
  R. Thorpe added support for multiple hooks and other clean up.
pfil implementation will need changes to
  suit a threaded kernel model.
| January 15, 2022 | NetBSD 10.0 |