From owner-svn-src-head@FreeBSD.ORG Sat Aug 24 11:17:25 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id D63AE624; Sat, 24 Aug 2013 11:17:25 +0000 (UTC) (envelope-from andre@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id C2FFC285B; Sat, 24 Aug 2013 11:17:25 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r7OBHPet032343; Sat, 24 Aug 2013 11:17:25 GMT (envelope-from andre@svn.freebsd.org) Received: (from andre@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r7OBHPQ1032341; Sat, 24 Aug 2013 11:17:25 GMT (envelope-from andre@svn.freebsd.org) Message-Id: <201308241117.r7OBHPQ1032341@svn.freebsd.org> From: Andre Oppermann Date: Sat, 24 Aug 2013 11:17:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r254773 - head/sys/net X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 24 Aug 2013 11:17:26 -0000 Author: andre Date: Sat Aug 24 11:17:25 2013 New Revision: 254773 URL: http://svnweb.freebsd.org/changeset/base/254773 Log: Resolve the confusion between the head_list and the hook list. The linked list of pfil hooks is changed to "chain" and this term is applied consistently. The head_list remains with "list" term. Add KASSERT to vnet_pfil_uninit(). Update and extend comments. Reviewed by: eri (previous version) Modified: head/sys/net/pfil.c head/sys/net/pfil.h Modified: head/sys/net/pfil.c ============================================================================== --- head/sys/net/pfil.c Sat Aug 24 10:38:02 2013 (r254772) +++ head/sys/net/pfil.c Sat Aug 24 11:17:25 2013 (r254773) @@ -52,9 +52,9 @@ static struct mtx pfil_global_lock; MTX_SYSINIT(pfil_heads_lock, &pfil_global_lock, "pfil_head_list lock", MTX_DEF); -static struct packet_filter_hook *pfil_hook_get(int, struct pfil_head *); -static int pfil_list_add(pfil_list_t *, struct packet_filter_hook *, int); -static int pfil_list_remove(pfil_list_t *, pfil_func_t, void *); +static struct packet_filter_hook *pfil_chain_get(int, struct pfil_head *); +static int pfil_chain_add(pfil_chain_t *, struct packet_filter_hook *, int); +static int pfil_chain_remove(pfil_chain_t *, pfil_func_t, void *); LIST_HEAD(pfilheadhead, pfil_head); VNET_DEFINE(struct pfilheadhead, pfil_head_list); @@ -63,7 +63,7 @@ VNET_DEFINE(struct rmlock, pfil_lock); #define V_pfil_lock VNET(pfil_lock) /* - * pfil_run_hooks() runs the specified packet filter hooks. + * pfil_run_hooks() runs the specified packet filter hook chain. */ int pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp, @@ -76,8 +76,8 @@ pfil_run_hooks(struct pfil_head *ph, str PFIL_RLOCK(ph, &rmpt); KASSERT(ph->ph_nhooks >= 0, ("Pfil hook count dropped < 0")); - for (pfh = pfil_hook_get(dir, ph); pfh != NULL; - pfh = TAILQ_NEXT(pfh, pfil_link)) { + for (pfh = pfil_chain_get(dir, ph); pfh != NULL; + pfh = TAILQ_NEXT(pfh, pfil_chain)) { if (pfh->pfil_func != NULL) { rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir, inp); @@ -91,7 +91,7 @@ pfil_run_hooks(struct pfil_head *ph, str } static struct packet_filter_hook * -pfil_hook_get(int dir, struct pfil_head *ph) +pfil_chain_get(int dir, struct pfil_head *ph) { if (dir == PFIL_IN) @@ -163,6 +163,7 @@ pfil_wowned(struct pfil_head *ph) return (PFIL_WOWNED(ph)); } + /* * pfil_head_register() registers a pfil_head with the packet filter hook * mechanism. @@ -202,9 +203,9 @@ pfil_head_unregister(struct pfil_head *p PFIL_LIST_LOCK(); LIST_REMOVE(ph, ph_list); PFIL_LIST_UNLOCK(); - TAILQ_FOREACH_SAFE(pfh, &ph->ph_in, pfil_link, pfnext) + TAILQ_FOREACH_SAFE(pfh, &ph->ph_in, pfil_chain, pfnext) free(pfh, M_IFADDR); - TAILQ_FOREACH_SAFE(pfh, &ph->ph_out, pfil_link, pfnext) + TAILQ_FOREACH_SAFE(pfh, &ph->ph_out, pfil_chain, pfnext) free(pfh, M_IFADDR); PFIL_LOCK_DESTROY(ph); return (0); @@ -261,7 +262,7 @@ pfil_add_hook(pfil_func_t func, void *ar if (flags & PFIL_IN) { pfh1->pfil_func = func; pfh1->pfil_arg = arg; - err = pfil_list_add(&ph->ph_in, pfh1, flags & ~PFIL_OUT); + err = pfil_chain_add(&ph->ph_in, pfh1, flags & ~PFIL_OUT); if (err) goto locked_error; ph->ph_nhooks++; @@ -269,10 +270,10 @@ pfil_add_hook(pfil_func_t func, void *ar if (flags & PFIL_OUT) { pfh2->pfil_func = func; pfh2->pfil_arg = arg; - err = pfil_list_add(&ph->ph_out, pfh2, flags & ~PFIL_IN); + err = pfil_chain_add(&ph->ph_out, pfh2, flags & ~PFIL_IN); if (err) { if (flags & PFIL_IN) - pfil_list_remove(&ph->ph_in, func, arg); + pfil_chain_remove(&ph->ph_in, func, arg); goto locked_error; } ph->ph_nhooks++; @@ -291,7 +292,7 @@ error: /* * pfil_remove_hook removes a specific function from the packet filter hook - * list. + * chain. */ int pfil_remove_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph) @@ -300,12 +301,12 @@ pfil_remove_hook(pfil_func_t func, void PFIL_WLOCK(ph); if (flags & PFIL_IN) { - err = pfil_list_remove(&ph->ph_in, func, arg); + err = pfil_chain_remove(&ph->ph_in, func, arg); if (err == 0) ph->ph_nhooks--; } if ((err == 0) && (flags & PFIL_OUT)) { - err = pfil_list_remove(&ph->ph_out, func, arg); + err = pfil_chain_remove(&ph->ph_out, func, arg); if (err == 0) ph->ph_nhooks--; } @@ -313,15 +314,18 @@ pfil_remove_hook(pfil_func_t func, void return (err); } +/* + * Internal: Add a new pfil hook into a hook chain. + */ static int -pfil_list_add(pfil_list_t *list, struct packet_filter_hook *pfh1, int flags) +pfil_chain_add(pfil_chain_t *chain, struct packet_filter_hook *pfh1, int flags) { struct packet_filter_hook *pfh; /* * First make sure the hook is not already there. */ - TAILQ_FOREACH(pfh, list, pfil_link) + TAILQ_FOREACH(pfh, chain, pfil_chain) if (pfh->pfil_func == pfh1->pfil_func && pfh->pfil_arg == pfh1->pfil_arg) return (EEXIST); @@ -331,24 +335,23 @@ pfil_list_add(pfil_list_t *list, struct * the same path is followed in or out of the kernel. */ if (flags & PFIL_IN) - TAILQ_INSERT_HEAD(list, pfh1, pfil_link); + TAILQ_INSERT_HEAD(chain, pfh1, pfil_chain); else - TAILQ_INSERT_TAIL(list, pfh1, pfil_link); + TAILQ_INSERT_TAIL(chain, pfh1, pfil_chain); return (0); } /* - * pfil_list_remove is an internal function that takes a function off the - * specified list. + * Internal: Remove a pfil hook from a hook chain. */ static int -pfil_list_remove(pfil_list_t *list, pfil_func_t func, void *arg) +pfil_chain_remove(pfil_chain_t *chain, pfil_func_t func, void *arg) { struct packet_filter_hook *pfh; - TAILQ_FOREACH(pfh, list, pfil_link) + TAILQ_FOREACH(pfh, chain, pfil_chain) if (pfh->pfil_func == func && pfh->pfil_arg == arg) { - TAILQ_REMOVE(list, pfh, pfil_link); + TAILQ_REMOVE(chain, pfh, pfil_chain); free(pfh, M_IFADDR); return (0); } @@ -375,7 +378,8 @@ static int vnet_pfil_uninit(const void *unused) { - /* XXX should panic if list is not empty */ + KASSERT(LIST_EMPTY(&V_pfil_head_list), + ("%s: pfil_head_list %p not empty", __func__, &V_pfil_head_list)); PFIL_LOCK_DESTROY_REAL(&V_pfil_lock); return (0); } Modified: head/sys/net/pfil.h ============================================================================== --- head/sys/net/pfil.h Sat Aug 24 10:38:02 2013 (r254772) +++ head/sys/net/pfil.h Sat Aug 24 11:17:25 2013 (r254773) @@ -48,10 +48,11 @@ typedef int (*pfil_func_t)(void *, struc /* * The packet filter hooks are designed for anything to call them to - * possibly intercept the packet. + * possibly intercept the packet. Multiple filter hooks are chained + * together and after each other in the specified order. */ struct packet_filter_hook { - TAILQ_ENTRY(packet_filter_hook) pfil_link; + TAILQ_ENTRY(packet_filter_hook) pfil_chain; pfil_func_t pfil_func; void *pfil_arg; }; @@ -61,16 +62,20 @@ struct packet_filter_hook { #define PFIL_WAITOK 0x00000004 #define PFIL_ALL (PFIL_IN|PFIL_OUT) -typedef TAILQ_HEAD(pfil_list, packet_filter_hook) pfil_list_t; +typedef TAILQ_HEAD(pfil_chain, packet_filter_hook) pfil_chain_t; #define PFIL_TYPE_AF 1 /* key is AF_* type */ #define PFIL_TYPE_IFNET 2 /* key is ifnet pointer */ #define PFIL_FLAG_PRIVATE_LOCK 0x01 /* Personal lock instead of global */ +/* + * A pfil head is created by each protocol or packet intercept point. + * For packet is then run through the hook chain for inspection. + */ struct pfil_head { - pfil_list_t ph_in; - pfil_list_t ph_out; + pfil_chain_t ph_in; + pfil_chain_t ph_out; int ph_type; int ph_nhooks; #if defined( __linux__ ) || defined( _WIN32 ) @@ -89,11 +94,20 @@ struct pfil_head { LIST_ENTRY(pfil_head) ph_list; }; +/* Public functions for pfil hook management by packet filters. */ +struct pfil_head *pfil_head_get(int, u_long); int pfil_add_hook(pfil_func_t, void *, int, struct pfil_head *); int pfil_remove_hook(pfil_func_t, void *, int, struct pfil_head *); + +/* Public functions to run the packet inspection by protocols. */ int pfil_run_hooks(struct pfil_head *, struct mbuf **, struct ifnet *, int, struct inpcb *inp); +/* Public functions for pfil head management by protocols. */ +int pfil_head_register(struct pfil_head *); +int pfil_head_unregister(struct pfil_head *); + +/* Internal pfil locking functions. */ struct rm_priotracker; /* Do not require including rmlock header */ int pfil_try_rlock(struct pfil_head *, struct rm_priotracker *); void pfil_rlock(struct pfil_head *, struct rm_priotracker *); @@ -102,11 +116,6 @@ void pfil_wlock(struct pfil_head *); void pfil_wunlock(struct pfil_head *); int pfil_wowned(struct pfil_head *ph); -int pfil_head_register(struct pfil_head *); -int pfil_head_unregister(struct pfil_head *); - -struct pfil_head *pfil_head_get(int, u_long); - #define PFIL_HOOKED(p) ((p)->ph_nhooks > 0) #define PFIL_LOCK_INIT_REAL(l, t) \ rm_init_flags(l, "PFil " t " rmlock", RM_RECURSE)