[Zrouter-src-freebsd] ZRouter.org: push to FreeBSD HEAD tree

zrouter-src-freebsd at zrouter.org zrouter-src-freebsd at zrouter.org
Wed Feb 1 10:56:31 UTC 2012


details:   http://zrouter.org/hg/FreeBSD/head//rev/f683213c97d4
changeset: 307:f683213c97d4
user:      ray at terran.dlink.ua
date:      Wed Feb 01 11:31:34 2012 +0200
description:
Update sys/fs

diffstat:

 head/sys/netgraph/ng_base.c      |  125 ++++++++++++-----------
 head/sys/netgraph/ng_ipfw.c      |    4 +-
 head/sys/netgraph/ng_socket.c    |  202 ++++++++++++++++++++++----------------
 head/sys/netgraph/ng_socketvar.h |   16 +--
 head/sys/netgraph/ng_tag.c       |    7 +-
 5 files changed, 188 insertions(+), 166 deletions(-)

diffs (786 lines):

diff -r 48da769ef822 -r f683213c97d4 head/sys/netgraph/ng_base.c
--- a/head/sys/netgraph/ng_base.c	Wed Feb 01 11:31:17 2012 +0200
+++ b/head/sys/netgraph/ng_base.c	Wed Feb 01 11:31:34 2012 +0200
@@ -34,7 +34,7 @@
  * Authors: Julian Elischer <julian at freebsd.org>
  *          Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD: head/sys/netgraph/ng_base.c 229003 2011-12-30 15:41:28Z glebius $
+ * $FreeBSD: head/sys/netgraph/ng_base.c 230480 2012-01-23 15:17:14Z glebius $
  * $Whistle: ng_base.c,v 1.39 1999/01/28 23:54:53 julian Exp $
  */
 
@@ -50,6 +50,7 @@
 #include <sys/kernel.h>
 #include <sys/ktr.h>
 #include <sys/limits.h>
+#include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/queue.h>
@@ -57,6 +58,7 @@
 #include <sys/syslog.h>
 #include <sys/refcount.h>
 #include <sys/proc.h>
+#include <sys/rwlock.h>
 #include <sys/unistd.h>
 #include <sys/kthread.h>
 #include <sys/smp.h>
@@ -163,19 +165,28 @@
 
 /* List of installed types */
 static LIST_HEAD(, ng_type) ng_typelist;
-static struct mtx	ng_typelist_mtx;
+static struct rwlock	ng_typelist_lock;
+#define	TYPELIST_RLOCK()	rw_rlock(&ng_typelist_lock)
+#define	TYPELIST_RUNLOCK()	rw_runlock(&ng_typelist_lock)
+#define	TYPELIST_WLOCK()	rw_wlock(&ng_typelist_lock)
+#define	TYPELIST_WUNLOCK()	rw_wunlock(&ng_typelist_lock)
 
 /* Hash related definitions */
 /* XXX Don't need to initialise them because it's a LIST */
 static VNET_DEFINE(LIST_HEAD(, ng_node), ng_ID_hash[NG_ID_HASH_SIZE]);
 #define	V_ng_ID_hash			VNET(ng_ID_hash)
 
