Module Name:    src
Committed By:   christos
Date:           Mon Dec 26 23:21:49 UTC 2016

Modified Files:
        src/sys/dist/pf/net: pf_if.c
        src/sys/external/bsd/ipf/netinet: ip_fil_netbsd.c
        src/sys/net: if.c if_pppoe.c if_spppsubr.c pfil.c pfil.h

Log Message:
pfil(9) improvements to handle address changes:

Add:
  PFIL_IFADDR     call on interface reconfig (mbuf is ioctl #)
  PFIL_IFNET      call on interface attach/detach (mbuf is PFIL_IFNET_*)

from rmind@


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/sys/dist/pf/net/pf_if.c
cvs rdiff -u -r1.19 -r1.20 src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c
cvs rdiff -u -r1.368 -r1.369 src/sys/net/if.c
cvs rdiff -u -r1.121 -r1.122 src/sys/net/if_pppoe.c
cvs rdiff -u -r1.163 -r1.164 src/sys/net/if_spppsubr.c
cvs rdiff -u -r1.28 -r1.29 src/sys/net/pfil.c
cvs rdiff -u -r1.31 -r1.32 src/sys/net/pfil.h

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

Modified files:

Index: src/sys/dist/pf/net/pf_if.c
diff -u src/sys/dist/pf/net/pf_if.c:1.31 src/sys/dist/pf/net/pf_if.c:1.32
--- src/sys/dist/pf/net/pf_if.c:1.31	Wed Jul 20 03:37:51 2016
+++ src/sys/dist/pf/net/pf_if.c	Mon Dec 26 18:21:49 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: pf_if.c,v 1.31 2016/07/20 07:37:51 ozaki-r Exp $	*/
+/*	$NetBSD: pf_if.c,v 1.32 2016/12/26 23:21:49 christos Exp $	*/
 /*	$OpenBSD: pf_if.c,v 1.47 2007/07/13 09:17:48 markus Exp $ */
 
 /*
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pf_if.c,v 1.31 2016/07/20 07:37:51 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pf_if.c,v 1.32 2016/12/26 23:21:49 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -87,8 +87,8 @@ int		 pfi_unmask(void *);
 void		 pfi_init_groups(struct ifnet *);
 void		 pfi_destroy_groups(struct ifnet *);
 
-int		 pfil_ifnet_wrapper(void *, struct mbuf **, struct ifnet *, int);
-int		 pfil_ifaddr_wrapper(void *, struct mbuf **, struct ifnet *, int);
+void		 pfil_ifnet_wrapper(void *, u_long, void *);
+void		 pfil_ifaddr_wrapper(void *, u_long, void *);
 #endif
 
 RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
@@ -138,8 +138,8 @@ pfi_initialize(void)
 	pserialize_read_exit(s);
 	curlwp_bindx(bound);
 
-	pfil_add_hook(pfil_ifnet_wrapper, NULL, PFIL_IFNET, if_pfil);
-	pfil_add_hook(pfil_ifaddr_wrapper, NULL, PFIL_IFADDR, if_pfil);
+	pfil_add_ihook(pfil_ifnet_wrapper, NULL, PFIL_IFNET, if_pfil);
+	pfil_add_ihook(pfil_ifaddr_wrapper, NULL, PFIL_IFADDR, if_pfil);
 #endif /* __NetBSD__ */
 }
 
@@ -152,8 +152,8 @@ pfi_destroy(void)
 	int s;
 	int bound;
 
-	pfil_remove_hook(pfil_ifaddr_wrapper, NULL, PFIL_IFADDR, if_pfil);
-	pfil_remove_hook(pfil_ifnet_wrapper, NULL, PFIL_IFNET, if_pfil);
+	pfil_remove_ihook(pfil_ifaddr_wrapper, NULL, PFIL_IFADDR, if_pfil);
+	pfil_remove_ihook(pfil_ifnet_wrapper, NULL, PFIL_IFNET, if_pfil);
 
 	bound = curlwp_bind();
 	s = pserialize_read_enter();
