Module Name:    src
Committed By:   rmind
Date:           Sat Jun 29 21:06:58 UTC 2013

Modified Files:
        src/sys/conf: files
        src/sys/external/bsd/ipf/netinet: ip_fil.h ip_fil_netbsd.c
        src/sys/net: if.c if.h if_bridge.c if_ecosubr.c if_ethersubr.c
            if_pppoe.c if_spppsubr.c pfil.c pfil.h
        src/sys/net/npf: npf_handler.c
        src/sys/netinet: in.c ip_input.c ip_output.c
        src/sys/netinet6: in6.c ip6_forward.c ip6_input.c ip6_output.c

Log Message:
- Rewrite parts of pfil(9): use array to store hooks and thus be more cache
  friendly (there are only few hooks in the system).  Make the structures
  opaque and the interface more strict.
- Remove PFIL_HOOKS option by making pfil(9) mandatory.


To generate a diff of this commit:
cvs rdiff -u -r1.1076 -r1.1077 src/sys/conf/files
cvs rdiff -u -r1.4 -r1.5 src/sys/external/bsd/ipf/netinet/ip_fil.h \
    src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c
cvs rdiff -u -r1.264 -r1.265 src/sys/net/if.c
cvs rdiff -u -r1.155 -r1.156 src/sys/net/if.h
cvs rdiff -u -r1.76 -r1.77 src/sys/net/if_bridge.c
cvs rdiff -u -r1.36 -r1.37 src/sys/net/if_ecosubr.c
cvs rdiff -u -r1.194 -r1.195 src/sys/net/if_ethersubr.c
cvs rdiff -u -r1.98 -r1.99 src/sys/net/if_pppoe.c
cvs rdiff -u -r1.126 -r1.127 src/sys/net/if_spppsubr.c
cvs rdiff -u -r1.27 -r1.28 src/sys/net/pfil.c
cvs rdiff -u -r1.30 -r1.31 src/sys/net/pfil.h
cvs rdiff -u -r1.26 -r1.27 src/sys/net/npf/npf_handler.c
cvs rdiff -u -r1.143 -r1.144 src/sys/netinet/in.c
cvs rdiff -u -r1.307 -r1.308 src/sys/netinet/ip_input.c
cvs rdiff -u -r1.223 -r1.224 src/sys/netinet/ip_output.c
cvs rdiff -u -r1.165 -r1.166 src/sys/netinet6/in6.c
cvs rdiff -u -r1.71 -r1.72 src/sys/netinet6/ip6_forward.c
cvs rdiff -u -r1.142 -r1.143 src/sys/netinet6/ip6_input.c
cvs rdiff -u -r1.153 -r1.154 src/sys/netinet6/ip6_output.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/conf/files
diff -u src/sys/conf/files:1.1076 src/sys/conf/files:1.1077
--- src/sys/conf/files:1.1076	Mon Jun 24 16:19:43 2013
+++ src/sys/conf/files	Sat Jun 29 21:06:57 2013
@@ -1,4 +1,4 @@
-#	$NetBSD: files,v 1.1076 2013/06/24 16:19:43 jakllsch Exp $
+#	$NetBSD: files,v 1.1077 2013/06/29 21:06:57 rmind Exp $
 #	@(#)files.newconf	7.5 (Berkeley) 5/10/93
 
 version 	20100430
@@ -212,7 +212,6 @@ obsolete defflag		IPX		# obsolete
 obsolete defparam opt_md.h	MEMORY_RBFLAGS	# superseded by
 						# MEMORY_DISK_RBFLAGS
 
-defflag				PFIL_HOOKS	# pfil(9)
 defflag	opt_bridge_ipf.h	BRIDGE_IPF	# bridge(4) use inet_pfil_hooks
 defflag	opt_ppp.h		PPP_DEFLATE PPP_BSDCOMP PPP_FILTER
 						# Include deflate or bsd
@@ -1693,7 +1692,7 @@ file	net/if_tap.c			tap
 file	net/if_tun.c			tun
 file	net/if_vlan.c			vlan			needs-flag
 file	net/if_pppoe.c			pppoe			needs-flag
-file	net/pfil.c			pfil_hooks | ipfilter | pf
+file	net/pfil.c
 file	net/ppp-deflate.c		ppp & ppp_deflate
 file	net/ppp_tty.c			ppp
 file	net/net_stats.c

Index: src/sys/external/bsd/ipf/netinet/ip_fil.h
diff -u src/sys/external/bsd/ipf/netinet/ip_fil.h:1.4 src/sys/external/bsd/ipf/netinet/ip_fil.h:1.5
--- src/sys/external/bsd/ipf/netinet/ip_fil.h:1.4	Sat Sep 15 16:56:45 2012
+++ src/sys/external/bsd/ipf/netinet/ip_fil.h	Sat Jun 29 21:06:57 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_fil.h,v 1.4 2012/09/15 16:56:45 plunky Exp $	*/
+/*	$NetBSD: ip_fil.h,v 1.5 2013/06/29 21:06:57 rmind Exp $	*/
 
 /*
  * Copyright (C) 2012 by Darren Reed.
@@ -1455,7 +1455,7 @@ typedef	struct	ipftune	{
 #if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \
     (defined(NetBSD1_2) && NetBSD1_2 > 1) || \
     (defined(__FreeBSD__) && (__FreeBSD_version >= 500043))
-# if (NetBSD >= 199905)
+# if (NetBSD >= 199905) && !defined(PFIL_HOOKS)
 #  define PFIL_HOOKS
 # endif
 # ifdef PFIL_HOOKS
Index: src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c
diff -u src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c:1.4 src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c:1.5
--- src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c:1.4	Tue Jan 15 03:39:16 2013
+++ src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c	Sat Jun 29 21:06:57 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_fil_netbsd.c,v 1.4 2013/01/15 03:39:16 msaitoh Exp $	*/
+/*	$NetBSD: ip_fil_netbsd.c,v 1.5 2013/06/29 21:06:57 rmind Exp $	*/
 
 /*
  * Copyright (C) 2012 by Darren Reed.
@@ -8,7 +8,7 @@
 #if !defined(lint)
 #if defined(__NetBSD__)
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_fil_netbsd.c,v 1.4 2013/01/15 03:39:16 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_fil_netbsd.c,v 1.5 2013/06/29 21:06:57 rmind Exp $");
 #else
 static const char sccsid[] = "@(#)ip_fil.c	2.41 6/5/96 (C) 1993-2000 Darren Reed";
 static const char rcsid[] = "@(#)Id: ip_fil_netbsd.c,v 1.1.1.2 2012/07/22 13:45:17 darrenr Exp";
@@ -23,7 +23,6 @@ static const char rcsid[] = "@(#)Id: ip_
 #endif
 #include <sys/param.h>
 #if (NetBSD >= 199905) && !defined(IPFILTER_LKM)
-# include "opt_pfil_hooks.h"
 # include "opt_ipsec.h"
 #endif
 #include <sys/errno.h>
@@ -326,12 +325,12 @@ ipfattach(ipf_main_softc_t *softc)
 #if defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000)
 	int error = 0;
 # if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105110000)
-        struct pfil_head *ph_inet;
+        pfil_head_t *ph_inet;
 #  ifdef USE_INET6
-        struct pfil_head *ph_inet6;
+        pfil_head_t *ph_inet6;
 #  endif
 #  if defined(PFIL_TYPE_IFNET) && defined(PFIL_IFNET)
-        struct pfil_head *ph_ifsync;
+        pfil_head_t *ph_ifsync;
 #  endif
 # endif
 #endif
@@ -353,9 +352,9 @@ ipfattach(ipf_main_softc_t *softc)
 #ifdef NETBSD_PF
 # if (__NetBSD_Version__ >= 104200000)
 #  if __NetBSD_Version__ >= 105110000
-	ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
+	ph_inet = pfil_head_get(PFIL_TYPE_AF, (void *)AF_INET);
 #   ifdef USE_INET6
-	ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+	ph_inet6 = pfil_head_get(PFIL_TYPE_AF, (void *)AF_INET6);
 #   endif
 #   if defined(PFIL_TYPE_IFNET) && defined(PFIL_IFNET)
 	ph_ifsync = pfil_head_get(PFIL_TYPE_IFNET, 0);
@@ -503,9 +502,9 @@ ipfdetach(ipf_main_softc_t *softc)
 #if defined(NETBSD_PF) && (__NetBSD_Version__ >= 104200000)
 	int error = 0;
 # if __NetBSD_Version__ >= 105150000
-	struct pfil_head *ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
+	pfil_head_t *ph_inet = pfil_head_get(PFIL_TYPE_AF, (void *)AF_INET);
 #  ifdef USE_INET6
-	struct pfil_head *ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+	pfil_head_t *ph_inet6 = pfil_head_get(PFIL_TYPE_AF, (void *)AF_INET6);
 #  endif
 #  if defined(PFIL_TYPE_IFNET) && defined(PFIL_IFNET)
 	struct pfil_head *ph_ifsync = pfil_head_get(PFIL_TYPE_IFNET, 0);

Index: src/sys/net/if.c
diff -u src/sys/net/if.c:1.264 src/sys/net/if.c:1.265
--- src/sys/net/if.c:1.264	Thu Jun 20 13:56:29 2013
+++ src/sys/net/if.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.264 2013/06/20 13:56:29 roy Exp $	*/
+/*	$NetBSD: if.c,v 1.265 2013/06/29 21:06:58 rmind Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,13 +90,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.264 2013/06/20 13:56:29 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.265 2013/06/29 21:06:58 rmind Exp $");
 
 #include "opt_inet.h"
 
 #include "opt_atalk.h"
 #include "opt_natm.h"
-#include "opt_pfil_hooks.h"
 
 #include <sys/param.h>
 #include <sys/mbuf.h>
@@ -164,9 +163,8 @@ static int if_cloners_count;
 static uint64_t index_gen;
 static kmutex_t index_gen_mtx;
 
-#ifdef PFIL_HOOKS
-struct pfil_head if_pfil;	/* packet filtering hook for interfaces */
-#endif
+/* Packet filtering hook for interfaces. */
+pfil_head_t *	if_pfil;
 
 static kauth_listener_t if_listener;
 