-static struct mtx	ng_idhash_mtx;
+static struct rwlock	ng_idhash_lock;
+#define	IDHASH_RLOCK()		rw_rlock(&ng_idhash_lock)
+#define	IDHASH_RUNLOCK()	rw_runlock(&ng_idhash_lock)
+#define	IDHASH_WLOCK()		rw_wlock(&ng_idhash_lock)
+#define	IDHASH_WUNLOCK()	rw_wunlock(&ng_idhash_lock)
+
 /* Method to find a node.. used twice so do it here */
 #define NG_IDHASH_FN(ID) ((ID) % (NG_ID_HASH_SIZE))
 #define NG_IDHASH_FIND(ID, node)					\
 	do { 								\
-		mtx_assert(&ng_idhash_mtx, MA_OWNED);			\
+		rw_assert(&ng_idhash_lock, RA_LOCKED);			\
 		LIST_FOREACH(node, &V_ng_ID_hash[NG_IDHASH_FN(ID)],	\
 						nd_idnodes) {		\
 			if (NG_NODE_IS_VALID(node)			\
@@ -188,7 +199,6 @@
 static VNET_DEFINE(LIST_HEAD(, ng_node), ng_name_hash[NG_NAME_HASH_SIZE]);
 #define	V_ng_name_hash			VNET(ng_name_hash)
 
-static struct mtx	ng_namehash_mtx;
 #define NG_NAMEHASH(NAME, HASH)				\
 	do {						\
 		u_char	h = 0;				\
@@ -198,6 +208,11 @@
 		(HASH) = h % (NG_NAME_HASH_SIZE);	\
 	} while (0)
 
+static struct rwlock	ng_namehash_lock;
+#define	NAMEHASH_RLOCK()	rw_rlock(&ng_namehash_lock)
+#define	NAMEHASH_RUNLOCK()	rw_runlock(&ng_namehash_lock)
+#define	NAMEHASH_WLOCK()	rw_wlock(&ng_namehash_lock)
+#define	NAMEHASH_WUNLOCK()	rw_wunlock(&ng_namehash_lock)
 
 /* Internal functions */
 static int	ng_add_hook(node_p node, const char *name, hook_p * hookp);
@@ -650,12 +665,12 @@
 	LIST_INIT(&node->nd_hooks);
 
 	/* Link us into the name hash. */
-	mtx_lock(&ng_namehash_mtx);
+	NAMEHASH_WLOCK();
 	LIST_INSERT_HEAD(&V_ng_name_hash[0], node, nd_nodes);
-	mtx_unlock(&ng_namehash_mtx);
+	NAMEHASH_WUNLOCK();
 
 	/* get an ID and put us in the hash chain */
-	mtx_lock(&ng_idhash_mtx);
+	IDHASH_WLOCK();
 	for (;;) { /* wrap protection, even if silly */
 		node_p node2 = NULL;
 		node->nd_ID = V_nextID++; /* 137/sec for 1 year before wrap */
@@ -668,7 +683,7 @@
 	}
 	LIST_INSERT_HEAD(&V_ng_ID_hash[NG_IDHASH_FN(node->nd_ID)], node,
 	    nd_idnodes);
-	mtx_unlock(&ng_idhash_mtx);
+	IDHASH_WUNLOCK();
 
 	/* Done */
 	*nodepp = node;
@@ -780,14 +795,14 @@
 
 	if (refcount_release(&node->nd_refs)) { /* we were the last */
 
-		mtx_lock(&ng_namehash_mtx);
 		node->nd_type->refs--; /* XXX maybe should get types lock? */
+		NAMEHASH_WLOCK();
 		LIST_REMOVE(node, nd_nodes);
-		mtx_unlock(&ng_namehash_mtx);
-
-		mtx_lock(&ng_idhash_mtx);
+		NAMEHASH_WUNLOCK();
+
+		IDHASH_WLOCK();
 		LIST_REMOVE(node, nd_idnodes);
-		mtx_unlock(&ng_idhash_mtx);
+		IDHASH_WUNLOCK();
 
 		mtx_destroy(&node->nd_input_queue.q_mtx);
 		NG_FREE_NODE(node);
@@ -801,11 +816,11 @@
 ng_ID2noderef(ng_ID_t ID)
 {
 	node_p node;
-	mtx_lock(&ng_idhash_mtx);
+	IDHASH_RLOCK();
 	NG_IDHASH_FIND(ID, node);
 	if(node)
 		NG_NODE_REF(node);
-	mtx_unlock(&ng_idhash_mtx);
+	IDHASH_RUNLOCK();
 	return(node);
 }
 
@@ -854,10 +869,10 @@
 
 	/* Update name hash. */
 	NG_NAMEHASH(name, hash);
-	mtx_lock(&ng_namehash_mtx);
+	NAMEHASH_WLOCK();
 	LIST_REMOVE(node, nd_nodes);
 	LIST_INSERT_HEAD(&V_ng_name_hash[hash], node, nd_nodes);
-	mtx_unlock(&ng_namehash_mtx);
+	NAMEHASH_WUNLOCK();
 
 	return (0);
 }
@@ -892,16 +907,15 @@
 
 	/* Find node by name */
 	NG_NAMEHASH(name, hash);
-	mtx_lock(&ng_namehash_mtx);
-	LIST_FOREACH(node, &V_ng_name_hash[hash], nd_nodes) {
+	NAMEHASH_RLOCK();
+	LIST_FOREACH(node, &V_ng_name_hash[hash], nd_nodes)
 		if (NG_NODE_IS_VALID(node) &&
 		    (strcmp(NG_NODE_NAME(node), name) == 0)) {
+			NG_NODE_REF(node);
 			break;
 		}
-	}
-	if (node)
-		NG_NODE_REF(node);
-	mtx_unlock(&ng_namehash_mtx);
+	NAMEHASH_RUNLOCK();
+
 	return (node);
 }
 
@@ -1190,10 +1204,10 @@
 
 
 	/* Link in new type */
-	mtx_lock(&ng_typelist_mtx);
+	TYPELIST_WLOCK();
 	LIST_INSERT_HEAD(&ng_typelist, tp, types);
 	tp->refs = 1;	/* first ref is linked list */
-	mtx_unlock(&ng_typelist_mtx);
+	TYPELIST_WUNLOCK();
 	return (0);
 }
 
@@ -1211,9 +1225,9 @@
 	}
 
 	/* Unlink type */
