1.\" $NetBSD: pfil.9,v 1.40 2022/01/15 17:54:01 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.\" 15.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25.\" SUCH DAMAGE. 26.\" 27.Dd January 15, 2022 28.Dt PFIL 9 29.Os 30.Sh NAME 31.Nm pfil , 32.Nm pfil_head_create , 33.Nm pfil_head_destroy , 34.Nm pfil_head_get , 35.Nm pfil_hook_get , 36.Nm pfil_add_hook , 37.Nm pfil_remove_hook , 38.Nm pfil_run_hooks , 39.Nm pfil_add_ihook , 40.Nm pfil_remove_ihook , 41.Nm pfil_run_addrhooks , 42.Nm pfil_run_ifhooks 43.Nd packet filter interface 44.Sh SYNOPSIS 45.In sys/param.h 46.In sys/mbuf.h 47.In net/if.h 48.In net/pfil.h 49.Ft pfil_head_t * 50.Fn pfil_head_create "int type" "void *key" 51.Ft int 52.Fn pfil_head_destroy "pfil_head_t *ph" 53.Ft pfil_head_t * 54.Fn pfil_head_get "int type" "void *key" 55.Ft struct packet_filter_hook * 56.Fn pfil_hook_get "int dir" "pfil_head_t *ph" 57.Ft int 58.Fn pfil_add_hook "pfil_func_t func" "void *arg" "int flags" "pfil_head_t *ph" 59.Ft int 60.Fn pfil_remove_hook "pfil_func_t func" "void *arg" "int flags" "pfil_head_t *ph" 61.Ft int 62.Fn (*func) "void *arg" "struct mbuf **mp" "struct ifnet *" "int dir" 63.Ft int 64.Fn pfil_run_hooks "pfil_head_t *ph" "struct mbuf **mp" "struct ifnet *ifp" "int dir" 65.Ft int 66.Fn pfil_add_ihook "pfil_ifunc_t ifunc" "void *arg" "int flags" "pfil_head_t *ph" 67.Ft int 68.Fn pfil_remove_ihook "pfil_ifunc_t ifunc" "void *arg" "int flags" "pfil_head_t *ph" 69.Ft void 70.Fn (*ifunc) "void *arg" "unsigned long cmd" "void *ptr" 71.Ft void 72.Fn pfil_run_addrhooks "pfil_head_t *ph" "unsigned long" "struct ifaddr *ifa" 73.Ft void 74.Fn pfil_run_ifhooks "pfil_head_t *ph" "unsigned long" "struct ifnet *ifp" 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 created with 84.Fn pfil_head_create . 85Filtering points are identified by a 86data link 87.Vt ( int ) 88.Fa type 89and a 90.Vt ( void * ) 91.Fa key . 92If a packet filtering point already exists for that data link 93.Fa type 94and 95.Fa key 96then the 97.Fn pfil_head_create 98function returns 99.Dv NULL . 100Packet filters use the 101.Fn pfil_head_get 102function specifying the data link 103.Fa type 104and the 105.Fa key 106to look up the filtering point with which they register themselves. 107The 108.Fa key 109is unique to the filtering point. 110The data link 111.Fa type 112is a 113.Xr bpf 4 114.Dv DLT_ Ns Ar type 115constant indicating what kind of header is present on the packet 116at the filtering point. 117Filtering points may be destroyed with the 118.Fn pfil_head_destroy 119function. 120.Pp 121Packet filters register/unregister themselves with a filtering point 122with the 123.Fn pfil_add_hook 124and 125.Fn pfil_remove_hook 126functions, respectively. 127The head is looked up using the 128.Fn pfil_head_get 129function, which takes the data link 130.Fa type 131and the 132.Fa key 133that the packet filter expects. 134Filters may provide an argument to be passed to the filter when 135invoked on a packet. 136.Pp 137When a filter is invoked, the packet appears just as if it 138.Dq came off the wire . 139That is, all protocol fields are in network byte order. 140The filter is called with its specified argument, the pointer to the 141pointer to the mbuf containing the packet, the pointer to the network 142interface that the packet is traversing, and the direction (either 143.Dv PFIL_IN 144or 145.Dv PFIL_OUT , 146see also below) that the packet is traveling. 147The filter may change which mbuf the 148.Vt "mbuf **" 149argument references. 150The filter returns an errno if the packet processing is to stop, or 0 151if the processing is to continue. 152If the packet processing is to stop, it is the responsibility of the 153filter to free the packet. 154.Pp 155The 156.Fa flags 157parameter, used in the 158.Fn pfil_add_hook 159and 160.Fn pfil_remove_hook 161functions, indicates when the filter should be called. 162The flags are: 163.Pp 164.Bl -tag -offset indent -width ".Dv PFIL_ALL" -compact 165.It Dv PFIL_IN 166call me on incoming packets 167.It Dv PFIL_OUT 168call me on outgoing packets 169.It Dv PFIL_ALL 170call me on all of the above 171.El 172.Pp 173By the same token, event handlers register/unregister themselves 174with the 175.Fn pfil_add_ihook 176and 177.Fn pfil_remove_ihook 178functions, respectively. 179The event handler is called with its specified argument, the event id 180(either 181.Dv PFIL_IFNET_ATTACH 182or 183.Dv PFIL_IFNET_DETACH , 184see also below) or ioctl number, and the pointer 185to the network interface or the pointer to the ifaddr. 186.Pp 187The 188.Fa flags 189parameter, used in the 190.Fn pfil_add_ihook 191and 192.Fn pfil_remove_ihook 193functions, indicates when the filter should be called. 194The flags are: 195.Pp 196.Bl -tag -offset indent -width ".Dv PFIL_IFADDR" -compact 197.It Dv PFIL_IFADDR 198call me on interface reconfig 199.Fa ( cmd 200is ioctl #) 201.It Dv PFIL_IFNET 202call me on interface attach/detach 203.Fa ( cmd 204is either 205.Dv PFIL_IFNET_ATTACH 206or 207.Dv PFIL_IFNET_DETACH ) 208.El 209.Sh SEE ALSO 210.Xr bpf 4 211.Sh HISTORY 212The 213.Nm 214interface first appeared in 215.Nx 1.3 . 216The 217.Nm 218input and output lists were originally implemented as 219.In sys/queue.h 220.Dv LIST 221structures; 222however this was changed in 223.Nx 1.4 224to 225.Dv TAILQ 226structures. 227This change was to allow the input and output filters to be processed in 228reverse order, to allow the same path to be taken, in or out of the kernel. 229.Pp 230The 231.Nm 232interface was changed in 1.4T to accept a 3rd parameter to both 233.Fn pfil_add_hook 234and 235.Fn pfil_remove_hook , 236introducing the capability of per-protocol filtering. 237This was done primarily in order to support filtering of IPv6. 238.Pp 239In 1.5K, the 240.Nm 241framework was changed to work with an arbitrary number of filtering points, 242as well as be less IP-centric. 243.Pp 244.Fn pfil_add_ihook 245and 246.Fn pfil_remove_ihook 247were added in 248.Nx 8.0 . 249.Sh AUTHORS 250.An -nosplit 251The 252.Nm 253interface was designed and implemented by 254.An Matthew R. Green , 255with help from 256.An Darren Reed , 257.An Jason R. Thorpe , 258and 259.An Charles M. Hannum . 260.An Darren Reed 261added support for IPv6 in addition to IPv4. 262.An Jason R. Thorpe 263added support for multiple hooks and other clean up. 264.Sh BUGS 265The current 266.Nm 267implementation will need changes to suit a threaded kernel model. 268