@@ -237,15 +235,9 @@ ifinit(void)
 void
 ifinit1(void)
 {
-
 	mutex_init(&index_gen_mtx, MUTEX_DEFAULT, IPL_NONE);
-
-#ifdef PFIL_HOOKS
-	if_pfil.ph_type = PFIL_TYPE_IFNET;
-	if_pfil.ph_ifnet = NULL;
-	if (pfil_head_register(&if_pfil) != 0)
-		printf("WARNING: unable to register pfil hook\n");
-#endif
+	if_pfil = pfil_head_create(PFIL_TYPE_IFNET, NULL);
+	KASSERT(if_pfil != NULL);
 }
 
 struct ifnet *
@@ -611,15 +603,9 @@ if_attach(struct ifnet *ifp)
 	ifp->if_snd.altq_ifp  = ifp;
 #endif
 
-#ifdef PFIL_HOOKS
-	ifp->if_pfil.ph_type = PFIL_TYPE_IFNET;
-	ifp->if_pfil.ph_ifnet = ifp;
-	if (pfil_head_register(&ifp->if_pfil) != 0)
-		printf("%s: WARNING: unable to register pfil hook\n",
-		    ifp->if_xname);
-	(void)pfil_run_hooks(&if_pfil,
+	ifp->if_pfil = pfil_head_create(PFIL_TYPE_IFNET, ifp);
+	(void)pfil_run_hooks(if_pfil,
 	    (struct mbuf **)PFIL_IFNET_ATTACH, ifp, PFIL_IFNET);
-#endif
 
 	if (!STAILQ_EMPTY(&domains))
 		if_attachdomain1(ifp);
@@ -845,11 +831,9 @@ again:
 		}
 	}
 