-	mtx_lock(&ng_typelist_mtx);
+	TYPELIST_WLOCK();
 	LIST_REMOVE(tp, types);
-	mtx_unlock(&ng_typelist_mtx);
+	TYPELIST_WUNLOCK();
 	return (0);
 }
 
@@ -1225,12 +1239,12 @@
 {
 	struct ng_type *type;
 
-	mtx_lock(&ng_typelist_mtx);
+	TYPELIST_RLOCK();
 	LIST_FOREACH(type, &ng_typelist, types) {
 		if (strcmp(type->name, typename) == 0)
 			break;
 	}
-	mtx_unlock(&ng_typelist_mtx);
+	TYPELIST_RUNLOCK();
 	return (type);
 }
 
@@ -2568,7 +2582,7 @@
 		node_p node;
 		int num = 0, i;
 
-		mtx_lock(&ng_namehash_mtx);
+		NAMEHASH_RLOCK();
 		/* Count number of nodes */
 		for (i = 0; i < NG_NAME_HASH_SIZE; i++) {
 			LIST_FOREACH(node, &V_ng_name_hash[i], nd_nodes) {
@@ -2578,12 +2592,12 @@
 				}
 			}
 		}
-		mtx_unlock(&ng_namehash_mtx);
 
 		/* Get response struct */
 		NG_MKRESPONSE(resp, msg, sizeof(*nl) +
 		    (num * sizeof(struct nodeinfo)), M_NOWAIT);
 		if (resp == NULL) {
+			NAMEHASH_RUNLOCK();
 			error = ENOMEM;
 			break;
 		}
@@ -2591,7 +2605,6 @@
 
 		/* Cycle through the linked list of nodes */
 		nl->numnames = 0;
-		mtx_lock(&ng_namehash_mtx);
 		for (i = 0; i < NG_NAME_HASH_SIZE; i++) {
 			LIST_FOREACH(node, &V_ng_name_hash[i], nd_nodes) {
 				struct nodeinfo *const np =
@@ -2601,20 +2614,17 @@
 					continue;
 				if (!unnamed && (! NG_NODE_HAS_NAME(node)))
 					continue;
-				if (nl->numnames >= num) {
-					log(LOG_ERR, "%s: number of nodes changed\n",
-					    __func__);
-					break;
-				}
 				if (NG_NODE_HAS_NAME(node))
 					strcpy(np->name, NG_NODE_NAME(node));
 				strcpy(np->type, node->nd_type->name);
 				np->id = ng_node2ID(node);
 				np->hooks = node->nd_numhooks;
+				KASSERT(nl->numnames < num, ("%s: no space",
+				    __func__));
 				nl->numnames++;
 			}
 		}
