svn commit: r243415 - user/andre/tcp_workqueue/sys/net

Andre Oppermann andre at FreeBSD.org
Thu Nov 22 21:47:22 UTC 2012


Author: andre
Date: Thu Nov 22 21:47:21 2012
New Revision: 243415
URL: http://svnweb.freebsd.org/changeset/base/243415

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 applied consistently.  The head_list remains with "list"
  term.
  
  Add KASSERT to vnet_pfil_uninit().
  
  Update and extend comments.

Modified:
  user/andre/tcp_workqueue/sys/net/pfil.c
  user/andre/tcp_workqueue/sys/net/pfil.h

Modified: user/andre/tcp_workqueue/sys/net/pfil.c
==============================================================================
--- user/andre/tcp_workqueue/sys/net/pfil.c	Thu Nov 22 20:43:09 2012	(r243414)
+++ user/andre/tcp_workqueue/sys/net/pfil.c	Thu Nov 22 21:47:21 2012	(r243415)
@@ -50,9 +50,9 @@
 static struct mtx pfil_global_lock;
 MTX_SYSINIT(pfil_global_lock, &pfil_global_lock, "pfil_head_list lock", MTX_DEF);
 
-static int pfil_list_add(pfil_list_t *, struct packet_filter_hook *, int,
-    uint8_t);
-static int pfil_list_remove(pfil_list_t *, pfil_func_t, void *);
+static int 	pfil_chain_add(pfil_chain_t *, struct packet_filter_hook *,
+		    int, uint8_t);
+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,8 +63,9 @@ VNET_DEFINE(struct rmlock, pfil_lock);
 /*
  * pfil_run_hooks() runs the specified packet filter hooks.
  *
- * The cookie, if set, skips all hooks before the hook with
- * the same cookie and continues with the next hook after it.
+ * The cookie, if set, skips all hooks before and including
+ * the hook with the same cookie and continues with the next
+ * hook after it.
  */
 int
 pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
@@ -75,7 +76,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)
@@ -97,8 +98,8 @@ pfil_run_inject(struct pfil_head *ph, st
 
 	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 (cookie != 0) {
 			/* Continue on the next hook. */
 			if (pfh->pfil_cookie == cookie)
@@ -171,6 +172,7 @@ pfil_wowned(struct pfil_head *ph)
 {
 	return PFIL_WOWNED(ph);
 }
+
 /*
  * pfil_head_register() registers a pfil_head with the packet filter hook
  * mechanism.
@@ -210,9 +212,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);
@@ -288,16 +290,16 @@ pfil_add_hook_order(pfil_func_t func, vo
 	}
 	PFIL_WLOCK(ph);
 	if (flags & PFIL_IN) {
-		err = pfil_list_add(&ph->ph_in, pfh1, flags & ~PFIL_OUT, order);
+		err = pfil_chain_add(&ph->ph_in, pfh1, flags & ~PFIL_OUT, order);
 		if (err)
 			goto locked_error;
 		ph->ph_nhooks++;
 	}
 	if (flags & PFIL_OUT) {
-		err = pfil_list_add(&ph->ph_out, pfh2, flags & ~PFIL_IN, order);
+		err = pfil_chain_add(&ph->ph_out, pfh2, flags & ~PFIL_IN, order);
 		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++;
@@ -325,12 +327,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--;
 	}
@@ -341,20 +343,20 @@ pfil_remove_hook(pfil_func_t func, void 
 int
 pfil_get_cookie(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
 {
-	pfil_list_t *list;
+	pfil_chain_t *chain;
 	struct packet_filter_hook *pfh;
 	struct rm_priotracker tracker;
 	int cookie = 0;
 
 	PFIL_RLOCK(ph, &tracker);
 	if (flags & PFIL_IN)
-		list = &ph->ph_in;
+		chain = &ph->ph_in;
 	else if (flags & PFIL_OUT)
-		list = &ph->ph_out;
+		chain = &ph->ph_out;
 	else
 		goto out;
 
-	TAILQ_FOREACH(pfh, list, pfil_link)
+	TAILQ_FOREACH(pfh, chain, pfil_chain)
 		if (pfh->pfil_func == func &&
 		    pfh->pfil_arg == arg)
 			cookie = pfh->pfil_cookie;
@@ -363,8 +365,11 @@ out:
 	return (cookie);
 }
 
+/*
+ * 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,
     uint8_t order)
 {
 	struct packet_filter_hook *pfh;
@@ -372,7 +377,7 @@ pfil_list_add(pfil_list_t *list, struct 
 	/*
 	 * 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);
@@ -382,38 +387,37 @@ pfil_list_add(pfil_list_t *list, struct 
 	 * the same path is followed in or out of the kernel.
 	 */
 	if (flags & PFIL_IN) {
-		TAILQ_FOREACH(pfh, list, pfil_link) {
+		TAILQ_FOREACH(pfh, chain, pfil_chain) {
 			if (pfh->pfil_order <= order)
 				break;
 		}
 		if (pfh == NULL)
-			TAILQ_INSERT_HEAD(list, pfh1, pfil_link);
+			TAILQ_INSERT_HEAD(chain, pfh1, pfil_chain);
 		else
-			TAILQ_INSERT_BEFORE(pfh, pfh1, pfil_link);
+			TAILQ_INSERT_BEFORE(pfh, pfh1, pfil_chain);
 	} else {
-		TAILQ_FOREACH_REVERSE(pfh, list, pfil_list, pfil_link)
+		TAILQ_FOREACH_REVERSE(pfh, chain, pfil_chain, pfil_chain)
 			if (pfh->pfil_order >= order)
 				break;
 		if (pfh == NULL)
-			TAILQ_INSERT_TAIL(list, pfh1, pfil_link);
+			TAILQ_INSERT_TAIL(chain, pfh1, pfil_chain);
 		else
-			TAILQ_INSERT_AFTER(list, pfh, pfh1, pfil_link);
+			TAILQ_INSERT_AFTER(chain, pfh, 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);
 		}
@@ -440,7 +444,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: user/andre/tcp_workqueue/sys/net/pfil.h
==============================================================================
--- user/andre/tcp_workqueue/sys/net/pfil.h	Thu Nov 22 20:43:09 2012	(r243414)
+++ user/andre/tcp_workqueue/sys/net/pfil.h	Thu Nov 22 21:47:21 2012	(r243415)
@@ -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;
 	int	 pfil_cookie;
@@ -68,16 +69,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;
 	struct rmlock	*ph_plock;	/* Pointer to the used lock */
@@ -92,12 +97,14 @@ struct pfil_head {
 	LIST_ENTRY(pfil_head) ph_list;
 };
 
+/* Public functions for pfil head management by protocols. */
 int	pfil_add_hook(pfil_func_t, void *, int, struct pfil_head *);
 int	pfil_add_hook_order(pfil_func_t, void *, char *, int, uint8_t,
 	    struct pfil_head *);
 int	pfil_get_cookie(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);
 int	pfil_run_inject(struct pfil_head *, struct mbuf **, struct ifnet *,


More information about the svn-src-user mailing list