-#ifdef PFIL_HOOKS
-	(void)pfil_run_hooks(&if_pfil,
+	(void)pfil_run_hooks(if_pfil,
 	    (struct mbuf **)PFIL_IFNET_DETACH, ifp, PFIL_IFNET);
-	(void)pfil_head_unregister(&ifp->if_pfil);
-#endif
+	(void)pfil_head_destroy(ifp->if_pfil);
 
 	/* Announce that the interface is gone. */
 	rt_ifannouncemsg(ifp, IFAN_DEPARTURE);

Index: src/sys/net/if.h
diff -u src/sys/net/if.h:1.155 src/sys/net/if.h:1.156
--- src/sys/net/if.h:1.155	Thu Oct 25 11:53:14 2012
+++ src/sys/net/if.h	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.h,v 1.155 2012/10/25 11:53:14 msaitoh Exp $	*/
+/*	$NetBSD: if.h,v 1.156 2013/06/29 21:06:58 rmind Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -284,7 +284,7 @@ typedef struct ifnet {
 	const uint8_t *if_broadcastaddr;/* linklevel broadcast bytestring */
 	void	*if_bridge;		/* bridge glue */
 	int	if_dlt;			/* data link type (<net/dlt.h>) */
-	struct pfil_head if_pfil;	/* filtering point */
+	pfil_head_t *	if_pfil;	/* filtering point */
 	uint64_t if_capabilities;	/* interface capabilities */
 	uint64_t if_capenable;		/* capabilities enabled */
 	union {

Index: src/sys/net/if_bridge.c
diff -u src/sys/net/if_bridge.c:1.76 src/sys/net/if_bridge.c:1.77
--- src/sys/net/if_bridge.c:1.76	Thu Mar 22 12:59:33 2012
+++ src/sys/net/if_bridge.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_bridge.c,v 1.76 2012/03/22 12:59:33 wiz Exp $	*/
+/*	$NetBSD: if_bridge.c,v 1.77 2013/06/29 21:06:58 rmind Exp $	*/
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -80,12 +80,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.76 2012/03/22 12:59:33 wiz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.77 2013/06/29 21:06:58 rmind Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_bridge_ipf.h"
 #include "opt_inet.h"
-#include "opt_pfil_hooks.h"
 #endif /* _KERNEL_OPT */
 
 #include <sys/param.h>
@@ -111,7 +110,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_bridge.c,
 #include <net/if_ether.h>
 #include <net/if_bridgevar.h>
 
-#if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
+#if defined(BRIDGE_IPF)
 /* Used for bridge_ip[6]_checkbasic */
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
@@ -123,7 +122,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_bridge.c,
 #include <netinet6/in6_var.h>
 #include <netinet6/ip6_var.h>
 #include <netinet6/ip6_private.h>	/* XXX */
-#endif /* BRIDGE_IPF && PFIL_HOOKS */
+#endif /* BRIDGE_IPF */
 
 /*
  * Size of the route hash table.  Must be a power of two.
@@ -243,7 +242,7 @@ static int	bridge_ioctl_gma(struct bridg
 static int	bridge_ioctl_sma(struct bridge_softc *, void *);
 static int	bridge_ioctl_sifprio(struct bridge_softc *, void *);
 static int	bridge_ioctl_sifcost(struct bridge_softc *, void *);
-#if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
+#if defined(BRIDGE_IPF)
 static int	bridge_ioctl_gfilt(struct bridge_softc *, void *);
 static int	bridge_ioctl_sfilt(struct bridge_softc *, void *);
 static int	bridge_ipf(void *, struct mbuf **, struct ifnet *, int);
@@ -251,7 +250,7 @@ static int	bridge_ip_checkbasic(struct m
 # ifdef INET6
 static int	bridge_ip6_checkbasic(struct mbuf **mp);
 # endif /* INET6 */
-#endif /* BRIDGE_IPF && PFIL_HOOKS */
+#endif /* BRIDGE_IPF */
 
 struct bridge_control {
 	int	(*bc_func)(struct bridge_softc *, void *);
@@ -300,10 +299,10 @@ static const struct bridge_control bridg
 [BRDGSIFPRIO] = {bridge_ioctl_sifprio, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, 
 
 [BRDGSIFCOST] = {bridge_ioctl_sifcost, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, 
-#if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
+#if defined(BRIDGE_IPF)
 [BRDGGFILT] = {bridge_ioctl_gfilt, sizeof(struct ifbrparam), BC_F_COPYOUT},
 [BRDGSFILT] = {bridge_ioctl_sfilt, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
-#endif /* BRIDGE_IPF && PFIL_HOOKS */
+#endif /* BRIDGE_IPF */
 };
 static const int bridge_control_table_size = __arraycount(bridge_control_table);
 
@@ -1016,7 +1015,7 @@ bridge_ioctl_sifprio(struct bridge_softc
 	return (0);
 }
 
-#if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
+#if defined(BRIDGE_IPF)
 static int
 bridge_ioctl_gfilt(struct bridge_softc *sc, void *arg)
 {
@@ -1041,18 +1040,18 @@ bridge_ioctl_sfilt(struct bridge_softc *
 
 	if ((nflags & IFBF_FILT_USEIPF) && !(oflags & IFBF_FILT_USEIPF)) {
 		pfil_add_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT,
-			&sc->sc_if.if_pfil);
+			sc->sc_if.if_pfil);
 	}
 	if (!(nflags & IFBF_FILT_USEIPF) && (oflags & IFBF_FILT_USEIPF)) {
 		pfil_remove_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT,
-			&sc->sc_if.if_pfil);
+			sc->sc_if.if_pfil);
 	}
 
 	sc->sc_filter_flags = nflags;
 
 	return (0);
 }
-#endif /* BRIDGE_IPF && PFIL_HOOKS */
+#endif /* BRIDGE_IPF */
 
 static int
 bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg)
@@ -1154,9 +1153,8 @@ bridge_enqueue(struct bridge_softc *sc, 
 	 */
 	m->m_pkthdr.csum_flags = 0;
 
-#ifdef PFIL_HOOKS
 	if (runfilt) {
-		if (pfil_run_hooks(&sc->sc_if.if_pfil, &m,
+		if (pfil_run_hooks(sc->sc_if.if_pfil, &m,
 		    dst_ifp, PFIL_OUT) != 0) {
 			if (m != NULL)
 				m_freem(m);
@@ -1165,7 +1163,6 @@ bridge_enqueue(struct bridge_softc *sc, 
 		if (m == NULL)
 			return;
 	}
-#endif /* PFIL_HOOKS */
 
 #ifdef ALTQ
 	/*
@@ -1427,8 +1424,7 @@ bridge_forward(void *v)
 			dst_if = NULL;
 		}
 
-#ifdef PFIL_HOOKS
-		if (pfil_run_hooks(&sc->sc_if.if_pfil, &m,
+		if (pfil_run_hooks(sc->sc_if.if_pfil, &m,
 		    m->m_pkthdr.rcvif, PFIL_IN) != 0) {
 			if (m != NULL)
 				m_freem(m);
@@ -1436,7 +1432,6 @@ bridge_forward(void *v)
 		}
 		if (m == NULL)
 			continue;
-#endif /* PFIL_HOOKS */
 
 		if (dst_if == NULL) {
 			bridge_broadcast(sc, src_if, m);
@@ -1998,9 +1993,9 @@ bridge_rtnode_destroy(struct bridge_soft
 	splx(s);
 }
 
-#if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
-extern struct pfil_head inet_pfil_hook;                 /* XXX */
-extern struct pfil_head inet6_pfil_hook;                /* XXX */
+#if defined(BRIDGE_IPF)
+extern pfil_head_t *inet_pfil_hook;                 /* XXX */
+extern pfil_head_t *inet6_pfil_hook;                /* XXX */
 
 /*
  * Send bridge packets through IPF if they are one of the types IPF can deal
@@ -2076,13 +2071,13 @@ bridge_ipf(void *arg, struct mbuf **mp, 
 	case ETHERTYPE_IP :
 		error = (dir == PFIL_IN) ? bridge_ip_checkbasic(mp) : 0;
 		if (error == 0)
-			error = pfil_run_hooks(&inet_pfil_hook, mp, ifp, dir);
+			error = pfil_run_hooks(inet_pfil_hook, mp, ifp, dir);
 		break;
 # ifdef INET6
 	case ETHERTYPE_IPV6 :
 		error = (dir == PFIL_IN) ? bridge_ip6_checkbasic(mp) : 0;
 		if (error == 0)
-			error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp, dir);
+			error = pfil_run_hooks(inet6_pfil_hook, mp, ifp, dir);
 		break;
 # endif
 	default :
@@ -2279,4 +2274,4 @@ bridge_ip6_checkbasic(struct mbuf **mp)
 	return -1;
 }
 # endif /* INET6 */
-#endif /* BRIDGE_IPF && PFIL_HOOKS */
+#endif /* BRIDGE_IPF */

Index: src/sys/net/if_ecosubr.c
diff -u src/sys/net/if_ecosubr.c:1.36 src/sys/net/if_ecosubr.c:1.37
--- src/sys/net/if_ecosubr.c:1.36	Sun Nov 20 12:15:38 2011
+++ src/sys/net/if_ecosubr.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ecosubr.c,v 1.36 2011/11/20 12:15:38 kiyohara Exp $	*/
+/*	$NetBSD: if_ecosubr.c,v 1.37 2013/06/29 21:06:58 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2001 Ben Harris
@@ -58,10 +58,9 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ecosubr.c,v 1.36 2011/11/20 12:15:38 kiyohara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ecosubr.c,v 1.37 2013/06/29 21:06:58 rmind Exp $");
 
 #include "opt_inet.h"
-#include "opt_pfil_hooks.h"
 
 #include <sys/param.h>
 #include <sys/errno.h>
@@ -320,12 +319,10 @@ eco_output(struct ifnet *ifp, struct mbu
 		erp->erp_count = retry_count;
 	}
 
-#ifdef PFIL_HOOKS
-	if ((error = pfil_run_hooks(&ifp->if_pfil, &m, ifp, PFIL_OUT)) != 0)
+	if ((error = pfil_run_hooks(ifp->if_pfil, &m, ifp, PFIL_OUT)) != 0)
 		return (error);
 	if (m == NULL)
 		return (0);
-#endif
 
 	return ifq_enqueue(ifp, m ALTQ_COMMA ALTQ_DECL(&pktattr));
 
@@ -366,12 +363,10 @@ eco_input(struct ifnet *ifp, struct mbuf
 	void *tha;
 #endif
 
-#ifdef PFIL_HOOKS
-	if (pfil_run_hooks(&ifp->if_pfil, &m, ifp, PFIL_IN) != 0)
+	if (pfil_run_hooks(ifp->if_pfil, &m, ifp, PFIL_IN) != 0)
 		return;
 	if (m == NULL)
 		return;
-#endif
 
 	/* Copy the mbuf header and trim it off. */
 	/* XXX use m_split? */

Index: src/sys/net/if_ethersubr.c
diff -u src/sys/net/if_ethersubr.c:1.194 src/sys/net/if_ethersubr.c:1.195
--- src/sys/net/if_ethersubr.c:1.194	Fri Mar  1 18:25:56 2013
+++ src/sys/net/if_ethersubr.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ethersubr.c,v 1.194 2013/03/01 18:25:56 joerg Exp $	*/
+/*	$NetBSD: if_ethersubr.c,v 1.195 2013/06/29 21:06:58 rmind Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.194 2013/03/01 18:25:56 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.195 2013/06/29 21:06:58 rmind Exp $");
 
 #include "opt_inet.h"
 #include "opt_atalk.h"
@@ -69,7 +69,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_ethersubr
 #include "opt_mbuftrace.h"
 #include "opt_mpls.h"
 #include "opt_gateway.h"
-#include "opt_pfil_hooks.h"
 #include "opt_pppoe.h"
 #include "vlan.h"
 #include "pppoe.h"
@@ -436,12 +435,10 @@ ether_output(struct ifnet * const ifp0, 
 	}
 #endif /* NCARP > 0 */
 
-#ifdef PFIL_HOOKS
-	if ((error = pfil_run_hooks(&ifp->if_pfil, &m, ifp, PFIL_OUT)) != 0)
+	if ((error = pfil_run_hooks(ifp->if_pfil, &m, ifp, PFIL_OUT)) != 0)
 		return (error);
 	if (m == NULL)
 		return (0);
-#endif
 
 #if NBRIDGE > 0
 	/*
@@ -683,9 +680,8 @@ ether_input(struct ifnet *ifp, struct mb
 		}
 	}
 
-#ifdef PFIL_HOOKS
 	if ((m->m_flags & M_PROMISC) == 0) {
-		if (pfil_run_hooks(&ifp->if_pfil, &m, ifp, PFIL_IN) != 0)
+		if (pfil_run_hooks(ifp->if_pfil, &m, ifp, PFIL_IN) != 0)
 			return;
 		if (m == NULL)
 			return;
@@ -694,7 +690,6 @@ ether_input(struct ifnet *ifp, struct mb
 		etype = ntohs(eh->ether_type);
 		ehlen = sizeof(*eh);
 	}
-#endif
 
 #if NAGR > 0
 	if (ifp->if_agrprivate &&

Index: src/sys/net/if_pppoe.c
diff -u src/sys/net/if_pppoe.c:1.98 src/sys/net/if_pppoe.c:1.99
--- src/sys/net/if_pppoe.c:1.98	Mon Sep  5 12:19:09 2011
+++ src/sys/net/if_pppoe.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: if_pppoe.c,v 1.98 2011/09/05 12:19:09 rjs Exp $ */
+/* $NetBSD: if_pppoe.c,v 1.99 2013/06/29 21:06:58 rmind Exp $ */
 
 /*-
  * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
@@ -30,10 +30,9 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.98 2011/09/05 12:19:09 rjs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.99 2013/06/29 21:06:58 rmind Exp $");
 
 #include "pppoe.h"
-#include "opt_pfil_hooks.h"
 #include "opt_pppoe.h"
 
 #include <sys/param.h>
@@ -193,9 +192,7 @@ static struct pppoe_softc * pppoe_find_s
 static struct pppoe_softc * pppoe_find_softc_by_hunique(uint8_t *, size_t, struct ifnet *);
 static struct mbuf *pppoe_get_mbuf(size_t len);
 
-#ifdef PFIL_HOOKS
 static int pppoe_ifattach_hook(void *, struct mbuf **, struct ifnet *, int);
-#endif
 
 static LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list;
 
@@ -249,11 +246,9 @@ pppoe_clone_create(struct if_clone *ifc,
 	sppp_attach(&sc->sc_sppp.pp_if);
 
 	bpf_attach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0);
-#ifdef PFIL_HOOKS
-	if (LIST_EMPTY(&pppoe_softc_list))
-		pfil_add_hook(pppoe_ifattach_hook, NULL,
-		    PFIL_IFNET|PFIL_WAITOK, &if_pfil);
-#endif
+	if (LIST_EMPTY(&pppoe_softc_list)) {
+		pfil_add_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil);
+	}
 	LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list);
 	return 0;
 }
@@ -265,11 +260,9 @@ pppoe_clone_destroy(struct ifnet *ifp)
 
 	callout_stop(&sc->sc_timeout);
 	LIST_REMOVE(sc, sc_list);
-#ifdef PFIL_HOOKS
-	if (LIST_EMPTY(&pppoe_softc_list))
-		pfil_remove_hook(pppoe_ifattach_hook, NULL,
-		    PFIL_IFNET|PFIL_WAITOK, &if_pfil);
-#endif
+	if (LIST_EMPTY(&pppoe_softc_list)) {
+		pfil_remove_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil);
+	}
 	bpf_detach(ifp);
 	sppp_detach(&sc->sc_sppp.pp_if);
 	if_detach(ifp);
@@ -1514,10 +1507,8 @@ pppoe_start(struct ifnet *ifp)
 }
 
 
-#ifdef PFIL_HOOKS
 static int
-pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp,
-    int dir)
+pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
 {
 	struct pppoe_softc *sc;
 	int s;
@@ -1541,7 +1532,6 @@ pppoe_ifattach_hook(void *arg, struct mb
 
 	return 0;
 }
-#endif
 
 static void
 pppoe_clear_softc(struct pppoe_softc *sc, const char *message)

Index: src/sys/net/if_spppsubr.c
diff -u src/sys/net/if_spppsubr.c:1.126 src/sys/net/if_spppsubr.c:1.127
--- src/sys/net/if_spppsubr.c:1.126	Fri Mar  1 18:25:56 2013
+++ src/sys/net/if_spppsubr.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_spppsubr.c,v 1.126 2013/03/01 18:25:56 joerg Exp $	 */
+/*	$NetBSD: if_spppsubr.c,v 1.127 2013/06/29 21:06:58 rmind Exp $	 */
 
 /*
  * Synchronous PPP/Cisco link level subroutines.
@@ -41,12 +41,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.126 2013/03/01 18:25:56 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.127 2013/06/29 21:06:58 rmind Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
 #include "opt_ipx.h"
-#include "opt_pfil_hooks.h"
 #include "opt_modular.h"
 #include "opt_compat_netbsd.h"
 #endif
@@ -4897,11 +4896,10 @@ found:
 			log(LOG_DEBUG, "%s: sppp_set_ip_addrs: in_ifinit "
 			" failed, error=%d\n", ifp->if_xname, error);
 		}
-#ifdef PFIL_HOOKS
-		if (!error)
-			(void)pfil_run_hooks(&if_pfil,
+		if (!error) {
+			(void)pfil_run_hooks(if_pfil,
 			    (struct mbuf **)SIOCAIFADDR, ifp, PFIL_IFADDR);
-#endif
+		}
 	}
 }
 
@@ -4946,10 +4944,8 @@ found:
 			/* replace peer addr in place */
 			dest->sin_addr.s_addr = sp->ipcp.saved_hisaddr;
 		in_ifinit(ifp, ifatoia(ifa), &new_sin, 0);
-#ifdef PFIL_HOOKS
-		(void)pfil_run_hooks(&if_pfil,
+		(void)pfil_run_hooks(if_pfil,
 		    (struct mbuf **)SIOCDIFADDR, ifp, PFIL_IFADDR);
-#endif
 	}
 }
 #endif
@@ -5050,11 +5046,10 @@ sppp_set_ip6_addr(struct sppp *sp, const
 			log(LOG_DEBUG, "%s: sppp_set_ip6_addr: in6_ifinit "
 			" failed, error=%d\n", ifp->if_xname, error);
 		}
-#ifdef PFIL_HOOKS
-		if (!error)
-			(void)pfil_run_hooks(&if_pfil,
+		if (!error) {
+			(void)pfil_run_hooks(if_pfil,
 			    (struct mbuf **)SIOCAIFADDR_IN6, ifp, PFIL_IFADDR);
-#endif
+		}
 	}
 }
 #endif

Index: src/sys/net/pfil.c
diff -u src/sys/net/pfil.c:1.27 src/sys/net/pfil.c:1.28
--- src/sys/net/pfil.c:1.27	Mon Jun 23 03:13:12 2008
+++ src/sys/net/pfil.c	Sat Jun 29 21:06:58 2013
@@ -1,6 +1,7 @@
-/*	$NetBSD: pfil.c,v 1.27 2008/06/23 03:13:12 dyoung Exp $	*/
+/*	$NetBSD: pfil.c,v 1.28 2013/06/29 21:06:58 rmind Exp $	*/
 
 /*
+ * Copyright (c) 2013 Mindaugas Rasiukevicius <rmind at NetBSD org>
  * Copyright (c) 1996 Matthew R. Green
  * All rights reserved.
  *
@@ -27,245 +28,253 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pfil.c,v 1.27 2008/06/23 03:13:12 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pfil.c,v 1.28 2013/06/29 21:06:58 rmind Exp $");
 
 #include <sys/param.h>
-#include <sys/errno.h>
-#include <sys/malloc.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
 #include <sys/systm.h>
-#include <sys/proc.h>
 #include <sys/queue.h>
+#include <sys/kmem.h>
 
 #include <net/if.h>
 #include <net/pfil.h>
 
-static int pfil_list_add(pfil_list_t *,
-    int (*)(void *, struct mbuf **, struct ifnet *, int), void *, int);
+#define	MAX_HOOKS	8
 
-static int pfil_list_remove(pfil_list_t *,
-    int (*)(void *, struct mbuf **, struct ifnet *, int), void *);
+typedef struct {
+	pfil_func_t	pfil_func;
+	void *		pfil_arg;
+} pfil_hook_t;
+
+typedef struct {
+	pfil_hook_t	hooks[MAX_HOOKS];
+	u_int		nhooks;
+} pfil_list_t;
+
+struct pfil_head {
+	pfil_list_t	ph_in;
+	pfil_list_t	ph_out;
+	pfil_list_t	ph_ifaddr;
+	pfil_list_t	ph_ifevent;
+	int		ph_type;
+	void *		ph_key;
+	LIST_ENTRY(pfil_head) ph_list;
+};
+
+static const int pfil_flag_cases[] = {
+	PFIL_IN, PFIL_OUT, PFIL_IFADDR, PFIL_IFNET
+};
 
-LIST_HEAD(, pfil_head) pfil_head_list =
+static LIST_HEAD(, pfil_head) pfil_head_list __read_mostly =
     LIST_HEAD_INITIALIZER(&pfil_head_list);
 
 /*
- * pfil_run_hooks() runs the specified packet filter hooks.
+ * pfil_head_create: create and register a packet filter head.
  */
-int
-pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
-    int dir)
+pfil_head_t *
+pfil_head_create(int type, void *key)
 {
-	struct packet_filter_hook *pfh;
-	struct mbuf *m = NULL;
-	int rv = 0;
-
-	if ((dir & PFIL_ALL) && mp)
-		m = *mp;
-	for (pfh = pfil_hook_get(dir, ph); pfh != NULL;
-	     pfh = TAILQ_NEXT(pfh, pfil_link)) {
-		if (pfh->pfil_func != NULL) {
-			if (pfh->pfil_flags & PFIL_ALL) {
-				rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp,
-				    dir);
-				if (rv != 0 || m == NULL)
-					break;
-			} else {
-				rv = (*pfh->pfil_func)(pfh->pfil_arg, mp, ifp,
-				    dir);
-				if (rv != 0)
-					break;
-			}
-		}
-	}
-
-	if ((dir & PFIL_ALL) && mp)
-		*mp = m;
-	return (rv);
-}
+	pfil_head_t *ph;
 
-/*
- * pfil_head_register() registers a pfil_head with the packet filter
- * hook mechanism.
- */
-int
-pfil_head_register(struct pfil_head *ph)
-{
-	struct pfil_head *lph;
-
-	LIST_FOREACH(lph, &pfil_head_list, ph_list) {
-		if (ph->ph_type == lph->ph_type &&
-		    ph->ph_un.phu_val == lph->ph_un.phu_val)
-			return EEXIST;
+	if (pfil_head_get(type, key)) {
+		return NULL;
 	}
-
-	TAILQ_INIT(&ph->ph_in);
-	TAILQ_INIT(&ph->ph_out);
-	TAILQ_INIT(&ph->ph_ifaddr);
-	TAILQ_INIT(&ph->ph_ifnetevent);
+	ph = kmem_zalloc(sizeof(pfil_head_t), KM_SLEEP);
+	ph->ph_type = type;
+	ph->ph_key = key;
 
 	LIST_INSERT_HEAD(&pfil_head_list, ph, ph_list);
-
-	return (0);
+	return ph;
 }
 
 /*
- * pfil_head_unregister() removes a pfil_head from the packet filter
- * hook mechanism.
+ * pfil_head_destroy: remove and destroy a packet filter head.
  */
-int
-pfil_head_unregister(struct pfil_head *pfh)
+void
+pfil_head_destroy(pfil_head_t *pfh)
 {
-
 	LIST_REMOVE(pfh, ph_list);
-	return (0);
+	kmem_free(pfh, sizeof(pfil_head_t));
 }
 
 /*
- * pfil_head_get() returns the pfil_head for a given key/dlt.
+ * pfil_head_get: returns the packer filter head for a given key.
  */
-struct pfil_head *
-pfil_head_get(int type, u_long val)
+pfil_head_t *
+pfil_head_get(int type, void *key)
 {
-	struct pfil_head *ph;
+	pfil_head_t *ph;
 
 	LIST_FOREACH(ph, &pfil_head_list, ph_list) {
-		if (ph->ph_type == type && ph->ph_un.phu_val == val)
+		if (ph->ph_type == type && ph->ph_key == key)
 			break;
 	}
-
-	return (ph);
+	return ph;
 }
 
-/*
- * pfil_add_hook() adds a function to the packet filter hook.  the
- * flags are:
- *	PFIL_IN		call me on incoming packets
- *	PFIL_OUT	call me on outgoing packets
- *	PFIL_ALL	call me on all of the above
- *	PFIL_IFADDR  	call me on interface reconfig (mbuf ** is ioctl #)
- *	PFIL_IFNET  	call me on interface attach/detach
- *			(mbuf ** is PFIL_IFNET_*)
- *	PFIL_WAITOK	OK to call malloc with M_WAITOK.
- */
-int
-pfil_add_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int),
-    void *arg, int flags, struct pfil_head *ph)
+static pfil_list_t *
+pfil_hook_get(int dir, pfil_head_t *ph)
 {
-	int err = 0;
-
-	if (flags & PFIL_IN) {
-		err = pfil_list_add(&ph->ph_in, func, arg, flags & ~PFIL_OUT);
-		if (err)
-			return err;
-	}
-	if (flags & PFIL_OUT) {
-		err = pfil_list_add(&ph->ph_out, func, arg, flags & ~PFIL_IN);
-		if (err) {
-			if (flags & PFIL_IN)
-				pfil_list_remove(&ph->ph_in, func, arg);
-			return err;
-		}
-	}
-	if (flags & PFIL_IFADDR) {
-		err = pfil_list_add(&ph->ph_ifaddr, func, arg, flags);
-		if (err) {
-			if (flags & PFIL_IN)
-				pfil_list_remove(&ph->ph_in, func, arg);
-			if (flags & PFIL_OUT)
-				pfil_list_remove(&ph->ph_out, func, arg);
-			return err;
-		}
-	}
-	if (flags & PFIL_IFNET) {
-		err = pfil_list_add(&ph->ph_ifnetevent, func, arg, flags);
-		if (err) {
-			if (flags & PFIL_IN)
-				pfil_list_remove(&ph->ph_in, func, arg);
-			if (flags & PFIL_OUT)
-				pfil_list_remove(&ph->ph_out, func, arg);
-			if (flags & PFIL_IFADDR)
-				pfil_list_remove(&ph->ph_ifaddr, func, arg);
-			return err;
-		}
+	switch (dir) {
+	case PFIL_IN:
+		return &ph->ph_in;
+	case PFIL_OUT:
+		return &ph->ph_out;
+	case PFIL_IFADDR:
+		return &ph->ph_ifaddr;
+	case PFIL_IFNET:
+		return &ph->ph_ifevent;
 	}
-	return 0;
+	return NULL;
 }
 
 static int
-pfil_list_add(pfil_list_t *list,
-    int (*func)(void *, struct mbuf **, struct ifnet *, int), void *arg,
-    int flags)
+pfil_list_add(pfil_list_t *phlist, pfil_func_t func, void *arg, int flags)
 {
-	struct packet_filter_hook *pfh;
+	const u_int nhooks = phlist->nhooks;
+	pfil_hook_t *pfh;
 
-	/*
-	 * First make sure the hook is not already there.
-	 */
-	TAILQ_FOREACH(pfh, list, pfil_link) {
+	/* Check if we have a free slot. */
+	if (nhooks == MAX_HOOKS) {
+		return ENOSPC;
+	}
+	KASSERT(nhooks < MAX_HOOKS);
+
+	/* Make sure the hook is not already added. */
+	for (u_int i = 0; i < nhooks; i++) {
+		pfh = &phlist->hooks[i];
 		if (pfh->pfil_func == func && pfh->pfil_arg == arg)
 			return EEXIST;
 	}
 
-	pfh = (struct packet_filter_hook *)malloc(sizeof(*pfh), M_IFADDR,
-	    (flags & PFIL_WAITOK) ? M_WAITOK : M_NOWAIT);
-	if (pfh == NULL)
-		return ENOMEM;
-
-	pfh->pfil_func = func;
-	pfh->pfil_arg  = arg;
-	pfh->pfil_flags = flags;
-
 	/*
-	 * insert the input list in reverse order of the output list
-	 * so that the same path is followed in or out of the kernel.
+	 * Finally, add the hook.  Note: for PFIL_IN we insert the hooks in
+	 * reverse order of the PFIL_OUT so that the same path is followed
+	 * in or out of the kernel.
 	 */
-	if (flags & PFIL_IN)
-		TAILQ_INSERT_HEAD(list, pfh, pfil_link);
-	else
-		TAILQ_INSERT_TAIL(list, pfh, pfil_link);
+	if (flags & PFIL_IN) {
+		/* XXX: May want to revisit this later; */
+		size_t len = sizeof(pfil_hook_t) * nhooks;
+		pfh = &phlist->hooks[0];
+		memmove(&phlist->hooks[1], pfh, len);
+	} else {
+		pfh = &phlist->hooks[nhooks];
+	}
+	phlist->nhooks++;
 
+	pfh->pfil_func = func;
+	pfh->pfil_arg  = arg;
 	return 0;
 }
 
 /*
- * pfil_remove_hook removes a specific function from the packet filter
- * hook list.
+ * pfil_add_hook: add a function (hook) to the packet filter head.
+ * The possible flags are:
+ *
+ *	PFIL_IN		call on incoming packets
+ *	PFIL_OUT	call on outgoing packets
+ *	PFIL_ALL	call on all of the above
+ *	PFIL_IFADDR	call on interface reconfig (mbuf is ioctl #)
+ *	PFIL_IFNET	call on interface attach/detach (mbuf is PFIL_IFNET_*)
  */
 int
-pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int),
-    void *arg, int flags, struct pfil_head *ph)
+pfil_add_hook(pfil_func_t func, void *arg, int flags, pfil_head_t *ph)
 {
-	int err = 0;
+	int error = 0;
+
+	KASSERT(func != NULL);
+
+	for (u_int i = 0; i < __arraycount(pfil_flag_cases); i++) {
+		const int fcase = pfil_flag_cases[i];
+		pfil_list_t *phlist;
 
-	if (flags & PFIL_IN)
-		err = pfil_list_remove(&ph->ph_in, func, arg);
-	if ((err == 0) && (flags & PFIL_OUT))
-		err = pfil_list_remove(&ph->ph_out, func, arg);
-	if ((err == 0) && (flags & PFIL_IFADDR))
-		err = pfil_list_remove(&ph->ph_ifaddr, func, arg);
-	if ((err == 0) && (flags & PFIL_IFNET))
-		err = pfil_list_remove(&ph->ph_ifnetevent, func, arg);
-	return err;
+		if ((flags & fcase) == 0) {
+			continue;
+		}
+		phlist = pfil_hook_get(fcase, ph);
+		if ((error = pfil_list_add(phlist, func, arg, flags)) != 0) {
+			break;
+		}
+	}
+	if (error) {
+		pfil_remove_hook(func, arg, flags, ph);
+	}
+	return error;
 }
 
 /*
- * pfil_list_remove is an internal function that takes a function off the
- * specified list.
+ * pfil_list_remove: remove the hook from a specified list.
  */
 static int
-pfil_list_remove(pfil_list_t *list,
-    int (*func)(void *, struct mbuf **, struct ifnet *, int), void *arg)
+pfil_list_remove(pfil_list_t *phlist, pfil_func_t func, void *arg)
 {
-	struct packet_filter_hook *pfh;
+	const u_int nhooks = phlist->nhooks;
 
-	TAILQ_FOREACH(pfh, list, pfil_link) {
-		if (pfh->pfil_func == func && pfh->pfil_arg == arg) {
-			TAILQ_REMOVE(list, pfh, pfil_link);
-			free(pfh, M_IFADDR);
-			return 0;
+	for (u_int i = 0; i < nhooks; i++) {
+		pfil_hook_t *last, *pfh = &phlist->hooks[i];
+
+		if (pfh->pfil_func != func || pfh->pfil_arg != arg) {
+			continue;
+		}
+		if ((last = &phlist->hooks[nhooks - 1]) != pfh) {
+			memcpy(pfh, last, sizeof(pfil_hook_t));
 		}
+		phlist->nhooks--;
+		return 0;
 	}
 	return ENOENT;
 }
+
+/*
+ * pfil_remove_hook: remove the hook from the packet filter head.
+ */
+int
+pfil_remove_hook(pfil_func_t func, void *arg, int flags, pfil_head_t *ph)
+{
+	for (u_int i = 0; i < __arraycount(pfil_flag_cases); i++) {
+		const int fcase = pfil_flag_cases[i];
+		pfil_list_t *pflist;
+
+		if ((flags & fcase) == 0) {
+			continue;
+		}
+		pflist = pfil_hook_get(fcase, ph);
+		(void)pfil_list_remove(pflist, func, arg);
+	}
+	return 0;
+}
+
+/*
+ * pfil_run_hooks: run the specified packet filter hooks.
+ */
+int
+pfil_run_hooks(pfil_head_t *ph, struct mbuf **mp, ifnet_t *ifp, int dir)
+{
+	const bool pass_mbuf = (dir & PFIL_ALL) != 0 && mp;
+	struct mbuf *m = pass_mbuf ? *mp : NULL;
+	pfil_list_t *phlist;
+	int ret = 0;
+
+	if ((phlist = pfil_hook_get(dir, ph)) == NULL) {
+		return ret;
+	}
+
+	for (u_int i = 0; i < phlist->nhooks; i++) {
+		pfil_hook_t *pfh = &phlist->hooks[i];
+		pfil_func_t func = pfh->pfil_func;
+
+		if (__predict_true(dir & PFIL_ALL)) {
+			ret = (*func)(pfh->pfil_arg, &m, ifp, dir);
+			if (m == NULL)
+				break;
+		} else {
+			ret = (*func)(pfh->pfil_arg, mp, ifp, dir);
+		}
+		if (ret)
+			break;
+	}
+
+	if (pass_mbuf) {
+		*mp = m;
+	}
+	return ret;
+}

Index: src/sys/net/pfil.h
diff -u src/sys/net/pfil.h:1.30 src/sys/net/pfil.h:1.31
--- src/sys/net/pfil.h:1.30	Sun Sep 30 05:02:08 2012
+++ src/sys/net/pfil.h	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pfil.h,v 1.30 2012/09/30 05:02:08 dholland Exp $	*/
+/*	$NetBSD: pfil.h,v 1.31 2013/06/29 21:06:58 rmind Exp $	*/
 
 /*
  * Copyright (c) 1996 Matthew R. Green
@@ -29,13 +29,7 @@
 #ifndef _NET_PFIL_H_
 #define _NET_PFIL_H_
 
-#ifdef _KERNEL_OPT
-#include "opt_pfil_hooks.h"
-#endif
-
 #include <sys/queue.h>
-#include <net/dlt.h>
-#include <sys/null.h>
 
 struct mbuf;
 struct ifnet;
@@ -44,17 +38,11 @@ struct ifnet;
  * The packet filter hooks are designed for anything to call them to
  * possibly intercept the packet.
  */
-struct packet_filter_hook {
-        TAILQ_ENTRY(packet_filter_hook) pfil_link;
-	int	(*pfil_func)(void *, struct mbuf **, struct ifnet *, int);
-	void	*pfil_arg;
-	int	pfil_flags;
-};
+typedef int (*pfil_func_t)(void *, struct mbuf **, struct ifnet *, int);
 
 #define PFIL_IN		0x00000001
 #define PFIL_OUT	0x00000002
 #define PFIL_ALL	(PFIL_IN|PFIL_OUT)
-#define PFIL_WAITOK	0x00000004
 #define PFIL_IFADDR	0x00000008
 #define PFIL_IFNET	0x00000010
 
@@ -62,75 +50,24 @@ struct packet_filter_hook {
 #define	PFIL_IFNET_ATTACH	0
 #define	PFIL_IFNET_DETACH	1
 
-typedef	TAILQ_HEAD(pfil_list, packet_filter_hook) pfil_list_t;
-
 #define	PFIL_TYPE_AF		1	/* key is AF_* type */
 #define	PFIL_TYPE_IFNET		2	/* key is ifnet pointer */
 
-struct pfil_head {
-	pfil_list_t	ph_in;
-	pfil_list_t	ph_out;
-	pfil_list_t	ph_ifaddr;
-	pfil_list_t	ph_ifnetevent; /* XXX naming collision */
-	int		ph_type;
-	union {
-		unsigned long	phu_val;
-		void		*phu_ptr;
-	} ph_un;
-#define	ph_af		ph_un.phu_val
-#define	ph_ifnet	ph_un.phu_ptr
-	LIST_ENTRY(pfil_head) ph_list;
-};
-typedef struct pfil_head pfil_head_t;
+typedef struct pfil_head	pfil_head_t;
 
 #ifdef _KERNEL
 
-int	pfil_run_hooks(struct pfil_head *, struct mbuf **, struct ifnet *,
-	    int);
-
-int	pfil_add_hook(int (*func)(void *, struct mbuf **,
-	    struct ifnet *, int), void *, int, struct pfil_head *);
-int	pfil_remove_hook(int (*func)(void *, struct mbuf **,
-	    struct ifnet *, int), void *, int, struct pfil_head *);
-
-int	pfil_head_register(struct pfil_head *);
-int	pfil_head_unregister(struct pfil_head *);
-
-struct pfil_head *pfil_head_get(int, unsigned long);
-
-static __inline struct packet_filter_hook *
-pfil_hook_get(int dir, struct pfil_head *ph)
-{
-
-	if (dir == PFIL_IN)
-		return (TAILQ_FIRST(&ph->ph_in));
-	else if (dir == PFIL_OUT)
-		return (TAILQ_FIRST(&ph->ph_out));
-	else if (dir == PFIL_IFADDR)
-		return (TAILQ_FIRST(&ph->ph_ifaddr));
-	else if (dir == PFIL_IFNET)
-		return (TAILQ_FIRST(&ph->ph_ifnetevent));
-	else
-		return (NULL);
-}
+int	pfil_run_hooks(pfil_head_t *, struct mbuf **, struct ifnet *, int);
+int	pfil_add_hook(pfil_func_t, void *, int, pfil_head_t *);
+int	pfil_remove_hook(pfil_func_t, void *, int, pfil_head_t *);
+
+pfil_head_t *	pfil_head_create(int, void *);
+void		pfil_head_destroy(pfil_head_t *);
+pfil_head_t *	pfil_head_get(int, void *);
 
-#endif /* _KERNEL */
-
-/* XXX */
-#if defined(_KERNEL_OPT)
-#include "ipfilter.h"
-#endif
-
-#if NIPFILTER > 0
-#ifdef PFIL_HOOKS
-#undef PFIL_HOOKS
-#endif
-#define PFIL_HOOKS
-#endif /* NIPFILTER */
+/* Packet filtering hook for interfaces (in sys/net/if.c module). */
+extern pfil_head_t *if_pfil;
 
-#ifdef _KERNEL
-/* in sys/net/if.c */
-extern struct pfil_head if_pfil; /* packet filtering hook for interfaces */
 #endif /* _KERNEL */
 
 #endif /* !_NET_PFIL_H_ */

Index: src/sys/net/npf/npf_handler.c
diff -u src/sys/net/npf/npf_handler.c:1.26 src/sys/net/npf/npf_handler.c:1.27
--- src/sys/net/npf/npf_handler.c:1.26	Sat Feb  9 03:35:31 2013
+++ src/sys/net/npf/npf_handler.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_handler.c,v 1.26 2013/02/09 03:35:31 rmind Exp $	*/
+/*	$NetBSD: npf_handler.c,v 1.27 2013/06/29 21:06:58 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.26 2013/02/09 03:35:31 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.27 2013/06/29 21:06:58 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -57,9 +57,9 @@ __KERNEL_RCSID(0, "$NetBSD: npf_handler.
  * If npf_ph_if != NULL, pfil hooks are registered.  If NULL, not registered.
  * Used to check the state.  Locked by: softnet_lock + KERNEL_LOCK (XXX).
  */
-static struct pfil_head *	npf_ph_if = NULL;
-static struct pfil_head *	npf_ph_inet = NULL;
-static struct pfil_head *	npf_ph_inet6 = NULL;
+static pfil_head_t *	npf_ph_if = NULL;
+static pfil_head_t *	npf_ph_inet = NULL;
+static pfil_head_t *	npf_ph_inet6 = NULL;
 
 #ifndef INET6
 #define ip6_reass_packet(x, y)	ENOTSUP
@@ -309,8 +309,8 @@ npf_pfil_register(void)
 
 	/* Capture point of any activity in interfaces and IP layer. */
 	npf_ph_if = pfil_head_get(PFIL_TYPE_IFNET, 0);
-	npf_ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
-	npf_ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+	npf_ph_inet = pfil_head_get(PFIL_TYPE_AF, (void *)AF_INET);
+	npf_ph_inet6 = pfil_head_get(PFIL_TYPE_AF, (void *)AF_INET6);
 	if (!npf_ph_if || (!npf_ph_inet && !npf_ph_inet6)) {
 		npf_ph_if = NULL;
 		error = ENOENT;
@@ -319,18 +319,18 @@ npf_pfil_register(void)
 
 	/* Interface re-config or attach/detach hook. */
 	error = pfil_add_hook(npf_ifhook, NULL,
-	    PFIL_WAITOK | PFIL_IFADDR | PFIL_IFNET, npf_ph_if);
+	    PFIL_IFADDR | PFIL_IFNET, npf_ph_if);
 	KASSERT(error == 0);
 
 	/* Packet IN/OUT handler on all interfaces and IP layer. */
 	if (npf_ph_inet) {
 		error = pfil_add_hook(npf_packet_handler, NULL,
-		    PFIL_WAITOK | PFIL_ALL, npf_ph_inet);
+		    PFIL_ALL, npf_ph_inet);
 		KASSERT(error == 0);
 	}
 	if (npf_ph_inet6) {
 		error = pfil_add_hook(npf_packet_handler, NULL,
-		    PFIL_WAITOK | PFIL_ALL, npf_ph_inet6);
+		    PFIL_ALL, npf_ph_inet6);
 		KASSERT(error == 0);
 	}
 fail:

Index: src/sys/netinet/in.c
diff -u src/sys/netinet/in.c:1.143 src/sys/netinet/in.c:1.144
--- src/sys/netinet/in.c:1.143	Fri Jun  8 15:01:51 2012
+++ src/sys/netinet/in.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: in.c,v 1.143 2012/06/08 15:01:51 gdt Exp $	*/
+/*	$NetBSD: in.c,v 1.144 2013/06/29 21:06:58 rmind Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,12 +91,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.143 2012/06/08 15:01:51 gdt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.144 2013/06/29 21:06:58 rmind Exp $");
 
 #include "opt_inet.h"
 #include "opt_inet_conf.h"
 #include "opt_mrouting.h"
-#include "opt_pfil_hooks.h"
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
@@ -114,6 +113,7 @@ __KERNEL_RCSID(0, "$NetBSD: in.c,v 1.143
 
 #include <net/if.h>
 #include <net/route.h>
+#include <net/pfil.h>
 
 #include <net/if_ether.h>
 
@@ -132,10 +132,6 @@ __KERNEL_RCSID(0, "$NetBSD: in.c,v 1.143
 #include <netinet/in_selsrc.h>
 #endif
 
-#ifdef PFIL_HOOKS
-#include <net/pfil.h>
-#endif
-
 static u_int in_mask2len(struct in_addr *);
 static void in_len2mask(struct in_addr *, u_int);
 static int in_lifaddr_ioctl(struct socket *, u_long, void *,
@@ -475,11 +471,10 @@ in_control(struct socket *so, u_long cmd
 	case SIOCSIFADDR:
 		error = in_ifinit(ifp, ia, satocsin(ifreq_getaddr(cmd, ifr)),
 		    1);
-#ifdef PFIL_HOOKS
-		if (error == 0)
-			(void)pfil_run_hooks(&if_pfil,
+		if (error == 0) {
+			(void)pfil_run_hooks(if_pfil,
 			    (struct mbuf **)SIOCSIFADDR, ifp, PFIL_IFADDR);
-#endif
+		}
 		break;
 
 	case SIOCSIFNETMASK:
@@ -525,11 +520,9 @@ in_control(struct socket *so, u_long cmd
 		if ((ifp->if_flags & IFF_BROADCAST) &&
 		    (ifra->ifra_broadaddr.sin_family == AF_INET))
 			ia->ia_broadaddr = ifra->ifra_broadaddr;
-#ifdef PFIL_HOOKS
 		if (error == 0)
-			(void)pfil_run_hooks(&if_pfil,
+			(void)pfil_run_hooks(if_pfil,
 			    (struct mbuf **)SIOCAIFADDR, ifp, PFIL_IFADDR);
-#endif
 		break;
 
 	case SIOCGIFALIAS:
@@ -547,10 +540,8 @@ in_control(struct socket *so, u_long cmd
 
 	case SIOCDIFADDR:
 		in_purgeaddr(&ia->ia_ifa);
-#ifdef PFIL_HOOKS
-		(void)pfil_run_hooks(&if_pfil, (struct mbuf **)SIOCDIFADDR,
+		(void)pfil_run_hooks(if_pfil, (struct mbuf **)SIOCDIFADDR,
 		    ifp, PFIL_IFADDR);
-#endif
 		break;
 
 #ifdef MROUTING

Index: src/sys/netinet/ip_input.c
diff -u src/sys/netinet/ip_input.c:1.307 src/sys/netinet/ip_input.c:1.308
--- src/sys/netinet/ip_input.c:1.307	Thu Jun 27 20:17:36 2013
+++ src/sys/netinet/ip_input.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_input.c,v 1.307 2013/06/27 20:17:36 christos Exp $	*/
+/*	$NetBSD: ip_input.c,v 1.308 2013/06/29 21:06:58 rmind Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,12 +91,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.307 2013/06/27 20:17:36 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.308 2013/06/29 21:06:58 rmind Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
 #include "opt_gateway.h"
-#include "opt_pfil_hooks.h"
 #include "opt_ipsec.h"
 #include "opt_mrouting.h"
 #include "opt_mbuftrace.h"
@@ -230,9 +229,7 @@ uint16_t ip_id;
 
 percpu_t *ipstat_percpu;
 
-#ifdef PFIL_HOOKS
-struct pfil_head inet_pfil_hook;
-#endif
+pfil_head_t *inet_pfil_hook;
 
 struct pool inmulti_pool;
 
@@ -327,15 +324,9 @@ ip_init(void)
 	ipflow_init(ip_hashsize);
 #endif
 
-#ifdef PFIL_HOOKS
 	/* Register our Packet Filter hook. */
-	inet_pfil_hook.ph_type = PFIL_TYPE_AF;
-	inet_pfil_hook.ph_af   = AF_INET;
-	i = pfil_head_register(&inet_pfil_hook);
-	if (i != 0)
-		printf("ip_init: WARNING: unable to register pfil hook, "
-		    "error %d\n", i);
-#endif /* PFIL_HOOKS */
+	inet_pfil_hook = pfil_head_create(PFIL_TYPE_AF, (void *)AF_INET);
+	KASSERT(inet_pfil_hook != NULL);
 
 #ifdef MBUFTRACE
 	MOWNER_ATTACH(&ip_tx_mowner);
@@ -531,7 +522,6 @@ ip_input(struct mbuf *m)
 	 */
 	m->m_flags |= M_CANFASTFWD;
 
-#ifdef PFIL_HOOKS
 	/*
 	 * Run through list of hooks for input packets.  If there are any
 	 * filters which require that additional packets in the flow are
@@ -552,7 +542,7 @@ ip_input(struct mbuf *m)
 		struct in_addr odst;
 
 		odst = ip->ip_dst;
-		if (pfil_run_hooks(&inet_pfil_hook, &m, m->m_pkthdr.rcvif,
+		if (pfil_run_hooks(inet_pfil_hook, &m, m->m_pkthdr.rcvif,
 		    PFIL_IN) != 0)
 			return;
 		if (m == NULL)
@@ -575,7 +565,6 @@ ip_input(struct mbuf *m)
 		 */
 		srcrt = (odst.s_addr != ip->ip_dst.s_addr);
 	}
-#endif /* PFIL_HOOKS */
 
 #ifdef ALTQ
 	/* XXX Temporary until ALTQ is changed to use a pfil hook */

Index: src/sys/netinet/ip_output.c
diff -u src/sys/netinet/ip_output.c:1.223 src/sys/netinet/ip_output.c:1.224
--- src/sys/netinet/ip_output.c:1.223	Thu Jun 27 19:38:16 2013
+++ src/sys/netinet/ip_output.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_output.c,v 1.223 2013/06/27 19:38:16 christos Exp $	*/
+/*	$NetBSD: ip_output.c,v 1.224 2013/06/29 21:06:58 rmind Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,9 +91,8 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.223 2013/06/27 19:38:16 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.224 2013/06/29 21:06:58 rmind Exp $");
 
-#include "opt_pfil_hooks.h"
 #include "opt_inet.h"
 #include "opt_ipsec.h"
 #include "opt_mrouting.h"
@@ -140,9 +139,7 @@ static struct ifnet *ip_multicast_if(str
 static void ip_mloopback(struct ifnet *, struct mbuf *,
     const struct sockaddr_in *);
 
-#ifdef PFIL_HOOKS
-extern struct pfil_head inet_pfil_hook;			/* XXX */
-#endif
+extern pfil_head_t *inet_pfil_hook;			/* XXX */
 
 int	ip_do_loopback_cksum = 0;
 
@@ -481,18 +478,16 @@ sendit:
 	}
 #endif
 
-#ifdef PFIL_HOOKS
 	/*
 	 * Run through list of hooks for output packets.
 	 */
-	if ((error = pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT)) != 0)
+	if ((error = pfil_run_hooks(inet_pfil_hook, &m, ifp, PFIL_OUT)) != 0)
 		goto done;
 	if (m == NULL)
 		goto done;
 
 	ip = mtod(m, struct ip *);
 	hlen = ip->ip_hl << 2;