-		mtx_unlock(&ng_namehash_mtx);
+		NAMEHASH_RUNLOCK();
 		break;
 	    }
 
@@ -2624,17 +2634,16 @@
 		struct ng_type *type;
 		int num = 0;
 
-		mtx_lock(&ng_typelist_mtx);
+		TYPELIST_RLOCK();
 		/* Count number of types */
-		LIST_FOREACH(type, &ng_typelist, types) {
+		LIST_FOREACH(type, &ng_typelist, types)
 			num++;
-		}
-		mtx_unlock(&ng_typelist_mtx);
 
 		/* Get response struct */
 		NG_MKRESPONSE(resp, msg, sizeof(*tl) +
 		    (num * sizeof(struct typeinfo)), M_NOWAIT);
 		if (resp == NULL) {
+			TYPELIST_RUNLOCK();
 			error = ENOMEM;
 			break;
 		}
@@ -2642,20 +2651,15 @@
 
 		/* Cycle through the linked list of types */
 		tl->numtypes = 0;
-		mtx_lock(&ng_typelist_mtx);
 		LIST_FOREACH(type, &ng_typelist, types) {
 			struct typeinfo *const tp = &tl->typeinfo[tl->numtypes];
 
-			if (tl->numtypes >= num) {
-				log(LOG_ERR, "%s: number of %s changed\n",
-				    __func__, "types");
-				break;
-			}
 			strcpy(tp->type_name, type->name);
 			tp->numnodes = type->refs - 1; /* don't count list */
+			KASSERT(tl->numtypes < num, ("%s: no space", __func__));
 			tl->numtypes++;
 		}
-		mtx_unlock(&ng_typelist_mtx);
+		TYPELIST_RUNLOCK();
 		break;
 	    }
 
@@ -2989,10 +2993,10 @@
 		/* Call type specific code */
 		if (type->mod_event != NULL)
 			if ((error = (*type->mod_event)(mod, event, data))) {
-				mtx_lock(&ng_typelist_mtx);
+				TYPELIST_WLOCK();
 				type->refs--;	/* undo it */
 				LIST_REMOVE(type, types);
-				mtx_unlock(&ng_typelist_mtx);
+				TYPELIST_WUNLOCK();
 			}
 		break;
 
@@ -3007,9 +3011,9 @@
 				if (error != 0)	/* type refuses.. */
 					break;
 			}
-			mtx_lock(&ng_typelist_mtx);
+			TYPELIST_WLOCK();
 			LIST_REMOVE(type, types);
-			mtx_unlock(&ng_typelist_mtx);
+			TYPELIST_WUNLOCK();
 		}
 		break;
 