@@ -885,10 +885,10 @@ pfi_destroy_groups(struct ifnet *ifp)
 	if_destroy_groups(ifp);
 }
 
-int
-pfil_ifnet_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
+void
+pfil_ifnet_wrapper(void *arg, u_long cmd, void *arg2)
 {
-	u_long cmd = (u_long)mp;
+	ifnet_t *ifp = arg2;
 
 	switch (cmd) {
 	case PFIL_IFNET_ATTACH:
@@ -904,14 +904,12 @@ pfil_ifnet_wrapper(void *arg, struct mbu
 	default:
 		panic("pfil_ifnet_wrapper: unexpected cmd %lu", cmd);
 	}
-
-	return (0);
 }
 
-int
-pfil_ifaddr_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
+void
+pfil_ifaddr_wrapper(void *arg, u_long cmd, void *arg2)
 {
-	u_long cmd = (u_long)mp;
+	struct ifaddr *ifa = arg2;
 
 	switch (cmd) {
 	case SIOCSIFADDR:
@@ -921,12 +919,10 @@ pfil_ifaddr_wrapper(void *arg, struct mb
 	case SIOCAIFADDR_IN6:
 	case SIOCDIFADDR_IN6:
 #endif /* INET6 */
-		pfi_kifaddr_update(ifp->if_pf_kif);
+		pfi_kifaddr_update(ifa->ifa_ifp->if_pf_kif);
 		break;
 	default:
 		panic("pfil_ifaddr_wrapper: unexpected ioctl %lu", cmd);
 	}
-
-	return (0);
 }
 #endif /* __NetBSD__ */

Index: src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c
diff -u src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c:1.19 src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c:1.20
--- src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c:1.19	Thu Dec  8 00:16:33 2016
+++ src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c	Mon Dec 26 18:21:49 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_fil_netbsd.c,v 1.19 2016/12/08 05:16:33 ozaki-r Exp $	*/
+/*	$NetBSD: ip_fil_netbsd.c,v 1.20 2016/12/26 23:21:49 christos 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.19 2016/12/08 05:16:33 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_fil_netbsd.c,v 1.20 2016/12/26 23:21:49 christos 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";
@@ -268,10 +268,13 @@ ipf_check_wrapper6(void *arg, struct mbu
 
 
 # if defined(PFIL_TYPE_IFNET) && defined(PFIL_IFNET)
-static int ipf_pfilsync(void *, struct mbuf **, struct ifnet *, int);
 
-static int
-ipf_pfilsync(void *hdr, struct mbuf **mp, struct ifnet *ifp, int dir)
+#  if (__NetBSD_Version__ >= 799000400)
+
+static void ipf_pfilsync(void *, unsigned long, void *);
+
+static void
+ipf_pfilsync(void *hdr, unsigned long cmd, void *arg2)
 {
 	/*
 	 * The interface pointer is useless for create (we have nothing to
@@ -281,8 +284,20 @@ ipf_pfilsync(void *hdr, struct mbuf **mp
 	 * pointer, so it's not much use then, either.
 	 */
 	ipf_sync(&ipfmain, NULL);
+}
+
+#  else
+
+static int ipf_pfilsync(void *, struct mbuf **, struct ifnet *, int);
+
+static int
+ipf_pfilsync(void *hdr, struct mbuf **mp, struct ifnet *ifp, int dir)
+{
+	ipf_sync(&ipfmain, NULL);
 	return 0;
 }
+
+#  endif
 # endif
 
 #endif /* __NetBSD_Version__ >= 105110000 */
@@ -445,8 +460,13 @@ ipfattach(ipf_main_softc_t *softc)
 
 # if defined(PFIL_TYPE_IFNET) && defined(PFIL_IFNET)
 	if (ph_ifsync != NULL)
+#if (__NetBSD_Version__ >= 799000400)
 		(void) pfil_add_hook((void *)ipf_pfilsync, NULL,
 				     PFIL_IFNET, ph_ifsync);
+#else
+		(void) pfil_add_hook((void *)ipf_pfilsync, NULL,
+				     PFIL_IFNET, ph_ifsync);
+#endif
 # endif
 #endif
 

Index: src/sys/net/if.c
diff -u src/sys/net/if.c:1.368 src/sys/net/if.c:1.369
--- src/sys/net/if.c:1.368	Thu Dec 15 04:28:06 2016
+++ src/sys/net/if.c	Mon Dec 26 18:21:49 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.368 2016/12/15 09:28:06 ozaki-r Exp $	*/
+/*	$NetBSD: if.c,v 1.369 2016/12/26 23:21:49 christos Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.368 2016/12/15 09:28:06 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.369 2016/12/26 23:21:49 christos Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -194,7 +194,7 @@ static LIST_HEAD(, if_clone) if_cloners 
 static int if_cloners_count;
 
 /* Packet filtering hook for interfaces. */
-pfil_head_t *	if_pfil;
+pfil_head_t *			if_pfil __read_mostly;
 
 static kauth_listener_t if_listener;
 
@@ -690,8 +690,7 @@ if_initialize(ifnet_t *ifp)
 	IFQ_LOCK_INIT(&ifp->if_snd);
 
 	ifp->if_pfil = pfil_head_create(PFIL_TYPE_IFNET, ifp);
-	(void)pfil_run_hooks(if_pfil,
-	    (struct mbuf **)PFIL_IFNET_ATTACH, ifp, PFIL_IFNET);
+	pfil_run_ifhooks(if_pfil, PFIL_IFNET_ATTACH, ifp);
 
 	IF_AFDATA_LOCK_INIT(ifp);
 
@@ -1433,8 +1432,7 @@ again:
 		}
 	}
 