-#endif /* PFIL_HOOKS */
 
 	m->m_pkthdr.csum_data |= hlen << 16;
 

Index: src/sys/netinet6/in6.c
diff -u src/sys/netinet6/in6.c:1.165 src/sys/netinet6/in6.c:1.166
--- src/sys/netinet6/in6.c:1.165	Thu Jun 20 13:56:29 2013
+++ src/sys/netinet6/in6.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6.c,v 1.165 2013/06/20 13:56:29 roy Exp $	*/
+/*	$NetBSD: in6.c,v 1.166 2013/06/29 21:06:58 rmind Exp $	*/
 /*	$KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $	*/
 
 /*
@@ -62,10 +62,9 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.165 2013/06/20 13:56:29 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.166 2013/06/29 21:06:58 rmind Exp $");
 
 #include "opt_inet.h"
-#include "opt_pfil_hooks.h"
 #include "opt_compat_netbsd.h"
 
 #include <sys/param.h>
@@ -87,6 +86,7 @@ __KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.16
 #include <net/if_types.h>
 #include <net/route.h>
 #include <net/if_dl.h>
+#include <net/pfil.h>
 
 #include <netinet/in.h>
 #include <netinet/in_var.h>
@@ -102,9 +102,6 @@ __KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.16
 
 #include <net/net_osdep.h>
 
-#ifdef PFIL_HOOKS
-#include <net/pfil.h>
-#endif
 #ifdef COMPAT_50
 #include <compat/netinet6/in6_var.h>
 #endif
@@ -754,11 +751,8 @@ in6_control1(struct socket *so, u_long c
 		 */
 		pfxlist_onlink_check();
 