@@ -3032,7 +3036,7 @@
 
 	do {
 		/* Find a node to kill */
-		mtx_lock(&ng_namehash_mtx);
+		NAMEHASH_RLOCK();
 		for (i = 0; i < NG_NAME_HASH_SIZE; i++) {
 			LIST_FOREACH(node, &V_ng_name_hash[i], nd_nodes) {
 				if (node != &ng_deadnode) {
@@ -3043,7 +3047,7 @@
 			if (node != NULL)
 				break;
 		}
-		mtx_unlock(&ng_namehash_mtx);
+		NAMEHASH_RUNLOCK();
 
 		/* Attempt to kill it only if it is a regular node */
 		if (node != NULL) {
@@ -3081,12 +3085,9 @@
 	case MOD_LOAD:
 		/* Initialize everything. */
 		NG_WORKLIST_LOCK_INIT();
-		mtx_init(&ng_typelist_mtx, "netgraph types mutex", NULL,
-		    MTX_DEF);
-		mtx_init(&ng_idhash_mtx, "netgraph idhash mutex", NULL,
-		    MTX_DEF);
-		mtx_init(&ng_namehash_mtx, "netgraph namehash mutex", NULL,
-		    MTX_DEF);
+		rw_init(&ng_typelist_lock, "netgraph types");
+		rw_init(&ng_idhash_lock, "netgraph idhash");
+		rw_init(&ng_namehash_lock, "netgraph namehash");
 		mtx_init(&ng_topo_mtx, "netgraph topology mutex", NULL,
 		    MTX_DEF);
 #ifdef	NETGRAPH_DEBUG
diff -r 48da769ef822 -r f683213c97d4 head/sys/netgraph/ng_ipfw.c
--- a/head/sys/netgraph/ng_ipfw.c	Wed Feb 01 11:31:17 2012 +0200
+++ b/head/sys/netgraph/ng_ipfw.c	Wed Feb 01 11:31:34 2012 +0200
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/netgraph/ng_ipfw.c 226186 2011-10-10 09:33:07Z melifaro $
+ * $FreeBSD: head/sys/netgraph/ng_ipfw.c 230214 2012-01-16 12:33:55Z glebius $
  */
 
 #include "opt_inet.h"
@@ -194,7 +194,7 @@
 }
 
 /* Look up hook by name */
-hook_p
+static hook_p
 ng_ipfw_findhook(node_p node, const char *name)
 {
 	u_int16_t n;	/* numeric representation of hook */
diff -r 48da769ef822 -r f683213c97d4 head/sys/netgraph/ng_socket.c
--- a/head/sys/netgraph/ng_socket.c	Wed Feb 01 11:31:17 2012 +0200
+++ b/head/sys/netgraph/ng_socket.c	Wed Feb 01 11:31:34 2012 +0200
@@ -37,7 +37,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD: head/sys/netgraph/ng_socket.c 227309 2011-11-07 15:43:11Z ed $
+ * $FreeBSD: head/sys/netgraph/ng_socket.c 230487 2012-01-23 16:43:13Z glebius $
  * $Whistle: ng_socket.c,v 1.28 1999/11/01 09:24:52 julian Exp $
  */
 
@@ -51,6 +51,7 @@
 
 #include <sys/param.h>
 #include <sys/domain.h>
+#include <sys/hash.h>
 #include <sys/kernel.h>
 #include <sys/linker.h>
 #include <sys/lock.h>
@@ -64,9 +65,6 @@
 #include <sys/socketvar.h>
 #include <sys/syscallsubr.h>
 #include <sys/sysctl.h>
-#ifdef NOTYET
-#include <sys/vnode.h>
-#endif
 
 #include <net/vnet.h>
 
@@ -115,6 +113,7 @@
 static ng_shutdown_t	ngs_shutdown;
 static ng_newhook_t	ngs_newhook;
 static ng_connect_t	ngs_connect;
+static ng_findhook_t	ngs_findhook;
 static ng_rcvdata_t	ngs_rcvdata;
 static ng_disconnect_t	ngs_disconnect;
 
@@ -124,9 +123,6 @@
 static int	ng_attach_common(struct socket *so, int type);
 static void	ng_detach_common(struct ngpcb *pcbp, int type);
 static void	ng_socket_free_priv(struct ngsock *priv);
-#ifdef NOTYET
-static int	ng_internalize(struct mbuf *m, struct thread *p);
-#endif
 static int	ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp);
 static int	ng_bind(struct sockaddr *nam, struct ngpcb *pcbp);
 
@@ -143,6 +139,7 @@
 	.shutdown =	ngs_shutdown,
 	.newhook =	ngs_newhook,
 	.connect =	ngs_connect,
+	.findhook =	ngs_findhook,
 	.rcvdata =	ngs_rcvdata,
 	.disconnect =	ngs_disconnect,
 };
@@ -168,6 +165,27 @@
 #define TRAP_ERROR
 #endif
 
+struct hookpriv {
+	LIST_ENTRY(hookpriv)	next;
+	hook_p			hook;
+};
+LIST_HEAD(ngshash, hookpriv);
+
+/* Per-node private data */
+struct ngsock {
+	struct ng_node	*node;		/* the associated netgraph node */
+	struct ngpcb	*datasock;	/* optional data socket */
+	struct ngpcb	*ctlsock;	/* optional control socket */
+	struct ngshash	*hash;		/* hash for hook names */
+	u_long		hmask;		/* hash mask */
+	int	flags;
+	int	refs;
+	struct mtx	mtx;		/* mtx to wait on */
+	int		error;		/* place to store error */
+};
+
+#define	NGS_FLAG_NOLINGER	1	/* close with last hook */
+
 /***************************************************************
 	Control sockets
 ***************************************************************/
@@ -209,19 +227,10 @@
 	int len, error = 0;
 	struct ng_apply_info apply;
 
-#ifdef	NOTYET
-	if (control && (error = ng_internalize(control, td))) {
-		if (pcbp->sockdata == NULL) {
-			error = ENOTCONN;
-			goto release;
-		}
-	}
-#else	/* NOTYET */
 	if (control) {
 		error = EINVAL;
 		goto release;
 	}
-#endif	/* NOTYET */
 
 	/* Require destination as there may be >= 1 hooks on this node. */
 	if (addr == NULL) {
@@ -539,8 +548,14 @@
 		return (error);
 	}
 
-	/* Allocate node private info */
+	/*
+	 * Allocate node private info and hash. We start
+	 * with 16 hash entries, however we may grow later
+	 * in ngs_newhook(). We can't predict how much hooks
+	 * does this node plan to have.
+	 */
 	priv = malloc(sizeof(*priv), M_NETGRAPH_SOCK, M_WAITOK | M_ZERO);
+	priv->hash = hashinit(16, M_NETGRAPH_SOCK, &priv->hmask);
 
 	/* Initialize mutex. */
 	mtx_init(&priv->mtx, "ng_socket", NULL, MTX_DEF);
@@ -550,9 +565,7 @@
 	pcbp->sockdata = priv;
 	priv->refs++;
 	priv->node = node;
-
-	/* Store a hint for netstat(1). */
-	priv->node_id = priv->node->nd_ID;
+	pcbp->node_id = node->nd_ID;	/* hint for netstat(1) */
 
 	/* Link the node and the private data. */
 	NG_NODE_SET_PRIVATE(priv->node, priv);
@@ -623,6 +636,7 @@
 			panic("%s", __func__);
 		}
 		pcbp->sockdata = NULL;
+		pcbp->node_id = 0;
 
 		ng_socket_free_priv(priv);
 	}
