1.\" $NetBSD: pfil.9,v 1.22 2003/07/01 13:04:06 wiz Exp $ 2.\" 3.\" Copyright (c) 1996 Matthew R. Green 4.\" All rights reserved. 5.\" 6.\" Redistribution and use in source and binary forms, with or without 7.\" modification, are permitted provided that the following conditions 8.\" are met: 9.\" 1. Redistributions of source code must retain the above copyright 10.\" notice, this list of conditions and the following disclaimer. 11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" notice, this list of conditions and the following disclaimer in the 13.\" documentation and/or other materials provided with the distribution. 14.\" 3. The name of the author may not be used to endorse or promote products 15.\" derived from this software without specific prior written permission. 16.\" 17.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" SUCH DAMAGE. 28.\" 29.\" $FreeBSD$ 30.\" 31.Dd March 27, 2017 32.Dt PFIL 9 33.Os 34.Sh NAME 35.Nm pfil , 36.Nm pfil_head_register , 37.Nm pfil_head_unregister , 38.Nm pfil_head_get , 39.Nm pfil_add_hook , 40.Nm pfil_remove_hook , 41.Nm pfil_run_hooks , 42.Nm pfil_rlock , 43.Nm pfil_runlock , 44.Nm pfil_wlock , 45.Nm pfil_wunlock 46.Nd packet filter interface 47.Sh SYNOPSIS 48.In sys/param.h 49.In sys/mbuf.h 50.In net/if.h 51.In net/pfil.h 52.Bd -literal 53typedef int (*pfil_func_t)(void *arg, struct mbuf **mp, struct ifnet *, int dir, struct inpcb); 54.Ft int 55.Fn pfil_head_register "struct pfil_head *head" 56.Ft int 57.Fn pfil_head_unregister "struct pfil_head *head" 58.Ft "struct pfil_head *" 59.Fn pfil_head_get "int af" "u_long dlt" 60.Ft int 61.Fn pfil_add_hook "pfil_func_t" "void *arg" "int flags" "struct pfil_head *" 62.Ft int 63.Fn pfil_remove_hook "pfil_func_t" "void *arg" "int flags" "struct pfil_head *" 64.Ft int 65.Fn pfil_run_hooks "struct pfil_head *head" "struct mbuf **mp" "struct ifnet *" "int dir" "struct inpcb *" 66.Ft void 67.Fn pfil_rlock "struct pfil_head *" "struct rm_priotracker *" 68.Ft void 69.Fn pfil_runlock "struct pfil_head *" "struct rm_priotracker *" 70.Ft void 71.Fn pfil_wlock "struct pfil_head *" 72.Ft void 73.Fn pfil_wunlock "struct pfil_head *" 74.Ed 75.Sh DESCRIPTION 76The 77.Nm 78framework allows for a specified function to be invoked for every 79incoming or outgoing packet for a particular network I/O stream. 80These hooks may be used to implement a firewall or perform packet 81transformations. 82.Pp 83Packet filtering points are registered with 84.Fn pfil_head_register . 85Filtering points are identified by a key 86.Pq Vt "void *" 87and a data link type 88.Pq Vt int 89in the 90.Vt pfil_head 91structure. 92Packet filters use the key and data link type to look up the filtering 93point with which they register themselves. 94The key is unique to the filtering point. 95The data link type is a 96.Xr bpf 4 97DLT constant indicating what kind of header is present on the packet 98at the filtering point. 99Each filtering point uses common per-VNET rmlock by default. 100This can be changed by specifying 101.Vt PFIL_FLAG_PRIVATE_LOCK 102as 103.Vt "flags" 104field in the 105.Vt pfil_head 106structure. 107Note that specifying private lock can break filters sharing the same 108ruleset and/or state between different data link types. 109Filtering points may be unregistered with the 110.Fn pfil_head_unregister 111function. 112.Pp 113Packet filters register/unregister themselves with a filtering point 114with the 115.Fn pfil_add_hook 116and 117.Fn pfil_remove_hook 118functions, respectively. 119The head is looked up using the 120.Fn pfil_head_get 121function, which takes the key and data link type that the packet filter 122expects. 123Filters may provide an argument to be passed to the filter when 124invoked on a packet. 125.Pp 126When a filter is invoked, the packet appears just as if it 127.Dq came off the wire . 128That is, all protocol fields are in network byte order. 129The filter is called with its specified argument, the pointer to the 130pointer to the 131.Vt mbuf 132containing the packet, the pointer to the network 133interface that the packet is traversing, and the direction 134.Dv ( PFIL_IN 135or 136.Dv PFIL_OUT ) 137that the packet is traveling. 138The filter may change which mbuf the 139.Vt "mbuf\ **" 140argument references. 141The filter returns an error (errno) if the packet processing is to stop, or 0 142if the processing is to continue. 143If the packet processing is to stop, it is the responsibility of the 144filter to free the packet. 145.Pp 146Every filter hook is called with 147.Nm 148read lock held. 149All heads uses the same lock within the same VNET instance. 150Packet filter can use this lock instead of own locking model to 151improve performance. 152Since 153.Nm 154uses 155.Xr rmlock 9 156.Fn pfil_rlock 157and 158.Fn pfil_runlock 159require 160.Va struct rm_priotracker 161to be passed as argument. 162Filter can acquire and release writer lock via 163.Fn pfil_wlock 164and 165.Fn pfil_wunlock 166functions. 167See 168.Xr rmlock 9 169for more details. 170.Sh FILTERING POINTS 171Currently, filtering points are implemented for the following link types: 172.Pp 173.Bl -tag -width "AF_INET6" -offset XXX -compact 174.It AF_INET 175IPv4 packets. 176.It AF_INET6 177IPv6 packets. 178.It AF_LINK 179Link-layer packets. 180.El 181.Sh RETURN VALUES 182If successful, 183.Fn pfil_head_get 184returns the 185.Vt pfil_head 186structure for the given key/dlt. 187The 188.Fn pfil_add_hook 189and 190.Fn pfil_remove_hook 191functions 192return 0 if successful. 193If called with flag 194.Dv PFIL_WAITOK , 195.Fn pfil_remove_hook 196is expected to always succeed. 197.Pp 198The 199.Fn pfil_head_unregister 200function 201might sleep! 202.Sh SEE ALSO 203.Xr bpf 4 , 204.Xr if_bridge 4 , 205.Xr rmlock 9 206.Sh HISTORY 207The 208.Nm 209interface first appeared in 210.Nx 1.3 . 211The 212.Nm 213input and output lists were originally implemented as 214.In sys/queue.h 215.Dv LIST 216structures; 217however this was changed in 218.Nx 1.4 219to 220.Dv TAILQ 221structures. 222This change was to allow the input and output filters to be processed in 223reverse order, to allow the same path to be taken, in or out of the kernel. 224.Pp 225The 226.Nm 227interface was changed in 1.4T to accept a 3rd parameter to both 228.Fn pfil_add_hook 229and 230.Fn pfil_remove_hook , 231introducing the capability of per-protocol filtering. 232This was done primarily in order to support filtering of IPv6. 233.Pp 234In 1.5K, the 235.Nm 236framework was changed to work with an arbitrary number of filtering points, 237as well as be less IP-centric. 238.Pp 239Fine-grained locking was added in 240.Fx 5.2 . 241.Nm 242lock export was added in 243.Fx 10.0 . 244.Sh BUGS 245When a 246.Vt pfil_head 247is being modified, no traffic is diverted 248(to avoid deadlock). 249This means that traffic may be dropped unconditionally for a short period 250of time. 251.Fn pfil_run_hooks 252will return 253.Er ENOBUFS 254to indicate this. 255