-#ifdef PFIL_HOOKS
-		(void)pfil_run_hooks(&if_pfil, (struct mbuf **)SIOCAIFADDR_IN6,
+		(void)pfil_run_hooks(if_pfil, (struct mbuf **)SIOCAIFADDR_IN6,
 		    ifp, PFIL_IFADDR);
-#endif
-
 		break;
 	}
 
@@ -780,10 +774,8 @@ in6_control1(struct socket *so, u_long c
 		in6_purgeaddr(&ia->ia_ifa);
 		if (pr && pr->ndpr_refcnt == 0)
 			prelist_remove(pr);
-#ifdef PFIL_HOOKS
-		(void)pfil_run_hooks(&if_pfil, (struct mbuf **)SIOCDIFADDR_IN6,
+		(void)pfil_run_hooks(if_pfil, (struct mbuf **)SIOCDIFADDR_IN6,
 		    ifp, PFIL_IFADDR);
-#endif
 		break;
 	}
 

Index: src/sys/netinet6/ip6_forward.c
diff -u src/sys/netinet6/ip6_forward.c:1.71 src/sys/netinet6/ip6_forward.c:1.72
--- src/sys/netinet6/ip6_forward.c:1.71	Wed Jun  5 19:01:26 2013
+++ src/sys/netinet6/ip6_forward.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_forward.c,v 1.71 2013/06/05 19:01:26 christos Exp $	*/
+/*	$NetBSD: ip6_forward.c,v 1.72 2013/06/29 21:06:58 rmind Exp $	*/
 /*	$KAME: ip6_forward.c,v 1.109 2002/09/11 08:10:17 sakane Exp $	*/
 
 /*
@@ -31,11 +31,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.71 2013/06/05 19:01:26 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.72 2013/06/29 21:06:58 rmind Exp $");
 
 #include "opt_gateway.h"
 #include "opt_ipsec.h"
-#include "opt_pfil_hooks.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -51,6 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_forward.
 
 #include <net/if.h>
 #include <net/route.h>
+#include <net/pfil.h>
 
 #include <netinet/in.h>
 #include <netinet/in_var.h>
@@ -69,17 +69,11 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_forward.
 #include <netipsec/xform.h>
 #endif /* IPSEC */
 
-#ifdef PFIL_HOOKS
-#include <net/pfil.h>
-#endif
-
 #include <net/net_osdep.h>
 
 struct	route ip6_forward_rt;
 
-#ifdef PFIL_HOOKS
-extern struct pfil_head inet6_pfil_hook;	/* XXX */
-#endif
+extern pfil_head_t *inet6_pfil_hook;	/* XXX */
 
 /*
  * Forward a packet.  If some error occurs return the sender
@@ -391,17 +385,15 @@ ip6_forward(struct mbuf *m, int srcrt)
 	in6_clearscope(&ip6->ip6_src);
 	in6_clearscope(&ip6->ip6_dst);
 
-#ifdef PFIL_HOOKS
 	/*
 	 * Run through list of hooks for output packets.
 	 */
-	if ((error = pfil_run_hooks(&inet6_pfil_hook, &m, rt->rt_ifp,
+	if ((error = pfil_run_hooks(inet6_pfil_hook, &m, rt->rt_ifp,
 	    PFIL_OUT)) != 0)
 		goto senderr;
 	if (m == NULL)
 		goto freecopy;
 	ip6 = mtod(m, struct ip6_hdr *);
-#endif /* PFIL_HOOKS */
 
 	error = nd6_output(rt->rt_ifp, origifp, m, dst, rt);
 	if (error) {
@@ -422,9 +414,7 @@ ip6_forward(struct mbuf *m, int srcrt)
 		}
 	}
 
-#ifdef PFIL_HOOKS
  senderr:
-#endif
 	if (mcopy == NULL)
 		return;
 	switch (error) {

Index: src/sys/netinet6/ip6_input.c
diff -u src/sys/netinet6/ip6_input.c:1.142 src/sys/netinet6/ip6_input.c:1.143
--- src/sys/netinet6/ip6_input.c:1.142	Wed Jun  5 19:01:26 2013
+++ src/sys/netinet6/ip6_input.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_input.c,v 1.142 2013/06/05 19:01:26 christos Exp $	*/
+/*	$NetBSD: ip6_input.c,v 1.143 2013/06/29 21:06:58 rmind Exp $	*/
 /*	$KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $	*/
 
 /*
@@ -62,13 +62,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.142 2013/06/05 19:01:26 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.143 2013/06/29 21:06:58 rmind Exp $");
 
 #include "opt_gateway.h"
 #include "opt_inet.h"
 #include "opt_inet6.h"
 #include "opt_ipsec.h"
-#include "opt_pfil_hooks.h"
 #include "opt_compat_netbsd.h"
 
 #include <sys/param.h>
@@ -92,9 +91,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_input.c,
 #include <net/if_dl.h>
 #include <net/route.h>
 #include <net/netisr.h>
-#ifdef PFIL_HOOKS
 #include <net/pfil.h>
-#endif
 
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
@@ -148,9 +145,7 @@ int ip6_forward_srcrt;			/* XXX */
 int ip6_sourcecheck;			/* XXX */
 int ip6_sourcecheck_interval;		/* XXX */
 
-#ifdef PFIL_HOOKS
-struct pfil_head inet6_pfil_hook;
-#endif
+pfil_head_t *inet6_pfil_hook;
 
 percpu_t *ip6stat_percpu;
 
@@ -194,16 +189,9 @@ ip6_init(void)
 #ifdef GATEWAY
 	ip6flow_init(ip6_hashsize);
 #endif
-
-#ifdef PFIL_HOOKS
 	/* Register our Packet Filter hook. */
-	inet6_pfil_hook.ph_type = PFIL_TYPE_AF;
-	inet6_pfil_hook.ph_af   = AF_INET6;
-	i = pfil_head_register(&inet6_pfil_hook);
-	if (i != 0)
-		printf("ip6_init: WARNING: unable to register pfil hook, "
-		    "error %d\n", i);
-#endif /* PFIL_HOOKS */
+	inet6_pfil_hook = pfil_head_create(PFIL_TYPE_AF, (void *)AF_INET6);
+	KASSERT(inet6_pfil_hook != NULL);
 
 	ip6stat_percpu = percpu_alloc(sizeof(uint64_t) * IP6_NSTATS);
 }
@@ -345,7 +333,6 @@ ip6_input(struct mbuf *m)
 	 */
 	m->m_flags |= M_CANFASTFWD;
 
-#ifdef PFIL_HOOKS
 	/*
 	 * Run through list of hooks for input packets.  If there are any
 	 * filters which require that additional packets in the flow are
@@ -366,7 +353,7 @@ ip6_input(struct mbuf *m)
 		struct in6_addr odst;
 
 		odst = ip6->ip6_dst;
-		if (pfil_run_hooks(&inet6_pfil_hook, &m, m->m_pkthdr.rcvif,
+		if (pfil_run_hooks(inet6_pfil_hook, &m, m->m_pkthdr.rcvif,
 				   PFIL_IN) != 0)
 			return;
 		if (m == NULL)
@@ -374,7 +361,6 @@ ip6_input(struct mbuf *m)
 		ip6 = mtod(m, struct ip6_hdr *);
 		srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst);
 	}
-#endif /* PFIL_HOOKS */
 
 	IP6_STATINC(IP6_STAT_NXTHIST + ip6->ip6_nxt);
 

Index: src/sys/netinet6/ip6_output.c
diff -u src/sys/netinet6/ip6_output.c:1.153 src/sys/netinet6/ip6_output.c:1.154
--- src/sys/netinet6/ip6_output.c:1.153	Wed Jun  5 19:01:26 2013
+++ src/sys/netinet6/ip6_output.c	Sat Jun 29 21:06:58 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_output.c,v 1.153 2013/06/05 19:01:26 christos Exp $	*/
+/*	$NetBSD: ip6_output.c,v 1.154 2013/06/29 21:06:58 rmind Exp $	*/
 /*	$KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $	*/
 
 /*
@@ -62,12 +62,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.153 2013/06/05 19:01:26 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.154 2013/06/29 21:06:58 rmind Exp $");
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
 #include "opt_ipsec.h"
-#include "opt_pfil_hooks.h"
 
 #include <sys/param.h>
 #include <sys/malloc.h>
@@ -82,9 +81,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_output.c
 
 #include <net/if.h>
 #include <net/route.h>
-#ifdef PFIL_HOOKS
 #include <net/pfil.h>
-#endif
 
 #include <netinet/in.h>
 #include <netinet/in_var.h>
@@ -110,9 +107,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_output.c
 
 #include <net/net_osdep.h>
 
-#ifdef PFIL_HOOKS
-extern struct pfil_head inet6_pfil_hook;	/* XXX */
-#endif
+extern pfil_head_t *inet6_pfil_hook;	/* XXX */
 
 struct ip6_exthdrs {
 	struct mbuf *ip6e_ip6;
@@ -692,16 +687,15 @@ ip6_output(
 		ip6 = mtod(m, struct ip6_hdr *);
 	}
 
-#ifdef PFIL_HOOKS
 	/*
 	 * Run through list of hooks for output packets.
 	 */
-	if ((error = pfil_run_hooks(&inet6_pfil_hook, &m, ifp, PFIL_OUT)) != 0)
+	if ((error = pfil_run_hooks(inet6_pfil_hook, &m, ifp, PFIL_OUT)) != 0)
 		goto done;
 	if (m == NULL)
 		goto done;
 	ip6 = mtod(m, struct ip6_hdr *);
-#endif /* PFIL_HOOKS */
+
 	/*
 	 * Send the packet to the outgoing interface.
 	 * If necessary, do IPv6 fragmentation before sending.

Reply via email to