@@ -646,6 +660,7 @@
 
 	if (priv->refs == 0) {
 		mtx_destroy(&priv->mtx);
+		hashdestroy(priv->hash, M_NETGRAPH_SOCK, priv->hmask);
 		free(priv, M_NETGRAPH_SOCK);
 		return;
 	}
@@ -661,69 +676,6 @@
 		mtx_unlock(&priv->mtx);
 }
 
-#ifdef NOTYET
-/*
- * File descriptors can be passed into an AF_NETGRAPH socket.
- * Note, that file descriptors cannot be passed OUT.
- * Only character device descriptors are accepted.
- * Character devices are useful to connect a graph to a device,
- * which after all is the purpose of this whole system.
- */
-static int
-ng_internalize(struct mbuf *control, struct thread *td)
-{
-	const struct cmsghdr *cm = mtod(control, const struct cmsghdr *);
-	struct file *fp;
-	struct vnode *vn;
-	int oldfds;
-	int fd;
-
-	if (cm->cmsg_type != SCM_RIGHTS || cm->cmsg_level != SOL_SOCKET ||
-	    cm->cmsg_len != control->m_len) {
-		TRAP_ERROR;
-		return (EINVAL);
-	}
-
-	/* Check there is only one FD. XXX what would more than one signify? */
-	oldfds = ((caddr_t)cm + cm->cmsg_len - (caddr_t)data) / sizeof (int);
-	if (oldfds != 1) {
-		TRAP_ERROR;
-		return (EINVAL);
-	}
-
-	/* Check that the FD given is legit. and change it to a pointer to a
-	 * struct file. */
-	fd = CMSG_DATA(cm);
-	if ((error = fget(td, fd, 0, &fp)) != 0)
-		return (error);
-
-	/* Depending on what kind of resource it is, act differently. For
-	 * devices, we treat it as a file. For an AF_NETGRAPH socket,
-	 * shortcut straight to the node. */
-	switch (fp->f_type) {
-	case DTYPE_VNODE:
-		vn = fp->f_data;
-		if (vn && (vn->v_type == VCHR)) {
-			/* for a VCHR, actually reference the FILE */
-			fhold(fp);
-			/* XXX then what :) */
-			/* how to pass on to other modules? */
-		} else {
-			fdrop(fp, td);
-			TRAP_ERROR;
-			return (EINVAL);
-		}
-		break;
-	default:
-		fdrop(fp, td);
-		TRAP_ERROR;
-		return (EINVAL);
-	}
-	fdrop(fp, td);
-	return (0);
-}
-#endif	/* NOTYET */
-
 /*
  * Connect the data socket to a named control socket node.
  */
