[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