| PFIL(9) | Kernel Developer's Manual | PFIL(9) | 
pfil, pfil_head_register,
  pfil_head_unregister,
  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>
int
  
  pfil_head_register(struct
    pfil_head *ph);
int
  
  pfil_head_unregister(struct
    pfil_head *ph);
struct pfil_head *
  
  pfil_head_get(int
    af, u_long
  dlt);
struct packet_filter_hook *
  
  pfil_hook_get(int
    dir, struct pfil_head
    *ph);
int
  
  pfil_add_hook(int
    (*func)(), void
    *arg, int flags,
    struct pfil_head
  *ph);
int
  
  pfil_remove_hook(int
    (*func)(), void
    *arg, int flags,
    struct pfil_head
  *ph);
int
  
  (*func)(void
    *arg, struct mbuf
    **mp, struct ifnet
    *, int dir);
int
  
  pfil_run_hooks(struct
    pfil_head *ph, struct
    mbuf **mp, struct ifnet
    *ifp, int dir);
int
  
  pfil_add_ihook(void
    (*ifunc)(), void
    *arg, int flags,
    struct pfil_head
  *ph);
int
  
  pfil_remove_ihook(void
    (*ifunc)(), void
    *arg, int flags,
    struct pfil_head
  *ph);
void
  
  (*ifunc)(void
    *arg, unsigned long
    cmd, void
  *ptr);
void
  
  pfil_run_addrhooks(struct
    pfil_head *ph, unsigned
    long, struct ifaddr
    *ifa);
void
  
  pfil_run_ifhooks(struct
    pfil_head *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 registered with
    pfil_head_register(). 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_type constant indicating
    what kind of header is present on the packet at the filtering point.
    Filtering points may be unregistered with the
    pfil_head_unregister() 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 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 (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 17, 2018 | NetBSD 9.3 |