@@ -776,6 +728,7 @@
 	mtx_lock(&priv->mtx);
 	priv->datasock = pcbp;
 	pcbp->sockdata = priv;
+	pcbp->node_id = priv->node->nd_ID;	/* hint for netstat(1) */
 	priv->refs++;
 	mtx_unlock(&priv->mtx);
 	NG_FREE_ITEM(item);	/* drop the reference to the node */
@@ -817,6 +770,35 @@
 	return (EINVAL);
 }
 
+static void
+ngs_rehash(node_p node)
+{
+	struct ngsock *priv = NG_NODE_PRIVATE(node);
+	struct ngshash *new;
+	struct hookpriv *hp;
+	hook_p hook;
+	uint32_t h;
+	u_long hmask;
+
+	new = hashinit_flags((priv->hmask + 1) * 2, M_NETGRAPH_SOCK, &hmask,
+	    HASH_NOWAIT);
+	if (new == NULL)
+		return;
+
+	LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) {
+		hp = NG_HOOK_PRIVATE(hook);
+#ifdef INVARIANTS
+		LIST_REMOVE(hp, next);
+#endif
+		h = hash32_str(NG_HOOK_NAME(hook), HASHINIT) & hmask;
+		LIST_INSERT_HEAD(&new[h], hp, next);
+	}
+
+	hashdestroy(priv->hash, M_NETGRAPH_SOCK, priv->hmask);
+	priv->hash = new;
+	priv->hmask = hmask;
+}
+
 /*
  * We allow any hook to be connected to the node.
  * There is no per-hook private information though.
@@ -824,7 +806,20 @@
 static int
 ngs_newhook(node_p node, hook_p hook, const char *name)
 {
-	NG_HOOK_SET_PRIVATE(hook, NG_NODE_PRIVATE(node));
+	struct ngsock *const priv = NG_NODE_PRIVATE(node);
+	struct hookpriv *hp;
+	uint32_t h;
+
+	hp = malloc(sizeof(*hp), M_NETGRAPH_SOCK, M_NOWAIT);
+	if (hp == NULL)
+		return (ENOMEM);
+	if (node->nd_numhooks * 2 > priv->hmask)
+		ngs_rehash(node);
+	hp->hook = hook;
+	h = hash32_str(name, HASHINIT) & priv->hmask;
+	LIST_INSERT_HEAD(&priv->hash[h], hp, next);
+	NG_HOOK_SET_PRIVATE(hook, hp);
+
 	return (0);
 }
 
@@ -846,6 +841,41 @@
 	return (0);
 }
 
+/* Look up hook by name */
+static hook_p
+ngs_findhook(node_p node, const char *name)
+{
+	struct ngsock *priv = NG_NODE_PRIVATE(node);
+	struct hookpriv *hp;
+	uint32_t h;
+
+	/*
+	 * Microoptimisations for a ng_socket with no
+	 * hooks, or with a single hook, which is a
+	 * common case.
+	 */
+	if (node->nd_numhooks == 0)
+		return (NULL);
+	if (node->nd_numhooks == 1) {
+		hook_p hook;
+
+		hook = LIST_FIRST(&node->nd_hooks);
+
+		if (strcmp(NG_HOOK_NAME(hook), name) == 0)
+			return (hook);
+		else
+			return (NULL);
+	}
+
+	h = hash32_str(name, HASHINIT) & priv->hmask;
+
+	LIST_FOREACH(hp, &priv->hash[h], next)
+		if (strcmp(NG_HOOK_NAME(hp->hook), name) == 0)
+			return (hp->hook);
+
+	return (NULL);
+}
+
 /*
  * Incoming messages get passed up to the control socket.
  * Unless they are for us specifically (socket_type)
@@ -1013,6 +1043,10 @@
 {
 	node_p node = NG_HOOK_NODE(hook);
 	struct ngsock *const priv = NG_NODE_PRIVATE(node);
+	struct hookpriv *hp = NG_HOOK_PRIVATE(hook);
+
+	LIST_REMOVE(hp, next);
+	free(hp, M_NETGRAPH_SOCK);
 
 	if ((priv->datasock) && (priv->datasock->ng_socket)) {
 		if (NG_NODE_NUMHOOKS(node) == 1)
diff -r 48da769ef822 -r f683213c97d4 head/sys/netgraph/ng_socketvar.h
--- a/head/sys/netgraph/ng_socketvar.h	Wed Feb 01 11:31:17 2012 +0200
+++ b/head/sys/netgraph/ng_socketvar.h	Wed Feb 01 11:31:34 2012 +0200
@@ -37,7 +37,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/netgraph/ng_socketvar.h 230481 2012-01-23 15:39:45Z glebius $
  * $Whistle: ng_socketvar.h,v 1.1 1999/01/20 21:35:39 archie Exp $
  */
 