-	(void)pfil_run_hooks(if_pfil,
-	    (struct mbuf **)PFIL_IFNET_DETACH, ifp, PFIL_IFNET);
+	pfil_run_ifhooks(if_pfil, PFIL_IFNET_DETACH, ifp);
 	(void)pfil_head_destroy(ifp->if_pfil);
 
 	/* Announce that the interface is gone. */

Index: src/sys/net/if_pppoe.c
diff -u src/sys/net/if_pppoe.c:1.121 src/sys/net/if_pppoe.c:1.122
--- src/sys/net/if_pppoe.c:1.121	Fri Dec 16 03:47:36 2016
+++ src/sys/net/if_pppoe.c	Mon Dec 26 18:21:49 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_pppoe.c,v 1.121 2016/12/16 08:47:36 knakahara Exp $ */
+/* $NetBSD: if_pppoe.c,v 1.122 2016/12/26 23:21:49 christos Exp $ */
 
 /*-
  * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.121 2016/12/16 08:47:36 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.122 2016/12/26 23:21:49 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "pppoe.h"
@@ -235,7 +235,7 @@ static struct pppoe_softc * pppoe_find_s
     struct ifnet *, krw_t);
 static struct mbuf *pppoe_get_mbuf(size_t len);
 
-static int pppoe_ifattach_hook(void *, struct mbuf **, struct ifnet *, int);
+static void pppoe_ifattach_hook(void *, u_long, void *);
 
 static LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list;
 static krwlock_t pppoe_softc_list_lock;
@@ -339,7 +339,7 @@ pppoe_clone_create(struct if_clone *ifc,
 
 	bpf_attach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0);
 	if (LIST_EMPTY(&pppoe_softc_list)) {
-		pfil_add_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil);
+		pfil_add_ihook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil);
 	}
 
 	sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
@@ -364,7 +364,7 @@ pppoe_clone_destroy(struct ifnet *ifp)
 	LIST_REMOVE(sc, sc_list);
 
 	if (LIST_EMPTY(&pppoe_softc_list)) {
-		pfil_remove_hook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil);
+		pfil_remove_ihook(pppoe_ifattach_hook, NULL, PFIL_IFNET, if_pfil);
 	}
 	rw_exit(&pppoe_softc_list_lock);
 

Index: src/sys/net/if_spppsubr.c
diff -u src/sys/net/if_spppsubr.c:1.163 src/sys/net/if_spppsubr.c:1.164
--- src/sys/net/if_spppsubr.c:1.163	Mon Dec 12 19:35:11 2016
+++ src/sys/net/if_spppsubr.c	Mon Dec 26 18:21:49 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_spppsubr.c,v 1.163 2016/12/13 00:35:11 knakahara Exp $	 */
+/*	$NetBSD: if_spppsubr.c,v 1.164 2016/12/26 23:21:49 christos Exp $	 */
 
 /*
  * Synchronous PPP/Cisco link level subroutines.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.163 2016/12/13 00:35:11 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.164 2016/12/26 23:21:49 christos Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -5290,8 +5290,7 @@ sppp_set_ip_addrs_work(struct work *wk, 
 			    ifp->if_xname, __func__, error);
 		}
 		if (!error) {
-			(void)pfil_run_hooks(if_pfil,
-			    (struct mbuf **)SIOCAIFADDR, ifp, PFIL_IFADDR);
+			pfil_run_addrhooks(if_pfil, SIOCAIFADDR, ifa);
 		}
 	}
 
@@ -5521,8 +5520,7 @@ sppp_set_ip6_addr(struct sppp *sp, const
 			    ifp->if_xname, __func__, error);
 		}
 		if (!error) {
-			(void)pfil_run_hooks(if_pfil,
-			    (struct mbuf **)SIOCAIFADDR_IN6, ifp, PFIL_IFADDR);
+			pfil_run_addrhooks(if_pfil, SIOCAIFADDR_IN6, ifa);
 		}
 	}
 }

Index: src/sys/net/pfil.c
diff -u src/sys/net/pfil.c:1.28 src/sys/net/pfil.c:1.29
--- src/sys/net/pfil.c:1.28	Sat Jun 29 17:06:58 2013
+++ src/sys/net/pfil.c	Mon Dec 26 18:21:49 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: pfil.c,v 1.28 2013/06/29 21:06:58 rmind Exp $	*/
+/*	$NetBSD: pfil.c,v 1.29 2016/12/26 23:21:49 christos Exp $	*/
 
 /*
  * Copyright (c) 2013 Mindaugas Rasiukevicius <rmind at NetBSD org>
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pfil.c,v 1.28 2013/06/29 21:06:58 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pfil.c,v 1.29 2016/12/26 23:21:49 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -40,8 +40,11 @@ __KERNEL_RCSID(0, "$NetBSD: pfil.c,v 1.2
 
 #define	MAX_HOOKS	8
 
+/* Func is either pfil_func_t or pfil_ifunc_t. */
+typedef void		(*pfil_polyfunc_t)(void);
+
 typedef struct {
-	pfil_func_t	pfil_func;
+	pfil_polyfunc_t pfil_func;
 	void *		pfil_arg;
 } pfil_hook_t;
 