@@ -50,20 +50,6 @@
 	struct ngsock	 *sockdata;	/* netgraph info */
 	LIST_ENTRY(ngpcb) socks;	/* linked list of sockets */
 	int		  type;		/* NG_CONTROL or NG_DATA */
-};
-
-/* Per-node private data */
-struct ngsock {
-	struct ng_node	*node;		/* the associated netgraph node */
-	struct ngpcb	*datasock;	/* optional data socket */
-	struct ngpcb	*ctlsock;	/* optional control socket */
-	int    flags;
-	int    refs;
-	struct mtx	mtx;		/* mtx to wait on */
-	int		error;		/* place to store error */
 	ng_ID_t		node_id;	/* a hint for netstat(1) to find the node */
 };
-#define	NGS_FLAG_NOLINGER	1	/* close with last hook */
-
 #endif /* _NETGRAPH_NG_SOCKETVAR_H_ */
-
diff -r 48da769ef822 -r f683213c97d4 head/sys/netgraph/ng_tag.c
--- a/head/sys/netgraph/ng_tag.c	Wed Feb 01 11:31:17 2012 +0200
+++ b/head/sys/netgraph/ng_tag.c	Wed Feb 01 11:31:34 2012 +0200
@@ -27,7 +27,7 @@
  * Portions Copyright (c) 1999 Whistle Communications, Inc.
  * (ng_bpf by Archie Cobbs <archie at freebsd.org>)
  *
- * $FreeBSD: head/sys/netgraph/ng_tag.c 227293 2011-11-07 06:44:47Z ed $
+ * $FreeBSD: head/sys/netgraph/ng_tag.c 230272 2012-01-17 18:10:25Z glebius $
  */
 
 /*
@@ -303,8 +303,9 @@
 	int error;
 
 	/* Create hook private structure. */
-	hip = malloc(sizeof(*hip), M_NETGRAPH_TAG, M_WAITOK | M_ZERO);
-	/* M_WAITOK can't return NULL. */
+	hip = malloc(sizeof(*hip), M_NETGRAPH_TAG, M_NOWAIT | M_ZERO);
+	if (hip == NULL)
+		return (ENOMEM);
 	NG_HOOK_SET_PRIVATE(hook, hip);
 
 	/*


More information about the Zrouter-src-freebsd mailing list