@@ -50,9 +53,11 @@ typedef struct {
 	u_int		nhooks;
 } pfil_list_t;
 
+CTASSERT(PFIL_IN == 1);
+CTASSERT(PFIL_OUT == 2);
+
 struct pfil_head {
-	pfil_list_t	ph_in;
-	pfil_list_t	ph_out;
+	pfil_list_t	ph_inout[2];
 	pfil_list_t	ph_ifaddr;
 	pfil_list_t	ph_ifevent;
 	int		ph_type;
@@ -116,9 +121,8 @@ pfil_hook_get(int dir, pfil_head_t *ph)
 {
 	switch (dir) {
 	case PFIL_IN:
-		return &ph->ph_in;
 	case PFIL_OUT:
-		return &ph->ph_out;
+		return &ph->ph_inout[dir];
 	case PFIL_IFADDR:
 		return &ph->ph_ifaddr;
 	case PFIL_IFNET:
@@ -128,7 +132,7 @@ pfil_hook_get(int dir, pfil_head_t *ph)
 }
 
 static int
-pfil_list_add(pfil_list_t *phlist, pfil_func_t func, void *arg, int flags)
+pfil_list_add(pfil_list_t *phlist, pfil_polyfunc_t func, void *arg, int flags)
 {
 	const u_int nhooks = phlist->nhooks;
 	pfil_hook_t *pfh;
@@ -173,8 +177,6 @@ pfil_list_add(pfil_list_t *phlist, pfil_
  *	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_add_hook(pfil_func_t func, void *arg, int flags, pfil_head_t *ph)
@@ -182,6 +184,7 @@ pfil_add_hook(pfil_func_t func, void *ar
 	int error = 0;
 
 	KASSERT(func != NULL);
+	KASSERT((flags & ~PFIL_ALL) == 0);
 
 	for (u_int i = 0; i < __arraycount(pfil_flag_cases); i++) {
 		const int fcase = pfil_flag_cases[i];
@@ -191,7 +194,8 @@ pfil_add_hook(pfil_func_t func, void *ar
 			continue;
 		}
 		phlist = pfil_hook_get(fcase, ph);
-		if ((error = pfil_list_add(phlist, func, arg, flags)) != 0) {
+		error = pfil_list_add(phlist, (pfil_polyfunc_t)func, arg, flags);
+		if (error) {
 			break;
 		}
 	}
@@ -202,10 +206,27 @@ pfil_add_hook(pfil_func_t func, void *ar
 }
 
 /*
+ * pfil_add_hook: add an interface-event function (hook) to the packet
+ * filter head.  The possible flags are:
+ *
+ *	PFIL_IFADDR	call on interface reconfig (mbuf is ioctl #)
+ *	PFIL_IFNET	call on interface attach/detach (mbuf is PFIL_IFNET_*)
+ */
+int
+pfil_add_ihook(pfil_ifunc_t func, void *arg, int flags, pfil_head_t *ph)
+{
+	pfil_list_t *phlist;
+
+	KASSERT(flags == PFIL_IFADDR || flags == PFIL_IFNET);
+	phlist = pfil_hook_get(flags, ph);
+	return pfil_list_add(phlist, (pfil_polyfunc_t)func, arg, flags);
+}
+
+/*
  * pfil_list_remove: remove the hook from a specified list.
  */
 static int
-pfil_list_remove(pfil_list_t *phlist, pfil_func_t func, void *arg)
+pfil_list_remove(pfil_list_t *phlist, pfil_polyfunc_t func, void *arg)
 {
 	const u_int nhooks = phlist->nhooks;
 
@@ -238,43 +259,72 @@ pfil_remove_hook(pfil_func_t func, void 
 			continue;
 		}
 		pflist = pfil_hook_get(fcase, ph);
-		(void)pfil_list_remove(pflist, func, arg);
+		(void)pfil_list_remove(pflist, (pfil_polyfunc_t)func, arg);
 	}
 	return 0;
 }
 
+int
+pfil_remove_ihook(pfil_ifunc_t func, void *arg, int flags, pfil_head_t *ph)
+{
+	pfil_list_t *pflist;
+
+	KASSERT(flags == PFIL_IFADDR || flags == PFIL_IFNET);
+	pflist = pfil_hook_get(flags, ph);
+	(void)pfil_list_remove(pflist, (pfil_polyfunc_t)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;
+	struct mbuf *m = mp ? *mp : NULL;
 	pfil_list_t *phlist;
 	int ret = 0;
 
-	if ((phlist = pfil_hook_get(dir, ph)) == NULL) {
+	KASSERT((dir & ~PFIL_ALL) == 0);
+	if (__predict_false((phlist = &ph->ph_inout[dir]) == 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;
+		pfil_func_t func = (pfil_func_t)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)
+		ret = (*func)(pfh->pfil_arg, &m, ifp, dir);
+		if (m == NULL || ret)
 			break;
 	}
 
-	if (pass_mbuf) {
+	if (mp) {
 		*mp = m;
 	}
 	return ret;
 }
+
+void
+pfil_run_addrhooks(pfil_head_t *ph, u_long cmd, struct ifaddr *ifa)
+{
+	pfil_list_t *phlist = &ph->ph_ifaddr;
+
+	for (u_int i = 0; i < phlist->nhooks; i++) {
+		pfil_hook_t *pfh = &phlist->hooks[i];
+		pfil_ifunc_t func = (pfil_ifunc_t)pfh->pfil_func;
+		(*func)(pfh->pfil_arg, cmd, (void *)ifa);
+	}
+}
+
+void
+pfil_run_ifhooks(pfil_head_t *ph, u_long cmd, struct ifnet *ifp)
+{
+	pfil_list_t *phlist = &ph->ph_ifevent;
+
+	for (u_int i = 0; i < phlist->nhooks; i++) {
+		pfil_hook_t *pfh = &phlist->hooks[i];
+		pfil_ifunc_t func = (pfil_ifunc_t)pfh->pfil_func;
+		(*func)(pfh->pfil_arg, cmd, (void *)ifp);
+	}
+}

Index: src/sys/net/pfil.h
diff -u src/sys/net/pfil.h:1.31 src/sys/net/pfil.h:1.32
--- src/sys/net/pfil.h:1.31	Sat Jun 29 17:06:58 2013
+++ src/sys/net/pfil.h	Mon Dec 26 18:21:49 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: pfil.h,v 1.31 2013/06/29 21:06:58 rmind Exp $	*/
+/*	$NetBSD: pfil.h,v 1.32 2016/12/26 23:21:49 christos Exp $	*/
 
 /*
  * Copyright (c) 1996 Matthew R. Green
@@ -33,12 +33,14 @@
 
 struct mbuf;
 struct ifnet;
+struct ifaddr;
 
 /*
  * The packet filter hooks are designed for anything to call them to
  * possibly intercept the packet.
  */
 typedef int (*pfil_func_t)(void *, struct mbuf **, struct ifnet *, int);
+typedef void (*pfil_ifunc_t)(void *, unsigned long, void *);
 
 #define PFIL_IN		0x00000001
 #define PFIL_OUT	0x00000002
@@ -51,16 +53,22 @@ typedef int (*pfil_func_t)(void *, struc
 #define	PFIL_IFNET_DETACH	1
 
 #define	PFIL_TYPE_AF		1	/* key is AF_* type */
-#define	PFIL_TYPE_IFNET		2	/* key is ifnet pointer */
+#define	PFIL_TYPE_IFNET		2	/* key is ifnet or ifaddr pointer */
 
 typedef struct pfil_head	pfil_head_t;
 
 #ifdef _KERNEL
 
 int	pfil_run_hooks(pfil_head_t *, struct mbuf **, struct ifnet *, int);
+void	pfil_run_addrhooks(pfil_head_t *, unsigned long, struct ifaddr *);
+void	pfil_run_ifhooks(pfil_head_t *, unsigned long, struct ifnet *);
+
 int	pfil_add_hook(pfil_func_t, void *, int, pfil_head_t *);
 int	pfil_remove_hook(pfil_func_t, void *, int, pfil_head_t *);
 
+int	pfil_add_ihook(pfil_ifunc_t, void *, int, pfil_head_t *);
+int	pfil_remove_ihook(pfil_ifunc_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 *);

Reply via email to