ng_base.c revision 231830
1120492Sfjoe/*-
2194638Sdelphij * Copyright (c) 1996-1999 Whistle Communications, Inc.
3120492Sfjoe * All rights reserved.
4120492Sfjoe *
5120492Sfjoe * Subject to the following obligations and disclaimer of warranty, use and
6120492Sfjoe * redistribution of this software, in source or object code forms, with or
7120492Sfjoe * without modifications are expressly permitted by Whistle Communications;
8120492Sfjoe * provided, however, that:
9120492Sfjoe * 1. Any and all reproductions of the source or object code must include the
10120492Sfjoe *    copyright notice above and the following disclaimer of warranties; and
11120492Sfjoe * 2. No rights are granted, in any manner or form, to use Whistle
12120492Sfjoe *    Communications, Inc. trademarks, including the mark "WHISTLE
13120492Sfjoe *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
14120492Sfjoe *    such appears in the above copyright notice or in the software.
15120492Sfjoe *
16120492Sfjoe * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
17120492Sfjoe * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
18120492Sfjoe * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
19120492Sfjoe * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
20120492Sfjoe * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
21120492Sfjoe * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
22120492Sfjoe * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
23120492Sfjoe * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
24120492Sfjoe * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
25120492Sfjoe * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
26120492Sfjoe * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
27120492Sfjoe * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
28120492Sfjoe * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
29120492Sfjoe * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30120492Sfjoe * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31120492Sfjoe * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
32120492Sfjoe * OF SUCH DAMAGE.
33120492Sfjoe *
34120492Sfjoe * Authors: Julian Elischer <julian@freebsd.org>
35120492Sfjoe *          Archie Cobbs <archie@freebsd.org>
36120492Sfjoe *
37120492Sfjoe * $FreeBSD: head/sys/netgraph/ng_base.c 231830 2012-02-16 18:54:44Z glebius $
38120492Sfjoe * $Whistle: ng_base.c,v 1.39 1999/01/28 23:54:53 julian Exp $
39120492Sfjoe */
40120492Sfjoe
41120492Sfjoe/*
42120492Sfjoe * This file implements the base netgraph code.
43120492Sfjoe */
44194638Sdelphij
45120492Sfjoe#include <sys/param.h>
46120492Sfjoe#include <sys/systm.h>
47120492Sfjoe#include <sys/ctype.h>
48194638Sdelphij#include <sys/kdb.h>
49120492Sfjoe#include <sys/kernel.h>
50120492Sfjoe#include <sys/kthread.h>
51120492Sfjoe#include <sys/ktr.h>
52120492Sfjoe#include <sys/limits.h>
53120492Sfjoe#include <sys/lock.h>
54120492Sfjoe#include <sys/malloc.h>
55120492Sfjoe#include <sys/mbuf.h>
56120492Sfjoe#include <sys/proc.h>
57120492Sfjoe#include <sys/queue.h>
58120492Sfjoe#include <sys/refcount.h>
59120492Sfjoe#include <sys/rwlock.h>
60120492Sfjoe#include <sys/smp.h>
61194638Sdelphij#include <sys/sysctl.h>
62120492Sfjoe#include <sys/syslog.h>
63237698Sgabor#include <sys/unistd.h>
64120492Sfjoe#include <machine/cpu.h>
65120492Sfjoe
66120492Sfjoe#include <net/netisr.h>
67120492Sfjoe#include <net/vnet.h>
68237698Sgabor
69237698Sgabor#include <netgraph/ng_message.h>
70237698Sgabor#include <netgraph/netgraph.h>
71237698Sgabor#include <netgraph/ng_parse.h>
72237698Sgabor
73237698SgaborMODULE_VERSION(netgraph, NG_ABI_VERSION);
74237698Sgabor
75120492Sfjoe/* Mutex to protect topology events. */
76120492Sfjoestatic struct mtx	ng_topo_mtx;
77120492Sfjoe
78120492Sfjoe#ifdef	NETGRAPH_DEBUG
79120492Sfjoestatic struct mtx	ng_nodelist_mtx; /* protects global node/hook lists */
80120492Sfjoestatic struct mtx	ngq_mtx;	/* protects the queue item list */
81194638Sdelphij
82120492Sfjoestatic SLIST_HEAD(, ng_node) ng_allnodes;
83148717Sstefanfstatic LIST_HEAD(, ng_node) ng_freenodes; /* in debug, we never free() them */
84148717Sstefanfstatic SLIST_HEAD(, ng_hook) ng_allhooks;
85230196Skevlostatic LIST_HEAD(, ng_hook) ng_freehooks; /* in debug, we never free() them */
86120492Sfjoe
87230196Skevlostatic void ng_dumpitems(void);
88230196Skevlostatic void ng_dumpnodes(void);
89230196Skevlostatic void ng_dumphooks(void);
90230196Skevlo
91230196Skevlo#endif	/* NETGRAPH_DEBUG */
92230196Skevlo/*
93230196Skevlo * DEAD versions of the structures.
94230196Skevlo * In order to avoid races, it is sometimes neccesary to point
95230196Skevlo * at SOMETHING even though theoretically, the current entity is
96230196Skevlo * INVALID. Use these to avoid these races.
97230196Skevlo */
98194638Sdelphijstruct ng_type ng_deadtype = {
99194638Sdelphij	NG_ABI_VERSION,
100120492Sfjoe	"dead",
101194638Sdelphij	NULL,	/* modevent */
102194638Sdelphij	NULL,	/* constructor */
103194638Sdelphij	NULL,	/* rcvmsg */
104194638Sdelphij	NULL,	/* shutdown */
105120492Sfjoe	NULL,	/* newhook */
106120492Sfjoe	NULL,	/* findhook */
107120492Sfjoe	NULL,	/* connect */
108120492Sfjoe	NULL,	/* rcvdata */
109120492Sfjoe	NULL,	/* disconnect */
110120492Sfjoe	NULL, 	/* cmdlist */
111120492Sfjoe};
112120492Sfjoe
113120492Sfjoestruct ng_node ng_deadnode = {
114120492Sfjoe	"dead",
115120492Sfjoe	&ng_deadtype,
116120492Sfjoe	NGF_INVALID,
117120492Sfjoe	0,	/* numhooks */
118120492Sfjoe	NULL,	/* private */
119120492Sfjoe	0,	/* ID */
120120492Sfjoe	LIST_HEAD_INITIALIZER(ng_deadnode.nd_hooks),
121120492Sfjoe	{},	/* all_nodes list entry */
122120492Sfjoe	{},	/* id hashtable list entry */
123120492Sfjoe	{	0,
124120492Sfjoe		0,
125120492Sfjoe		{}, /* should never use! (should hang) */
126120492Sfjoe		{}, /* workqueue entry */
127120492Sfjoe		STAILQ_HEAD_INITIALIZER(ng_deadnode.nd_input_queue.queue),
128123293Sfjoe	},
129123293Sfjoe	1,	/* refs */
130123293Sfjoe	NULL,	/* vnet */
131194638Sdelphij#ifdef	NETGRAPH_DEBUG
132123293Sfjoe	ND_MAGIC,
133123293Sfjoe	__FILE__,
134123293Sfjoe	__LINE__,
135123293Sfjoe	{NULL}
136123293Sfjoe#endif	/* NETGRAPH_DEBUG */
137123293Sfjoe};
138123293Sfjoe
139123293Sfjoestruct ng_hook ng_deadhook = {
140123293Sfjoe	"dead",
141194638Sdelphij	NULL,		/* private */
142194638Sdelphij	HK_INVALID | HK_DEAD,
143194638Sdelphij	0,		/* undefined data link type */
144194638Sdelphij	&ng_deadhook,	/* Peer is self */
145194638Sdelphij	&ng_deadnode,	/* attached to deadnode */
146194638Sdelphij	{},		/* hooks list */
147194638Sdelphij	NULL,		/* override rcvmsg() */
148194638Sdelphij	NULL,		/* override rcvdata() */
149123293Sfjoe	1,		/* refs always >= 1 */
150123293Sfjoe#ifdef	NETGRAPH_DEBUG
151123293Sfjoe	HK_MAGIC,
152120492Sfjoe	__FILE__,
153120492Sfjoe	__LINE__,
154120492Sfjoe	{NULL}
155120492Sfjoe#endif	/* NETGRAPH_DEBUG */
156120492Sfjoe};
157120492Sfjoe
158120492Sfjoe/*
159120492Sfjoe * END DEAD STRUCTURES
160120492Sfjoe */
161120492Sfjoe/* List nodes with unallocated work */
162120492Sfjoestatic STAILQ_HEAD(, ng_node) ng_worklist = STAILQ_HEAD_INITIALIZER(ng_worklist);
163148717Sstefanfstatic struct mtx	ng_worklist_mtx;   /* MUST LOCK NODE FIRST */
164120492Sfjoe
165120492Sfjoe/* List of installed types */
166120492Sfjoestatic LIST_HEAD(, ng_type) ng_typelist;
167120492Sfjoestatic struct rwlock	ng_typelist_lock;
168126949Sbde#define	TYPELIST_RLOCK()	rw_rlock(&ng_typelist_lock)
169126949Sbde#define	TYPELIST_RUNLOCK()	rw_runlock(&ng_typelist_lock)
170120492Sfjoe#define	TYPELIST_WLOCK()	rw_wlock(&ng_typelist_lock)
171120492Sfjoe#define	TYPELIST_WUNLOCK()	rw_wunlock(&ng_typelist_lock)
172120492Sfjoe
173120492Sfjoe/* Hash related definitions */
174120492Sfjoe/* XXX Don't need to initialise them because it's a LIST */
175120492Sfjoestatic VNET_DEFINE(LIST_HEAD(, ng_node), ng_ID_hash[NG_ID_HASH_SIZE]);
176120492Sfjoe#define	V_ng_ID_hash			VNET(ng_ID_hash)
177120492Sfjoe
178120492Sfjoestatic struct rwlock	ng_idhash_lock;
179120492Sfjoe#define	IDHASH_RLOCK()		rw_rlock(&ng_idhash_lock)
180120492Sfjoe#define	IDHASH_RUNLOCK()	rw_runlock(&ng_idhash_lock)
181120492Sfjoe#define	IDHASH_WLOCK()		rw_wlock(&ng_idhash_lock)
182120492Sfjoe#define	IDHASH_WUNLOCK()	rw_wunlock(&ng_idhash_lock)
183120492Sfjoe
184120492Sfjoe/* Method to find a node.. used twice so do it here */
185120492Sfjoe#define NG_IDHASH_FN(ID) ((ID) % (NG_ID_HASH_SIZE))
186120492Sfjoe#define NG_IDHASH_FIND(ID, node)					\
187120492Sfjoe	do { 								\
188120492Sfjoe		rw_assert(&ng_idhash_lock, RA_LOCKED);			\
189120492Sfjoe		LIST_FOREACH(node, &V_ng_ID_hash[NG_IDHASH_FN(ID)],	\
190120492Sfjoe						nd_idnodes) {		\
191120492Sfjoe			if (NG_NODE_IS_VALID(node)			\
192120492Sfjoe			&& (NG_NODE_ID(node) == ID)) {			\
193120492Sfjoe				break;					\
194120492Sfjoe			}						\
195120492Sfjoe		}							\
196194638Sdelphij	} while (0)
197194638Sdelphij
198194638Sdelphijstatic VNET_DEFINE(LIST_HEAD(, ng_node), ng_name_hash[NG_NAME_HASH_SIZE]);
199194638Sdelphij#define	V_ng_name_hash			VNET(ng_name_hash)
200194638Sdelphij
201194638Sdelphij#define NG_NAMEHASH(NAME, HASH)				\
202194638Sdelphij	do {						\
203194638Sdelphij		u_char	h = 0;				\
204194638Sdelphij		const u_char	*c;			\
205194638Sdelphij		for (c = (const u_char*)(NAME); *c; c++)\
206194638Sdelphij			h += *c;			\
207194638Sdelphij		(HASH) = h % (NG_NAME_HASH_SIZE);	\
208194638Sdelphij	} while (0)
209194638Sdelphij
210194638Sdelphijstatic struct rwlock	ng_namehash_lock;
211194638Sdelphij#define	NAMEHASH_RLOCK()	rw_rlock(&ng_namehash_lock)
212194638Sdelphij#define	NAMEHASH_RUNLOCK()	rw_runlock(&ng_namehash_lock)
213194638Sdelphij#define	NAMEHASH_WLOCK()	rw_wlock(&ng_namehash_lock)
214194638Sdelphij#define	NAMEHASH_WUNLOCK()	rw_wunlock(&ng_namehash_lock)
215194638Sdelphij
216194638Sdelphij/* Internal functions */
217194638Sdelphijstatic int	ng_add_hook(node_p node, const char *name, hook_p * hookp);
218194638Sdelphijstatic int	ng_generic_msg(node_p here, item_p item, hook_p lasthook);
219194638Sdelphijstatic ng_ID_t	ng_decodeidname(const char *name);
220194638Sdelphijstatic int	ngb_mod_event(module_t mod, int event, void *data);
221120492Sfjoestatic void	ng_worklist_add(node_p node);
222120492Sfjoestatic void	ngthread(void *);
223120492Sfjoestatic int	ng_apply_item(node_p node, item_p item, int rw);
224120492Sfjoestatic void	ng_flush_input_queue(node_p node);
225120492Sfjoestatic node_p	ng_ID2noderef(ng_ID_t ID);
226120492Sfjoestatic int	ng_con_nodes(item_p item, node_p node, const char *name,
227120492Sfjoe		    node_p node2, const char *name2);
228120492Sfjoestatic int	ng_con_part2(node_p node, item_p item, hook_p hook);
229120492Sfjoestatic int	ng_con_part3(node_p node, item_p item, hook_p hook);
230120492Sfjoestatic int	ng_mkpeer(node_p node, const char *name,
231120492Sfjoe						const char *name2, char *type);
232120492Sfjoe
233120492Sfjoe/* Imported, these used to be externally visible, some may go back. */
234120492Sfjoevoid	ng_destroy_hook(hook_p hook);
235120492Sfjoeint	ng_path2noderef(node_p here, const char *path,
236120492Sfjoe	node_p *dest, hook_p *lasthook);
237120492Sfjoeint	ng_make_node(const char *type, node_p *nodepp);
238120492Sfjoeint	ng_path_parse(char *addr, char **node, char **path, char **hook);
239120492Sfjoevoid	ng_rmnode(node_p node, hook_p dummy1, void *dummy2, int dummy3);
240120492Sfjoevoid	ng_unname(node_p node);
241120492Sfjoe
242120492Sfjoe/* Our own netgraph malloc type */
243120492SfjoeMALLOC_DEFINE(M_NETGRAPH, "netgraph", "netgraph structures and ctrl messages");
244120492SfjoeMALLOC_DEFINE(M_NETGRAPH_MSG, "netgraph_msg", "netgraph name storage");
245120492Sfjoestatic MALLOC_DEFINE(M_NETGRAPH_HOOK, "netgraph_hook",
246120492Sfjoe    "netgraph hook structures");
247120492Sfjoestatic MALLOC_DEFINE(M_NETGRAPH_NODE, "netgraph_node",
248120492Sfjoe    "netgraph node structures");
249120492Sfjoestatic MALLOC_DEFINE(M_NETGRAPH_ITEM, "netgraph_item",
250120492Sfjoe    "netgraph item structures");
251120492Sfjoe
252120492Sfjoe/* Should not be visible outside this file */
253120492Sfjoe
254120492Sfjoe#define _NG_ALLOC_HOOK(hook) \
255120492Sfjoe	hook = malloc(sizeof(*hook), M_NETGRAPH_HOOK, M_NOWAIT | M_ZERO)
256120492Sfjoe#define _NG_ALLOC_NODE(node) \
257120492Sfjoe	node = malloc(sizeof(*node), M_NETGRAPH_NODE, M_NOWAIT | M_ZERO)
258120492Sfjoe
259120492Sfjoe#define	NG_QUEUE_LOCK_INIT(n)			\
260120492Sfjoe	mtx_init(&(n)->q_mtx, "ng_node", NULL, MTX_DEF)
261120492Sfjoe#define	NG_QUEUE_LOCK(n)			\
262120492Sfjoe	mtx_lock(&(n)->q_mtx)
263120492Sfjoe#define	NG_QUEUE_UNLOCK(n)			\
264120492Sfjoe	mtx_unlock(&(n)->q_mtx)
265120492Sfjoe#define	NG_WORKLIST_LOCK_INIT()			\
266120492Sfjoe	mtx_init(&ng_worklist_mtx, "ng_worklist", NULL, MTX_DEF)
267120492Sfjoe#define	NG_WORKLIST_LOCK()			\
268120492Sfjoe	mtx_lock(&ng_worklist_mtx)
269120492Sfjoe#define	NG_WORKLIST_UNLOCK()			\
270120492Sfjoe	mtx_unlock(&ng_worklist_mtx)
271120492Sfjoe#define	NG_WORKLIST_SLEEP()			\
272120492Sfjoe	mtx_sleep(&ng_worklist, &ng_worklist_mtx, PI_NET, "sleep", 0)
273120492Sfjoe#define	NG_WORKLIST_WAKEUP()			\
274120492Sfjoe	wakeup_one(&ng_worklist)
275120492Sfjoe
276120492Sfjoe#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/
277120492Sfjoe/*
278120492Sfjoe * In debug mode:
279120492Sfjoe * In an attempt to help track reference count screwups
280120492Sfjoe * we do not free objects back to the malloc system, but keep them
281120492Sfjoe * in a local cache where we can examine them and keep information safely
282120492Sfjoe * after they have been freed.
283120492Sfjoe * We use this scheme for nodes and hooks, and to some extent for items.
284120492Sfjoe */
285120492Sfjoestatic __inline hook_p
286120492Sfjoeng_alloc_hook(void)
287120492Sfjoe{
288120492Sfjoe	hook_p hook;
289120492Sfjoe	SLIST_ENTRY(ng_hook) temp;
290120492Sfjoe	mtx_lock(&ng_nodelist_mtx);
291120492Sfjoe	hook = LIST_FIRST(&ng_freehooks);
292120492Sfjoe	if (hook) {
293120492Sfjoe		LIST_REMOVE(hook, hk_hooks);
294120492Sfjoe		bcopy(&hook->hk_all, &temp, sizeof(temp));
295120492Sfjoe		bzero(hook, sizeof(struct ng_hook));
296120492Sfjoe		bcopy(&temp, &hook->hk_all, sizeof(temp));
297120492Sfjoe		mtx_unlock(&ng_nodelist_mtx);
298148717Sstefanf		hook->hk_magic = HK_MAGIC;
299120492Sfjoe	} else {
300120492Sfjoe		mtx_unlock(&ng_nodelist_mtx);
301120492Sfjoe		_NG_ALLOC_HOOK(hook);
302120492Sfjoe		if (hook) {
303120492Sfjoe			hook->hk_magic = HK_MAGIC;
304194638Sdelphij			mtx_lock(&ng_nodelist_mtx);
305194638Sdelphij			SLIST_INSERT_HEAD(&ng_allhooks, hook, hk_all);
306194638Sdelphij			mtx_unlock(&ng_nodelist_mtx);
307194638Sdelphij		}
308194638Sdelphij	}
309194638Sdelphij	return (hook);
310194638Sdelphij}
311194638Sdelphij
312194638Sdelphijstatic __inline node_p
313194638Sdelphijng_alloc_node(void)
314194638Sdelphij{
315194638Sdelphij	node_p node;
316194638Sdelphij	SLIST_ENTRY(ng_node) temp;
317194638Sdelphij	mtx_lock(&ng_nodelist_mtx);
318194638Sdelphij	node = LIST_FIRST(&ng_freenodes);
319194638Sdelphij	if (node) {
320194638Sdelphij		LIST_REMOVE(node, nd_nodes);
321237698Sgabor		bcopy(&node->nd_all, &temp, sizeof(temp));
322194638Sdelphij		bzero(node, sizeof(struct ng_node));
323120492Sfjoe		bcopy(&temp, &node->nd_all, sizeof(temp));
324120492Sfjoe		mtx_unlock(&ng_nodelist_mtx);
325120492Sfjoe		node->nd_magic = ND_MAGIC;
326120492Sfjoe	} else {
327120492Sfjoe		mtx_unlock(&ng_nodelist_mtx);
328120492Sfjoe		_NG_ALLOC_NODE(node);
329120492Sfjoe		if (node) {
330120492Sfjoe			node->nd_magic = ND_MAGIC;
331120492Sfjoe			mtx_lock(&ng_nodelist_mtx);
332120492Sfjoe			SLIST_INSERT_HEAD(&ng_allnodes, node, nd_all);
333120492Sfjoe			mtx_unlock(&ng_nodelist_mtx);
334120492Sfjoe		}
335120492Sfjoe	}
336120492Sfjoe	return (node);
337120492Sfjoe}
338120492Sfjoe
339237698Sgabor#define NG_ALLOC_HOOK(hook) do { (hook) = ng_alloc_hook(); } while (0)
340120492Sfjoe#define NG_ALLOC_NODE(node) do { (node) = ng_alloc_node(); } while (0)
341120492Sfjoe
342120492Sfjoe#define NG_FREE_HOOK(hook)						\
343120492Sfjoe	do {								\
344120492Sfjoe		mtx_lock(&ng_nodelist_mtx);				\
345120492Sfjoe		LIST_INSERT_HEAD(&ng_freehooks, hook, hk_hooks);	\
346120492Sfjoe		hook->hk_magic = 0;					\
347120492Sfjoe		mtx_unlock(&ng_nodelist_mtx);				\
348120492Sfjoe	} while (0)
349120492Sfjoe
350120492Sfjoe#define NG_FREE_NODE(node)						\
351120492Sfjoe	do {								\
352120492Sfjoe		mtx_lock(&ng_nodelist_mtx);				\
353120492Sfjoe		LIST_INSERT_HEAD(&ng_freenodes, node, nd_nodes);	\
354120492Sfjoe		node->nd_magic = 0;					\
355120492Sfjoe		mtx_unlock(&ng_nodelist_mtx);				\
356120492Sfjoe	} while (0)
357120492Sfjoe
358120492Sfjoe#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/
359120492Sfjoe
360120492Sfjoe#define NG_ALLOC_HOOK(hook) _NG_ALLOC_HOOK(hook)
361120492Sfjoe#define NG_ALLOC_NODE(node) _NG_ALLOC_NODE(node)
362120492Sfjoe
363120492Sfjoe#define NG_FREE_HOOK(hook) do { free((hook), M_NETGRAPH_HOOK); } while (0)
364120492Sfjoe#define NG_FREE_NODE(node) do { free((node), M_NETGRAPH_NODE); } while (0)
365120492Sfjoe
366120492Sfjoe#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/
367120492Sfjoe
368120492Sfjoe/* Set this to kdb_enter("X") to catch all errors as they occur */
369120492Sfjoe#ifndef TRAP_ERROR
370120492Sfjoe#define TRAP_ERROR()
371120492Sfjoe#endif
372120492Sfjoe
373120492Sfjoestatic VNET_DEFINE(ng_ID_t, nextID) = 1;
374120492Sfjoe#define	V_nextID			VNET(nextID)
375120492Sfjoe
376120492Sfjoe#ifdef INVARIANTS
377120492Sfjoe#define CHECK_DATA_MBUF(m)	do {					\
378120492Sfjoe		struct mbuf *n;						\
379120492Sfjoe		int total;						\
380120492Sfjoe									\
381120492Sfjoe		M_ASSERTPKTHDR(m);					\
382120492Sfjoe		for (total = 0, n = (m); n != NULL; n = n->m_next) {	\
383120492Sfjoe			total += n->m_len;				\
384120492Sfjoe			if (n->m_nextpkt != NULL)			\
385120492Sfjoe				panic("%s: m_nextpkt", __func__);	\
386120492Sfjoe		}							\
387120492Sfjoe									\
388120492Sfjoe		if ((m)->m_pkthdr.len != total) {			\
389120492Sfjoe			panic("%s: %d != %d",				\
390120492Sfjoe			    __func__, (m)->m_pkthdr.len, total);	\
391120492Sfjoe		}							\
392120492Sfjoe	} while (0)
393120492Sfjoe#else
394120492Sfjoe#define CHECK_DATA_MBUF(m)
395120492Sfjoe#endif
396120492Sfjoe
397120492Sfjoe#define ERROUT(x)	do { error = (x); goto done; } while (0)
398120492Sfjoe
399120492Sfjoe/************************************************************************
400120492Sfjoe	Parse type definitions for generic messages
401120492Sfjoe************************************************************************/
402120492Sfjoe
403120492Sfjoe/* Handy structure parse type defining macro */
404120492Sfjoe#define DEFINE_PARSE_STRUCT_TYPE(lo, up, args)				\
405120492Sfjoestatic const struct ng_parse_struct_field				\
406120492Sfjoe	ng_ ## lo ## _type_fields[] = NG_GENERIC_ ## up ## _INFO args;	\
407120492Sfjoestatic const struct ng_parse_type ng_generic_ ## lo ## _type = {	\
408120492Sfjoe	&ng_parse_struct_type,						\
409120492Sfjoe	&ng_ ## lo ## _type_fields					\
410120492Sfjoe}
411120492Sfjoe
412120492SfjoeDEFINE_PARSE_STRUCT_TYPE(mkpeer, MKPEER, ());
413120492SfjoeDEFINE_PARSE_STRUCT_TYPE(connect, CONNECT, ());
414120492SfjoeDEFINE_PARSE_STRUCT_TYPE(name, NAME, ());
415120492SfjoeDEFINE_PARSE_STRUCT_TYPE(rmhook, RMHOOK, ());
416120492SfjoeDEFINE_PARSE_STRUCT_TYPE(nodeinfo, NODEINFO, ());
417120492SfjoeDEFINE_PARSE_STRUCT_TYPE(typeinfo, TYPEINFO, ());
418120492SfjoeDEFINE_PARSE_STRUCT_TYPE(linkinfo, LINKINFO, (&ng_generic_nodeinfo_type));
419120492Sfjoe
420120492Sfjoe/* Get length of an array when the length is stored as a 32 bit
421120492Sfjoe   value immediately preceding the array -- as with struct namelist
422120492Sfjoe   and struct typelist. */
423120492Sfjoestatic int
424120492Sfjoeng_generic_list_getLength(const struct ng_parse_type *type,
425120492Sfjoe	const u_char *start, const u_char *buf)
426120492Sfjoe{
427120492Sfjoe	return *((const u_int32_t *)(buf - 4));
428120492Sfjoe}
429120492Sfjoe
430120492Sfjoe/* Get length of the array of struct linkinfo inside a struct hooklist */
431120492Sfjoestatic int
432120492Sfjoeng_generic_linkinfo_getLength(const struct ng_parse_type *type,
433120492Sfjoe	const u_char *start, const u_char *buf)
434120492Sfjoe{
435120492Sfjoe	const struct hooklist *hl = (const struct hooklist *)start;
436120492Sfjoe
437120492Sfjoe	return hl->nodeinfo.hooks;
438120492Sfjoe}
439120492Sfjoe
440120492Sfjoe/* Array type for a variable length array of struct namelist */
441120492Sfjoestatic const struct ng_parse_array_info ng_nodeinfoarray_type_info = {
442120492Sfjoe	&ng_generic_nodeinfo_type,
443120492Sfjoe	&ng_generic_list_getLength
444120492Sfjoe};
445120492Sfjoestatic const struct ng_parse_type ng_generic_nodeinfoarray_type = {
446194638Sdelphij	&ng_parse_array_type,
447194638Sdelphij	&ng_nodeinfoarray_type_info
448120492Sfjoe};
449120492Sfjoe
450120492Sfjoe/* Array type for a variable length array of struct typelist */
451194638Sdelphijstatic const struct ng_parse_array_info ng_typeinfoarray_type_info = {
452194638Sdelphij	&ng_generic_typeinfo_type,
453120492Sfjoe	&ng_generic_list_getLength
454194638Sdelphij};
455120492Sfjoestatic const struct ng_parse_type ng_generic_typeinfoarray_type = {
456120492Sfjoe	&ng_parse_array_type,
457120492Sfjoe	&ng_typeinfoarray_type_info
458120492Sfjoe};
459123293Sfjoe
460194638Sdelphij/* Array type for array of struct linkinfo in struct hooklist */
461123293Sfjoestatic const struct ng_parse_array_info ng_generic_linkinfo_array_type_info = {
462123293Sfjoe	&ng_generic_linkinfo_type,
463123293Sfjoe	&ng_generic_linkinfo_getLength
464123293Sfjoe};
465123293Sfjoestatic const struct ng_parse_type ng_generic_linkinfo_array_type = {
466120492Sfjoe	&ng_parse_array_type,
467	&ng_generic_linkinfo_array_type_info
468};
469
470DEFINE_PARSE_STRUCT_TYPE(typelist, TYPELIST, (&ng_generic_nodeinfoarray_type));
471DEFINE_PARSE_STRUCT_TYPE(hooklist, HOOKLIST,
472	(&ng_generic_nodeinfo_type, &ng_generic_linkinfo_array_type));
473DEFINE_PARSE_STRUCT_TYPE(listnodes, LISTNODES,
474	(&ng_generic_nodeinfoarray_type));
475
476/* List of commands and how to convert arguments to/from ASCII */
477static const struct ng_cmdlist ng_generic_cmds[] = {
478	{
479	  NGM_GENERIC_COOKIE,
480	  NGM_SHUTDOWN,
481	  "shutdown",
482	  NULL,
483	  NULL
484	},
485	{
486	  NGM_GENERIC_COOKIE,
487	  NGM_MKPEER,
488	  "mkpeer",
489	  &ng_generic_mkpeer_type,
490	  NULL
491	},
492	{
493	  NGM_GENERIC_COOKIE,
494	  NGM_CONNECT,
495	  "connect",
496	  &ng_generic_connect_type,
497	  NULL
498	},
499	{
500	  NGM_GENERIC_COOKIE,
501	  NGM_NAME,
502	  "name",
503	  &ng_generic_name_type,
504	  NULL
505	},
506	{
507	  NGM_GENERIC_COOKIE,
508	  NGM_RMHOOK,
509	  "rmhook",
510	  &ng_generic_rmhook_type,
511	  NULL
512	},
513	{
514	  NGM_GENERIC_COOKIE,
515	  NGM_NODEINFO,
516	  "nodeinfo",
517	  NULL,
518	  &ng_generic_nodeinfo_type
519	},
520	{
521	  NGM_GENERIC_COOKIE,
522	  NGM_LISTHOOKS,
523	  "listhooks",
524	  NULL,
525	  &ng_generic_hooklist_type
526	},
527	{
528	  NGM_GENERIC_COOKIE,
529	  NGM_LISTNAMES,
530	  "listnames",
531	  NULL,
532	  &ng_generic_listnodes_type	/* same as NGM_LISTNODES */
533	},
534	{
535	  NGM_GENERIC_COOKIE,
536	  NGM_LISTNODES,
537	  "listnodes",
538	  NULL,
539	  &ng_generic_listnodes_type
540	},
541	{
542	  NGM_GENERIC_COOKIE,
543	  NGM_LISTTYPES,
544	  "listtypes",
545	  NULL,
546	  &ng_generic_typeinfo_type
547	},
548	{
549	  NGM_GENERIC_COOKIE,
550	  NGM_TEXT_CONFIG,
551	  "textconfig",
552	  NULL,
553	  &ng_parse_string_type
554	},
555	{
556	  NGM_GENERIC_COOKIE,
557	  NGM_TEXT_STATUS,
558	  "textstatus",
559	  NULL,
560	  &ng_parse_string_type
561	},
562	{
563	  NGM_GENERIC_COOKIE,
564	  NGM_ASCII2BINARY,
565	  "ascii2binary",
566	  &ng_parse_ng_mesg_type,
567	  &ng_parse_ng_mesg_type
568	},
569	{
570	  NGM_GENERIC_COOKIE,
571	  NGM_BINARY2ASCII,
572	  "binary2ascii",
573	  &ng_parse_ng_mesg_type,
574	  &ng_parse_ng_mesg_type
575	},
576	{ 0 }
577};
578
579/************************************************************************
580			Node routines
581************************************************************************/
582
583/*
584 * Instantiate a node of the requested type
585 */
586int
587ng_make_node(const char *typename, node_p *nodepp)
588{
589	struct ng_type *type;
590	int	error;
591
592	/* Check that the type makes sense */
593	if (typename == NULL) {
594		TRAP_ERROR();
595		return (EINVAL);
596	}
597
598	/* Locate the node type. If we fail we return. Do not try to load
599	 * module.
600	 */
601	if ((type = ng_findtype(typename)) == NULL)
602		return (ENXIO);
603
604	/*
605	 * If we have a constructor, then make the node and
606	 * call the constructor to do type specific initialisation.
607	 */
608	if (type->constructor != NULL) {
609		if ((error = ng_make_node_common(type, nodepp)) == 0) {
610			if ((error = ((*type->constructor)(*nodepp))) != 0) {
611				NG_NODE_UNREF(*nodepp);
612			}
613		}
614	} else {
615		/*
616		 * Node has no constructor. We cannot ask for one
617		 * to be made. It must be brought into existence by
618		 * some external agency. The external agency should
619		 * call ng_make_node_common() directly to get the
620		 * netgraph part initialised.
621		 */
622		TRAP_ERROR();
623		error = EINVAL;
624	}
625	return (error);
626}
627
628/*
629 * Generic node creation. Called by node initialisation for externally
630 * instantiated nodes (e.g. hardware, sockets, etc ).
631 * The returned node has a reference count of 1.
632 */
633int
634ng_make_node_common(struct ng_type *type, node_p *nodepp)
635{
636	node_p node;
637
638	/* Require the node type to have been already installed */
639	if (ng_findtype(type->name) == NULL) {
640		TRAP_ERROR();
641		return (EINVAL);
642	}
643
644	/* Make a node and try attach it to the type */
645	NG_ALLOC_NODE(node);
646	if (node == NULL) {
647		TRAP_ERROR();
648		return (ENOMEM);
649	}
650	node->nd_type = type;
651#ifdef VIMAGE
652	node->nd_vnet = curvnet;
653#endif
654	NG_NODE_REF(node);				/* note reference */
655	type->refs++;
656
657	NG_QUEUE_LOCK_INIT(&node->nd_input_queue);
658	STAILQ_INIT(&node->nd_input_queue.queue);
659	node->nd_input_queue.q_flags = 0;
660
661	/* Initialize hook list for new node */
662	LIST_INIT(&node->nd_hooks);
663
664	/* Link us into the name hash. */
665	NAMEHASH_WLOCK();
666	LIST_INSERT_HEAD(&V_ng_name_hash[0], node, nd_nodes);
667	NAMEHASH_WUNLOCK();
668
669	/* get an ID and put us in the hash chain */
670	IDHASH_WLOCK();
671	for (;;) { /* wrap protection, even if silly */
672		node_p node2 = NULL;
673		node->nd_ID = V_nextID++; /* 137/sec for 1 year before wrap */
674
675		/* Is there a problem with the new number? */
676		NG_IDHASH_FIND(node->nd_ID, node2); /* already taken? */
677		if ((node->nd_ID != 0) && (node2 == NULL)) {
678			break;
679		}
680	}
681	LIST_INSERT_HEAD(&V_ng_ID_hash[NG_IDHASH_FN(node->nd_ID)], node,
682	    nd_idnodes);
683	IDHASH_WUNLOCK();
684
685	/* Done */
686	*nodepp = node;
687	return (0);
688}
689
690/*
691 * Forceably start the shutdown process on a node. Either call
692 * its shutdown method, or do the default shutdown if there is
693 * no type-specific method.
694 *
695 * We can only be called from a shutdown message, so we know we have
696 * a writer lock, and therefore exclusive access. It also means
697 * that we should not be on the work queue, but we check anyhow.
698 *
699 * Persistent node types must have a type-specific method which
700 * allocates a new node in which case, this one is irretrievably going away,
701 * or cleans up anything it needs, and just makes the node valid again,
702 * in which case we allow the node to survive.
703 *
704 * XXX We need to think of how to tell a persistent node that we
705 * REALLY need to go away because the hardware has gone or we
706 * are rebooting.... etc.
707 */
708void
709ng_rmnode(node_p node, hook_p dummy1, void *dummy2, int dummy3)
710{
711	hook_p hook;
712
713	/* Check if it's already shutting down */
714	if ((node->nd_flags & NGF_CLOSING) != 0)
715		return;
716
717	if (node == &ng_deadnode) {
718		printf ("shutdown called on deadnode\n");
719		return;
720	}
721
722	/* Add an extra reference so it doesn't go away during this */
723	NG_NODE_REF(node);
724
725	/*
726	 * Mark it invalid so any newcomers know not to try use it
727	 * Also add our own mark so we can't recurse
728	 * note that NGF_INVALID does not do this as it's also set during
729	 * creation
730	 */
731	node->nd_flags |= NGF_INVALID|NGF_CLOSING;
732
733	/* If node has its pre-shutdown method, then call it first*/
734	if (node->nd_type && node->nd_type->close)
735		(*node->nd_type->close)(node);
736
737	/* Notify all remaining connected nodes to disconnect */
738	while ((hook = LIST_FIRST(&node->nd_hooks)) != NULL)
739		ng_destroy_hook(hook);
740
741	/*
742	 * Drain the input queue forceably.
743	 * it has no hooks so what's it going to do, bleed on someone?
744	 * Theoretically we came here from a queue entry that was added
745	 * Just before the queue was closed, so it should be empty anyway.
746	 * Also removes us from worklist if needed.
747	 */
748	ng_flush_input_queue(node);
749
750	/* Ask the type if it has anything to do in this case */
751	if (node->nd_type && node->nd_type->shutdown) {
752		(*node->nd_type->shutdown)(node);
753		if (NG_NODE_IS_VALID(node)) {
754			/*
755			 * Well, blow me down if the node code hasn't declared
756			 * that it doesn't want to die.
757			 * Presumably it is a persistant node.
758			 * If we REALLY want it to go away,
759			 *  e.g. hardware going away,
760			 * Our caller should set NGF_REALLY_DIE in nd_flags.
761			 */
762			node->nd_flags &= ~(NGF_INVALID|NGF_CLOSING);
763			NG_NODE_UNREF(node); /* Assume they still have theirs */
764			return;
765		}
766	} else {				/* do the default thing */
767		NG_NODE_UNREF(node);
768	}
769
770	ng_unname(node); /* basically a NOP these days */
771
772	/*
773	 * Remove extra reference, possibly the last
774	 * Possible other holders of references may include
775	 * timeout callouts, but theoretically the node's supposed to
776	 * have cancelled them. Possibly hardware dependencies may
777	 * force a driver to 'linger' with a reference.
778	 */
779	NG_NODE_UNREF(node);
780}
781
782/*
783 * Remove a reference to the node, possibly the last.
784 * deadnode always acts as it it were the last.
785 */
786void
787ng_unref_node(node_p node)
788{
789
790	if (node == &ng_deadnode)
791		return;
792
793	if (refcount_release(&node->nd_refs)) { /* we were the last */
794
795		node->nd_type->refs--; /* XXX maybe should get types lock? */
796		NAMEHASH_WLOCK();
797		LIST_REMOVE(node, nd_nodes);
798		NAMEHASH_WUNLOCK();
799
800		IDHASH_WLOCK();
801		LIST_REMOVE(node, nd_idnodes);
802		IDHASH_WUNLOCK();
803
804		mtx_destroy(&node->nd_input_queue.q_mtx);
805		NG_FREE_NODE(node);
806	}
807}
808
809/************************************************************************
810			Node ID handling
811************************************************************************/
812static node_p
813ng_ID2noderef(ng_ID_t ID)
814{
815	node_p node;
816	IDHASH_RLOCK();
817	NG_IDHASH_FIND(ID, node);
818	if(node)
819		NG_NODE_REF(node);
820	IDHASH_RUNLOCK();
821	return(node);
822}
823
824ng_ID_t
825ng_node2ID(node_p node)
826{
827	return (node ? NG_NODE_ID(node) : 0);
828}
829
830/************************************************************************
831			Node name handling
832************************************************************************/
833
834/*
835 * Assign a node a name.
836 */
837int
838ng_name_node(node_p node, const char *name)
839{
840	int i, hash;
841	node_p node2;
842
843	/* Check the name is valid */
844	for (i = 0; i < NG_NODESIZ; i++) {
845		if (name[i] == '\0' || name[i] == '.' || name[i] == ':')
846			break;
847	}
848	if (i == 0 || name[i] != '\0') {
849		TRAP_ERROR();
850		return (EINVAL);
851	}
852	if (ng_decodeidname(name) != 0) { /* valid IDs not allowed here */
853		TRAP_ERROR();
854		return (EINVAL);
855	}
856
857	/* Check the name isn't already being used */
858	if ((node2 = ng_name2noderef(node, name)) != NULL) {
859		NG_NODE_UNREF(node2);
860		TRAP_ERROR();
861		return (EADDRINUSE);
862	}
863
864	/* copy it */
865	strlcpy(NG_NODE_NAME(node), name, NG_NODESIZ);
866
867	/* Update name hash. */
868	NG_NAMEHASH(name, hash);
869	NAMEHASH_WLOCK();
870	LIST_REMOVE(node, nd_nodes);
871	LIST_INSERT_HEAD(&V_ng_name_hash[hash], node, nd_nodes);
872	NAMEHASH_WUNLOCK();
873
874	return (0);
875}
876
877/*
878 * Find a node by absolute name. The name should NOT end with ':'
879 * The name "." means "this node" and "[xxx]" means "the node
880 * with ID (ie, at address) xxx".
881 *
882 * Returns the node if found, else NULL.
883 * Eventually should add something faster than a sequential search.
884 * Note it acquires a reference on the node so you can be sure it's still
885 * there.
886 */
887node_p
888ng_name2noderef(node_p here, const char *name)
889{
890	node_p node;
891	ng_ID_t temp;
892	int	hash;
893
894	/* "." means "this node" */
895	if (strcmp(name, ".") == 0) {
896		NG_NODE_REF(here);
897		return(here);
898	}
899
900	/* Check for name-by-ID */
901	if ((temp = ng_decodeidname(name)) != 0) {
902		return (ng_ID2noderef(temp));
903	}
904
905	/* Find node by name */
906	NG_NAMEHASH(name, hash);
907	NAMEHASH_RLOCK();
908	LIST_FOREACH(node, &V_ng_name_hash[hash], nd_nodes)
909		if (NG_NODE_IS_VALID(node) &&
910		    (strcmp(NG_NODE_NAME(node), name) == 0)) {
911			NG_NODE_REF(node);
912			break;
913		}
914	NAMEHASH_RUNLOCK();
915
916	return (node);
917}
918
919/*
920 * Decode an ID name, eg. "[f03034de]". Returns 0 if the
921 * string is not valid, otherwise returns the value.
922 */
923static ng_ID_t
924ng_decodeidname(const char *name)
925{
926	const int len = strlen(name);
927	char *eptr;
928	u_long val;
929
930	/* Check for proper length, brackets, no leading junk */
931	if ((len < 3) || (name[0] != '[') || (name[len - 1] != ']') ||
932	    (!isxdigit(name[1])))
933		return ((ng_ID_t)0);
934
935	/* Decode number */
936	val = strtoul(name + 1, &eptr, 16);
937	if ((eptr - name != len - 1) || (val == ULONG_MAX) || (val == 0))
938		return ((ng_ID_t)0);
939
940	return ((ng_ID_t)val);
941}
942
943/*
944 * Remove a name from a node. This should only be called
945 * when shutting down and removing the node.
946 */
947void
948ng_unname(node_p node)
949{
950}
951
952/************************************************************************
953			Hook routines
954 Names are not optional. Hooks are always connected, except for a
955 brief moment within these routines. On invalidation or during creation
956 they are connected to the 'dead' hook.
957************************************************************************/
958
959/*
960 * Remove a hook reference
961 */
962void
963ng_unref_hook(hook_p hook)
964{
965
966	if (hook == &ng_deadhook)
967		return;
968
969	if (refcount_release(&hook->hk_refs)) { /* we were the last */
970		if (_NG_HOOK_NODE(hook)) /* it'll probably be ng_deadnode */
971			_NG_NODE_UNREF((_NG_HOOK_NODE(hook)));
972		NG_FREE_HOOK(hook);
973	}
974}
975
976/*
977 * Add an unconnected hook to a node. Only used internally.
978 * Assumes node is locked. (XXX not yet true )
979 */
980static int
981ng_add_hook(node_p node, const char *name, hook_p *hookp)
982{
983	hook_p hook;
984	int error = 0;
985
986	/* Check that the given name is good */
987	if (name == NULL) {
988		TRAP_ERROR();
989		return (EINVAL);
990	}
991	if (ng_findhook(node, name) != NULL) {
992		TRAP_ERROR();
993		return (EEXIST);
994	}
995
996	/* Allocate the hook and link it up */
997	NG_ALLOC_HOOK(hook);
998	if (hook == NULL) {
999		TRAP_ERROR();
1000		return (ENOMEM);
1001	}
1002	hook->hk_refs = 1;		/* add a reference for us to return */
1003	hook->hk_flags = HK_INVALID;
1004	hook->hk_peer = &ng_deadhook;	/* start off this way */
1005	hook->hk_node = node;
1006	NG_NODE_REF(node);		/* each hook counts as a reference */
1007
1008	/* Set hook name */
1009	strlcpy(NG_HOOK_NAME(hook), name, NG_HOOKSIZ);
1010
1011	/*
1012	 * Check if the node type code has something to say about it
1013	 * If it fails, the unref of the hook will also unref the node.
1014	 */
1015	if (node->nd_type->newhook != NULL) {
1016		if ((error = (*node->nd_type->newhook)(node, hook, name))) {
1017			NG_HOOK_UNREF(hook);	/* this frees the hook */
1018			return (error);
1019		}
1020	}
1021	/*
1022	 * The 'type' agrees so far, so go ahead and link it in.
1023	 * We'll ask again later when we actually connect the hooks.
1024	 */
1025	LIST_INSERT_HEAD(&node->nd_hooks, hook, hk_hooks);
1026	node->nd_numhooks++;
1027	NG_HOOK_REF(hook);	/* one for the node */
1028
1029	if (hookp)
1030		*hookp = hook;
1031	return (0);
1032}
1033
1034/*
1035 * Find a hook
1036 *
1037 * Node types may supply their own optimized routines for finding
1038 * hooks.  If none is supplied, we just do a linear search.
1039 * XXX Possibly we should add a reference to the hook?
1040 */
1041hook_p
1042ng_findhook(node_p node, const char *name)
1043{
1044	hook_p hook;
1045
1046	if (node->nd_type->findhook != NULL)
1047		return (*node->nd_type->findhook)(node, name);
1048	LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) {
1049		if (NG_HOOK_IS_VALID(hook) &&
1050		    (strcmp(NG_HOOK_NAME(hook), name) == 0))
1051			return (hook);
1052	}
1053	return (NULL);
1054}
1055
1056/*
1057 * Destroy a hook
1058 *
1059 * As hooks are always attached, this really destroys two hooks.
1060 * The one given, and the one attached to it. Disconnect the hooks
1061 * from each other first. We reconnect the peer hook to the 'dead'
1062 * hook so that it can still exist after we depart. We then
1063 * send the peer its own destroy message. This ensures that we only
1064 * interact with the peer's structures when it is locked processing that
1065 * message. We hold a reference to the peer hook so we are guaranteed that
1066 * the peer hook and node are still going to exist until
1067 * we are finished there as the hook holds a ref on the node.
1068 * We run this same code again on the peer hook, but that time it is already
1069 * attached to the 'dead' hook.
1070 *
1071 * This routine is called at all stages of hook creation
1072 * on error detection and must be able to handle any such stage.
1073 */
1074void
1075ng_destroy_hook(hook_p hook)
1076{
1077	hook_p peer;
1078	node_p node;
1079
1080	if (hook == &ng_deadhook) {	/* better safe than sorry */
1081		printf("ng_destroy_hook called on deadhook\n");
1082		return;
1083	}
1084
1085	/*
1086	 * Protect divorce process with mutex, to avoid races on
1087	 * simultaneous disconnect.
1088	 */
1089	mtx_lock(&ng_topo_mtx);
1090
1091	hook->hk_flags |= HK_INVALID;
1092
1093	peer = NG_HOOK_PEER(hook);
1094	node = NG_HOOK_NODE(hook);
1095
1096	if (peer && (peer != &ng_deadhook)) {
1097		/*
1098		 * Set the peer to point to ng_deadhook
1099		 * from this moment on we are effectively independent it.
1100		 * send it an rmhook message of it's own.
1101		 */
1102		peer->hk_peer = &ng_deadhook;	/* They no longer know us */
1103		hook->hk_peer = &ng_deadhook;	/* Nor us, them */
1104		if (NG_HOOK_NODE(peer) == &ng_deadnode) {
1105			/*
1106			 * If it's already divorced from a node,
1107			 * just free it.
1108			 */
1109			mtx_unlock(&ng_topo_mtx);
1110		} else {
1111			mtx_unlock(&ng_topo_mtx);
1112			ng_rmhook_self(peer); 	/* Send it a surprise */
1113		}
1114		NG_HOOK_UNREF(peer);		/* account for peer link */
1115		NG_HOOK_UNREF(hook);		/* account for peer link */
1116	} else
1117		mtx_unlock(&ng_topo_mtx);
1118
1119	mtx_assert(&ng_topo_mtx, MA_NOTOWNED);
1120
1121	/*
1122	 * Remove the hook from the node's list to avoid possible recursion
1123	 * in case the disconnection results in node shutdown.
1124	 */
1125	if (node == &ng_deadnode) { /* happens if called from ng_con_nodes() */
1126		return;
1127	}
1128	LIST_REMOVE(hook, hk_hooks);
1129	node->nd_numhooks--;
1130	if (node->nd_type->disconnect) {
1131		/*
1132		 * The type handler may elect to destroy the node so don't
1133		 * trust its existence after this point. (except
1134		 * that we still hold a reference on it. (which we
1135		 * inherrited from the hook we are destroying)
1136		 */
1137		(*node->nd_type->disconnect) (hook);
1138	}
1139
1140	/*
1141	 * Note that because we will point to ng_deadnode, the original node
1142	 * is not decremented automatically so we do that manually.
1143	 */
1144	_NG_HOOK_NODE(hook) = &ng_deadnode;
1145	NG_NODE_UNREF(node);	/* We no longer point to it so adjust count */
1146	NG_HOOK_UNREF(hook);	/* Account for linkage (in list) to node */
1147}
1148
1149/*
1150 * Take two hooks on a node and merge the connection so that the given node
1151 * is effectively bypassed.
1152 */
1153int
1154ng_bypass(hook_p hook1, hook_p hook2)
1155{
1156	if (hook1->hk_node != hook2->hk_node) {
1157		TRAP_ERROR();
1158		return (EINVAL);
1159	}
1160	mtx_lock(&ng_topo_mtx);
1161	if (NG_HOOK_NOT_VALID(hook1) || NG_HOOK_NOT_VALID(hook2)) {
1162		mtx_unlock(&ng_topo_mtx);
1163		return (EINVAL);
1164	}
1165	hook1->hk_peer->hk_peer = hook2->hk_peer;
1166	hook2->hk_peer->hk_peer = hook1->hk_peer;
1167
1168	hook1->hk_peer = &ng_deadhook;
1169	hook2->hk_peer = &ng_deadhook;
1170	mtx_unlock(&ng_topo_mtx);
1171
1172	NG_HOOK_UNREF(hook1);
1173	NG_HOOK_UNREF(hook2);
1174
1175	/* XXX If we ever cache methods on hooks update them as well */
1176	ng_destroy_hook(hook1);
1177	ng_destroy_hook(hook2);
1178	return (0);
1179}
1180
1181/*
1182 * Install a new netgraph type
1183 */
1184int
1185ng_newtype(struct ng_type *tp)
1186{
1187	const size_t namelen = strlen(tp->name);
1188
1189	/* Check version and type name fields */
1190	if ((tp->version != NG_ABI_VERSION) || (namelen == 0) ||
1191	    (namelen >= NG_TYPESIZ)) {
1192		TRAP_ERROR();
1193		if (tp->version != NG_ABI_VERSION) {
1194			printf("Netgraph: Node type rejected. ABI mismatch. "
1195			    "Suggest recompile\n");
1196		}
1197		return (EINVAL);
1198	}
1199
1200	/* Check for name collision */
1201	if (ng_findtype(tp->name) != NULL) {
1202		TRAP_ERROR();
1203		return (EEXIST);
1204	}
1205
1206	/* Link in new type */
1207	TYPELIST_WLOCK();
1208	LIST_INSERT_HEAD(&ng_typelist, tp, types);
1209	tp->refs = 1;	/* first ref is linked list */
1210	TYPELIST_WUNLOCK();
1211	return (0);
1212}
1213
1214/*
1215 * unlink a netgraph type
1216 * If no examples exist
1217 */
1218int
1219ng_rmtype(struct ng_type *tp)
1220{
1221	/* Check for name collision */
1222	if (tp->refs != 1) {
1223		TRAP_ERROR();
1224		return (EBUSY);
1225	}
1226
1227	/* Unlink type */
1228	TYPELIST_WLOCK();
1229	LIST_REMOVE(tp, types);
1230	TYPELIST_WUNLOCK();
1231	return (0);
1232}
1233
1234/*
1235 * Look for a type of the name given
1236 */
1237struct ng_type *
1238ng_findtype(const char *typename)
1239{
1240	struct ng_type *type;
1241
1242	TYPELIST_RLOCK();
1243	LIST_FOREACH(type, &ng_typelist, types) {
1244		if (strcmp(type->name, typename) == 0)
1245			break;
1246	}
1247	TYPELIST_RUNLOCK();
1248	return (type);
1249}
1250
1251/************************************************************************
1252			Composite routines
1253************************************************************************/
1254/*
1255 * Connect two nodes using the specified hooks, using queued functions.
1256 */
1257static int
1258ng_con_part3(node_p node, item_p item, hook_p hook)
1259{
1260	int	error = 0;
1261
1262	/*
1263	 * When we run, we know that the node 'node' is locked for us.
1264	 * Our caller has a reference on the hook.
1265	 * Our caller has a reference on the node.
1266	 * (In this case our caller is ng_apply_item() ).
1267	 * The peer hook has a reference on the hook.
1268	 * We are all set up except for the final call to the node, and
1269	 * the clearing of the INVALID flag.
1270	 */
1271	if (NG_HOOK_NODE(hook) == &ng_deadnode) {
1272		/*
1273		 * The node must have been freed again since we last visited
1274		 * here. ng_destry_hook() has this effect but nothing else does.
1275		 * We should just release our references and
1276		 * free anything we can think of.
1277		 * Since we know it's been destroyed, and it's our caller
1278		 * that holds the references, just return.
1279		 */
1280		ERROUT(ENOENT);
1281	}
1282	if (hook->hk_node->nd_type->connect) {
1283		if ((error = (*hook->hk_node->nd_type->connect) (hook))) {
1284			ng_destroy_hook(hook);	/* also zaps peer */
1285			printf("failed in ng_con_part3()\n");
1286			ERROUT(error);
1287		}
1288	}
1289	/*
1290	 *  XXX this is wrong for SMP. Possibly we need
1291	 * to separate out 'create' and 'invalid' flags.
1292	 * should only set flags on hooks we have locked under our node.
1293	 */
1294	hook->hk_flags &= ~HK_INVALID;
1295done:
1296	NG_FREE_ITEM(item);
1297	return (error);
1298}
1299
1300static int
1301ng_con_part2(node_p node, item_p item, hook_p hook)
1302{
1303	hook_p	peer;
1304	int	error = 0;
1305
1306	/*
1307	 * When we run, we know that the node 'node' is locked for us.
1308	 * Our caller has a reference on the hook.
1309	 * Our caller has a reference on the node.
1310	 * (In this case our caller is ng_apply_item() ).
1311	 * The peer hook has a reference on the hook.
1312	 * our node pointer points to the 'dead' node.
1313	 * First check the hook name is unique.
1314	 * Should not happen because we checked before queueing this.
1315	 */
1316	if (ng_findhook(node, NG_HOOK_NAME(hook)) != NULL) {
1317		TRAP_ERROR();
1318		ng_destroy_hook(hook); /* should destroy peer too */
1319		printf("failed in ng_con_part2()\n");
1320		ERROUT(EEXIST);
1321	}
1322	/*
1323	 * Check if the node type code has something to say about it
1324	 * If it fails, the unref of the hook will also unref the attached node,
1325	 * however since that node is 'ng_deadnode' this will do nothing.
1326	 * The peer hook will also be destroyed.
1327	 */
1328	if (node->nd_type->newhook != NULL) {
1329		if ((error = (*node->nd_type->newhook)(node, hook,
1330		    hook->hk_name))) {
1331			ng_destroy_hook(hook); /* should destroy peer too */
1332			printf("failed in ng_con_part2()\n");
1333			ERROUT(error);
1334		}
1335	}
1336
1337	/*
1338	 * The 'type' agrees so far, so go ahead and link it in.
1339	 * We'll ask again later when we actually connect the hooks.
1340	 */
1341	hook->hk_node = node;		/* just overwrite ng_deadnode */
1342	NG_NODE_REF(node);		/* each hook counts as a reference */
1343	LIST_INSERT_HEAD(&node->nd_hooks, hook, hk_hooks);
1344	node->nd_numhooks++;
1345	NG_HOOK_REF(hook);	/* one for the node */
1346
1347	/*
1348	 * We now have a symmetrical situation, where both hooks have been
1349	 * linked to their nodes, the newhook methods have been called
1350	 * And the references are all correct. The hooks are still marked
1351	 * as invalid, as we have not called the 'connect' methods
1352	 * yet.
1353	 * We can call the local one immediately as we have the
1354	 * node locked, but we need to queue the remote one.
1355	 */
1356	if (hook->hk_node->nd_type->connect) {
1357		if ((error = (*hook->hk_node->nd_type->connect) (hook))) {
1358			ng_destroy_hook(hook);	/* also zaps peer */
1359			printf("failed in ng_con_part2(A)\n");
1360			ERROUT(error);
1361		}
1362	}
1363
1364	/*
1365	 * Acquire topo mutex to avoid race with ng_destroy_hook().
1366	 */
1367	mtx_lock(&ng_topo_mtx);
1368	peer = hook->hk_peer;
1369	if (peer == &ng_deadhook) {
1370		mtx_unlock(&ng_topo_mtx);
1371		printf("failed in ng_con_part2(B)\n");
1372		ng_destroy_hook(hook);
1373		ERROUT(ENOENT);
1374	}
1375	mtx_unlock(&ng_topo_mtx);
1376
1377	if ((error = ng_send_fn2(peer->hk_node, peer, item, &ng_con_part3,
1378	    NULL, 0, NG_REUSE_ITEM))) {
1379		printf("failed in ng_con_part2(C)\n");
1380		ng_destroy_hook(hook);	/* also zaps peer */
1381		return (error);		/* item was consumed. */
1382	}
1383	hook->hk_flags &= ~HK_INVALID; /* need both to be able to work */
1384	return (0);			/* item was consumed. */
1385done:
1386	NG_FREE_ITEM(item);
1387	return (error);
1388}
1389
1390/*
1391 * Connect this node with another node. We assume that this node is
1392 * currently locked, as we are only called from an NGM_CONNECT message.
1393 */
1394static int
1395ng_con_nodes(item_p item, node_p node, const char *name,
1396    node_p node2, const char *name2)
1397{
1398	int	error;
1399	hook_p	hook;
1400	hook_p	hook2;
1401
1402	if (ng_findhook(node2, name2) != NULL) {
1403		return(EEXIST);
1404	}
1405	if ((error = ng_add_hook(node, name, &hook)))  /* gives us a ref */
1406		return (error);
1407	/* Allocate the other hook and link it up */
1408	NG_ALLOC_HOOK(hook2);
1409	if (hook2 == NULL) {
1410		TRAP_ERROR();
1411		ng_destroy_hook(hook);	/* XXX check ref counts so far */
1412		NG_HOOK_UNREF(hook);	/* including our ref */
1413		return (ENOMEM);
1414	}
1415	hook2->hk_refs = 1;		/* start with a reference for us. */
1416	hook2->hk_flags = HK_INVALID;
1417	hook2->hk_peer = hook;		/* Link the two together */
1418	hook->hk_peer = hook2;
1419	NG_HOOK_REF(hook);		/* Add a ref for the peer to each*/
1420	NG_HOOK_REF(hook2);
1421	hook2->hk_node = &ng_deadnode;
1422	strlcpy(NG_HOOK_NAME(hook2), name2, NG_HOOKSIZ);
1423
1424	/*
1425	 * Queue the function above.
1426	 * Procesing continues in that function in the lock context of
1427	 * the other node.
1428	 */
1429	if ((error = ng_send_fn2(node2, hook2, item, &ng_con_part2, NULL, 0,
1430	    NG_NOFLAGS))) {
1431		printf("failed in ng_con_nodes(): %d\n", error);
1432		ng_destroy_hook(hook);	/* also zaps peer */
1433	}
1434
1435	NG_HOOK_UNREF(hook);		/* Let each hook go if it wants to */
1436	NG_HOOK_UNREF(hook2);
1437	return (error);
1438}
1439
1440/*
1441 * Make a peer and connect.
1442 * We assume that the local node is locked.
1443 * The new node probably doesn't need a lock until
1444 * it has a hook, because it cannot really have any work until then,
1445 * but we should think about it a bit more.
1446 *
1447 * The problem may come if the other node also fires up
1448 * some hardware or a timer or some other source of activation,
1449 * also it may already get a command msg via it's ID.
1450 *
1451 * We could use the same method as ng_con_nodes() but we'd have
1452 * to add ability to remove the node when failing. (Not hard, just
1453 * make arg1 point to the node to remove).
1454 * Unless of course we just ignore failure to connect and leave
1455 * an unconnected node?
1456 */
1457static int
1458ng_mkpeer(node_p node, const char *name, const char *name2, char *type)
1459{
1460	node_p	node2;
1461	hook_p	hook1, hook2;
1462	int	error;
1463
1464	if ((error = ng_make_node(type, &node2))) {
1465		return (error);
1466	}
1467
1468	if ((error = ng_add_hook(node, name, &hook1))) { /* gives us a ref */
1469		ng_rmnode(node2, NULL, NULL, 0);
1470		return (error);
1471	}
1472
1473	if ((error = ng_add_hook(node2, name2, &hook2))) {
1474		ng_rmnode(node2, NULL, NULL, 0);
1475		ng_destroy_hook(hook1);
1476		NG_HOOK_UNREF(hook1);
1477		return (error);
1478	}
1479
1480	/*
1481	 * Actually link the two hooks together.
1482	 */
1483	hook1->hk_peer = hook2;
1484	hook2->hk_peer = hook1;
1485
1486	/* Each hook is referenced by the other */
1487	NG_HOOK_REF(hook1);
1488	NG_HOOK_REF(hook2);
1489
1490	/* Give each node the opportunity to veto the pending connection */
1491	if (hook1->hk_node->nd_type->connect) {
1492		error = (*hook1->hk_node->nd_type->connect) (hook1);
1493	}
1494
1495	if ((error == 0) && hook2->hk_node->nd_type->connect) {
1496		error = (*hook2->hk_node->nd_type->connect) (hook2);
1497
1498	}
1499
1500	/*
1501	 * drop the references we were holding on the two hooks.
1502	 */
1503	if (error) {
1504		ng_destroy_hook(hook2);	/* also zaps hook1 */
1505		ng_rmnode(node2, NULL, NULL, 0);
1506	} else {
1507		/* As a last act, allow the hooks to be used */
1508		hook1->hk_flags &= ~HK_INVALID;
1509		hook2->hk_flags &= ~HK_INVALID;
1510	}
1511	NG_HOOK_UNREF(hook1);
1512	NG_HOOK_UNREF(hook2);
1513	return (error);
1514}
1515
1516/************************************************************************
1517		Utility routines to send self messages
1518************************************************************************/
1519
1520/* Shut this node down as soon as everyone is clear of it */
1521/* Should add arg "immediately" to jump the queue */
1522int
1523ng_rmnode_self(node_p node)
1524{
1525	int		error;
1526
1527	if (node == &ng_deadnode)
1528		return (0);
1529	node->nd_flags |= NGF_INVALID;
1530	if (node->nd_flags & NGF_CLOSING)
1531		return (0);
1532
1533	error = ng_send_fn(node, NULL, &ng_rmnode, NULL, 0);
1534	return (error);
1535}
1536
1537static void
1538ng_rmhook_part2(node_p node, hook_p hook, void *arg1, int arg2)
1539{
1540	ng_destroy_hook(hook);
1541	return ;
1542}
1543
1544int
1545ng_rmhook_self(hook_p hook)
1546{
1547	int		error;
1548	node_p node = NG_HOOK_NODE(hook);
1549
1550	if (node == &ng_deadnode)
1551		return (0);
1552
1553	error = ng_send_fn(node, hook, &ng_rmhook_part2, NULL, 0);
1554	return (error);
1555}
1556
1557/***********************************************************************
1558 * Parse and verify a string of the form:  <NODE:><PATH>
1559 *
1560 * Such a string can refer to a specific node or a specific hook
1561 * on a specific node, depending on how you look at it. In the
1562 * latter case, the PATH component must not end in a dot.
1563 *
1564 * Both <NODE:> and <PATH> are optional. The <PATH> is a string
1565 * of hook names separated by dots. This breaks out the original
1566 * string, setting *nodep to "NODE" (or NULL if none) and *pathp
1567 * to "PATH" (or NULL if degenerate). Also, *hookp will point to
1568 * the final hook component of <PATH>, if any, otherwise NULL.
1569 *
1570 * This returns -1 if the path is malformed. The char ** are optional.
1571 ***********************************************************************/
1572int
1573ng_path_parse(char *addr, char **nodep, char **pathp, char **hookp)
1574{
1575	char	*node, *path, *hook;
1576	int	k;
1577
1578	/*
1579	 * Extract absolute NODE, if any
1580	 */
1581	for (path = addr; *path && *path != ':'; path++);
1582	if (*path) {
1583		node = addr;	/* Here's the NODE */
1584		*path++ = '\0';	/* Here's the PATH */
1585
1586		/* Node name must not be empty */
1587		if (!*node)
1588			return -1;
1589
1590		/* A name of "." is OK; otherwise '.' not allowed */
1591		if (strcmp(node, ".") != 0) {
1592			for (k = 0; node[k]; k++)
1593				if (node[k] == '.')
1594					return -1;
1595		}
1596	} else {
1597		node = NULL;	/* No absolute NODE */
1598		path = addr;	/* Here's the PATH */
1599	}
1600
1601	/* Snoop for illegal characters in PATH */
1602	for (k = 0; path[k]; k++)
1603		if (path[k] == ':')
1604			return -1;
1605
1606	/* Check for no repeated dots in PATH */
1607	for (k = 0; path[k]; k++)
1608		if (path[k] == '.' && path[k + 1] == '.')
1609			return -1;
1610
1611	/* Remove extra (degenerate) dots from beginning or end of PATH */
1612	if (path[0] == '.')
1613		path++;
1614	if (*path && path[strlen(path) - 1] == '.')
1615		path[strlen(path) - 1] = 0;
1616
1617	/* If PATH has a dot, then we're not talking about a hook */
1618	if (*path) {
1619		for (hook = path, k = 0; path[k]; k++)
1620			if (path[k] == '.') {
1621				hook = NULL;
1622				break;
1623			}
1624	} else
1625		path = hook = NULL;
1626
1627	/* Done */
1628	if (nodep)
1629		*nodep = node;
1630	if (pathp)
1631		*pathp = path;
1632	if (hookp)
1633		*hookp = hook;
1634	return (0);
1635}
1636
1637/*
1638 * Given a path, which may be absolute or relative, and a starting node,
1639 * return the destination node.
1640 */
1641int
1642ng_path2noderef(node_p here, const char *address, node_p *destp,
1643    hook_p *lasthook)
1644{
1645	char    fullpath[NG_PATHSIZ];
1646	char   *nodename, *path;
1647	node_p  node, oldnode;
1648
1649	/* Initialize */
1650	if (destp == NULL) {
1651		TRAP_ERROR();
1652		return EINVAL;
1653	}
1654	*destp = NULL;
1655
1656	/* Make a writable copy of address for ng_path_parse() */
1657	strncpy(fullpath, address, sizeof(fullpath) - 1);
1658	fullpath[sizeof(fullpath) - 1] = '\0';
1659
1660	/* Parse out node and sequence of hooks */
1661	if (ng_path_parse(fullpath, &nodename, &path, NULL) < 0) {
1662		TRAP_ERROR();
1663		return EINVAL;
1664	}
1665
1666	/*
1667	 * For an absolute address, jump to the starting node.
1668	 * Note that this holds a reference on the node for us.
1669	 * Don't forget to drop the reference if we don't need it.
1670	 */
1671	if (nodename) {
1672		node = ng_name2noderef(here, nodename);
1673		if (node == NULL) {
1674			TRAP_ERROR();
1675			return (ENOENT);
1676		}
1677	} else {
1678		if (here == NULL) {
1679			TRAP_ERROR();
1680			return (EINVAL);
1681		}
1682		node = here;
1683		NG_NODE_REF(node);
1684	}
1685
1686	if (path == NULL) {
1687		if (lasthook != NULL)
1688			*lasthook = NULL;
1689		*destp = node;
1690		return (0);
1691	}
1692
1693	/*
1694	 * Now follow the sequence of hooks
1695	 *
1696	 * XXXGL: The path may demolish as we go the sequence, but if
1697	 * we hold the topology mutex at critical places, then, I hope,
1698	 * we would always have valid pointers in hand, although the
1699	 * path behind us may no longer exist.
1700	 */
1701	for (;;) {
1702		hook_p hook;
1703		char *segment;
1704
1705		/*
1706		 * Break out the next path segment. Replace the dot we just
1707		 * found with a NUL; "path" points to the next segment (or the
1708		 * NUL at the end).
1709		 */
1710		for (segment = path; *path != '\0'; path++) {
1711			if (*path == '.') {
1712				*path++ = '\0';
1713				break;
1714			}
1715		}
1716
1717		/* We have a segment, so look for a hook by that name */
1718		hook = ng_findhook(node, segment);
1719
1720		mtx_lock(&ng_topo_mtx);
1721		/* Can't get there from here... */
1722		if (hook == NULL || NG_HOOK_PEER(hook) == NULL ||
1723		    NG_HOOK_NOT_VALID(hook) ||
1724		    NG_HOOK_NOT_VALID(NG_HOOK_PEER(hook))) {
1725			TRAP_ERROR();
1726			NG_NODE_UNREF(node);
1727			mtx_unlock(&ng_topo_mtx);
1728			return (ENOENT);
1729		}
1730
1731		/*
1732		 * Hop on over to the next node
1733		 * XXX
1734		 * Big race conditions here as hooks and nodes go away
1735		 * *** Idea.. store an ng_ID_t in each hook and use that
1736		 * instead of the direct hook in this crawl?
1737		 */
1738		oldnode = node;
1739		if ((node = NG_PEER_NODE(hook)))
1740			NG_NODE_REF(node);	/* XXX RACE */
1741		NG_NODE_UNREF(oldnode);	/* XXX another race */
1742		if (NG_NODE_NOT_VALID(node)) {
1743			NG_NODE_UNREF(node);	/* XXX more races */
1744			mtx_unlock(&ng_topo_mtx);
1745			TRAP_ERROR();
1746			return (ENXIO);
1747		}
1748
1749		if (*path == '\0') {
1750			if (lasthook != NULL) {
1751				if (hook != NULL) {
1752					*lasthook = NG_HOOK_PEER(hook);
1753					NG_HOOK_REF(*lasthook);
1754				} else
1755					*lasthook = NULL;
1756			}
1757			mtx_unlock(&ng_topo_mtx);
1758			*destp = node;
1759			return (0);
1760		}
1761		mtx_unlock(&ng_topo_mtx);
1762	}
1763}
1764
1765/***************************************************************\
1766* Input queue handling.
1767* All activities are submitted to the node via the input queue
1768* which implements a multiple-reader/single-writer gate.
1769* Items which cannot be handled immediately are queued.
1770*
1771* read-write queue locking inline functions			*
1772\***************************************************************/
1773
1774static __inline void	ng_queue_rw(node_p node, item_p  item, int rw);
1775static __inline item_p	ng_dequeue(node_p node, int *rw);
1776static __inline item_p	ng_acquire_read(node_p node, item_p  item);
1777static __inline item_p	ng_acquire_write(node_p node, item_p  item);
1778static __inline void	ng_leave_read(node_p node);
1779static __inline void	ng_leave_write(node_p node);
1780
1781/*
1782 * Definition of the bits fields in the ng_queue flag word.
1783 * Defined here rather than in netgraph.h because no-one should fiddle
1784 * with them.
1785 *
1786 * The ordering here may be important! don't shuffle these.
1787 */
1788/*-
1789 Safety Barrier--------+ (adjustable to suit taste) (not used yet)
1790                       |
1791                       V
1792+-------+-------+-------+-------+-------+-------+-------+-------+
1793  | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
1794  | |A|c|t|i|v|e| |R|e|a|d|e|r| |C|o|u|n|t| | | | | | | | | |P|A|
1795  | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |O|W|
1796+-------+-------+-------+-------+-------+-------+-------+-------+
1797  \___________________________ ____________________________/ | |
1798                            V                                | |
1799                  [active reader count]                      | |
1800                                                             | |
1801            Operation Pending -------------------------------+ |
1802                                                               |
1803          Active Writer ---------------------------------------+
1804
1805Node queue has such semantics:
1806- All flags modifications are atomic.
1807- Reader count can be incremented only if there is no writer or pending flags.
1808  As soon as this can't be done with single operation, it is implemented with
1809  spin loop and atomic_cmpset().
1810- Writer flag can be set only if there is no any bits set.
1811  It is implemented with atomic_cmpset().
1812- Pending flag can be set any time, but to avoid collision on queue processing
1813  all queue fields are protected by the mutex.
1814- Queue processing thread reads queue holding the mutex, but releases it while
1815  processing. When queue is empty pending flag is removed.
1816*/
1817
1818#define WRITER_ACTIVE	0x00000001
1819#define OP_PENDING	0x00000002
1820#define READER_INCREMENT 0x00000004
1821#define READER_MASK	0xfffffffc	/* Not valid if WRITER_ACTIVE is set */
1822#define SAFETY_BARRIER	0x00100000	/* 128K items queued should be enough */
1823
1824/* Defines of more elaborate states on the queue */
1825/* Mask of bits a new read cares about */
1826#define NGQ_RMASK	(WRITER_ACTIVE|OP_PENDING)
1827
1828/* Mask of bits a new write cares about */
1829#define NGQ_WMASK	(NGQ_RMASK|READER_MASK)
1830
1831/* Test to decide if there is something on the queue. */
1832#define QUEUE_ACTIVE(QP) ((QP)->q_flags & OP_PENDING)
1833
1834/* How to decide what the next queued item is. */
1835#define HEAD_IS_READER(QP)  NGI_QUEUED_READER(STAILQ_FIRST(&(QP)->queue))
1836#define HEAD_IS_WRITER(QP)  NGI_QUEUED_WRITER(STAILQ_FIRST(&(QP)->queue)) /* notused */
1837
1838/* Read the status to decide if the next item on the queue can now run. */
1839#define QUEUED_READER_CAN_PROCEED(QP)			\
1840		(((QP)->q_flags & (NGQ_RMASK & ~OP_PENDING)) == 0)
1841#define QUEUED_WRITER_CAN_PROCEED(QP)			\
1842		(((QP)->q_flags & (NGQ_WMASK & ~OP_PENDING)) == 0)
1843
1844/* Is there a chance of getting ANY work off the queue? */
1845#define NEXT_QUEUED_ITEM_CAN_PROCEED(QP)				\
1846	((HEAD_IS_READER(QP)) ? QUEUED_READER_CAN_PROCEED(QP) :		\
1847				QUEUED_WRITER_CAN_PROCEED(QP))
1848
1849#define NGQRW_R 0
1850#define NGQRW_W 1
1851
1852#define NGQ2_WORKQ	0x00000001
1853
1854/*
1855 * Taking into account the current state of the queue and node, possibly take
1856 * the next entry off the queue and return it. Return NULL if there was
1857 * nothing we could return, either because there really was nothing there, or
1858 * because the node was in a state where it cannot yet process the next item
1859 * on the queue.
1860 */
1861static __inline item_p
1862ng_dequeue(node_p node, int *rw)
1863{
1864	item_p item;
1865	struct ng_queue *ngq = &node->nd_input_queue;
1866
1867	/* This MUST be called with the mutex held. */
1868	mtx_assert(&ngq->q_mtx, MA_OWNED);
1869
1870	/* If there is nothing queued, then just return. */
1871	if (!QUEUE_ACTIVE(ngq)) {
1872		CTR4(KTR_NET, "%20s: node [%x] (%p) queue empty; "
1873		    "queue flags 0x%lx", __func__,
1874		    node->nd_ID, node, ngq->q_flags);
1875		return (NULL);
1876	}
1877
1878	/*
1879	 * From here, we can assume there is a head item.
1880	 * We need to find out what it is and if it can be dequeued, given
1881	 * the current state of the node.
1882	 */
1883	if (HEAD_IS_READER(ngq)) {
1884		while (1) {
1885			long t = ngq->q_flags;
1886			if (t & WRITER_ACTIVE) {
1887				/* There is writer, reader can't proceed. */
1888				CTR4(KTR_NET, "%20s: node [%x] (%p) queued "
1889				    "reader can't proceed; queue flags 0x%lx",
1890				    __func__, node->nd_ID, node, t);
1891				return (NULL);
1892			}
1893			if (atomic_cmpset_acq_int(&ngq->q_flags, t,
1894			    t + READER_INCREMENT))
1895				break;
1896			cpu_spinwait();
1897		}
1898		/* We have got reader lock for the node. */
1899		*rw = NGQRW_R;
1900	} else if (atomic_cmpset_acq_int(&ngq->q_flags, OP_PENDING,
1901	    OP_PENDING + WRITER_ACTIVE)) {
1902		/* We have got writer lock for the node. */
1903		*rw = NGQRW_W;
1904	} else {
1905		/* There is somebody other, writer can't proceed. */
1906		CTR4(KTR_NET, "%20s: node [%x] (%p) queued writer can't "
1907		    "proceed; queue flags 0x%lx", __func__, node->nd_ID, node,
1908		    ngq->q_flags);
1909		return (NULL);
1910	}
1911
1912	/*
1913	 * Now we dequeue the request (whatever it may be) and correct the
1914	 * pending flags and the next and last pointers.
1915	 */
1916	item = STAILQ_FIRST(&ngq->queue);
1917	STAILQ_REMOVE_HEAD(&ngq->queue, el_next);
1918	if (STAILQ_EMPTY(&ngq->queue))
1919		atomic_clear_int(&ngq->q_flags, OP_PENDING);
1920	CTR6(KTR_NET, "%20s: node [%x] (%p) returning item %p as %s; queue "
1921	    "flags 0x%lx", __func__, node->nd_ID, node, item, *rw ? "WRITER" :
1922	    "READER", ngq->q_flags);
1923	return (item);
1924}
1925
1926/*
1927 * Queue a packet to be picked up later by someone else.
1928 * If the queue could be run now, add node to the queue handler's worklist.
1929 */
1930static __inline void
1931ng_queue_rw(node_p node, item_p  item, int rw)
1932{
1933	struct ng_queue *ngq = &node->nd_input_queue;
1934	if (rw == NGQRW_W)
1935		NGI_SET_WRITER(item);
1936	else
1937		NGI_SET_READER(item);
1938
1939	NG_QUEUE_LOCK(ngq);
1940	/* Set OP_PENDING flag and enqueue the item. */
1941	atomic_set_int(&ngq->q_flags, OP_PENDING);
1942	STAILQ_INSERT_TAIL(&ngq->queue, item, el_next);
1943
1944	CTR5(KTR_NET, "%20s: node [%x] (%p) queued item %p as %s", __func__,
1945	    node->nd_ID, node, item, rw ? "WRITER" : "READER" );
1946
1947	/*
1948	 * We can take the worklist lock with the node locked
1949	 * BUT NOT THE REVERSE!
1950	 */
1951	if (NEXT_QUEUED_ITEM_CAN_PROCEED(ngq))
1952		ng_worklist_add(node);
1953	NG_QUEUE_UNLOCK(ngq);
1954}
1955
1956/* Acquire reader lock on node. If node is busy, queue the packet. */
1957static __inline item_p
1958ng_acquire_read(node_p node, item_p item)
1959{
1960	KASSERT(node != &ng_deadnode,
1961	    ("%s: working on deadnode", __func__));
1962
1963	/* Reader needs node without writer and pending items. */
1964	for (;;) {
1965		long t = node->nd_input_queue.q_flags;
1966		if (t & NGQ_RMASK)
1967			break; /* Node is not ready for reader. */
1968		if (atomic_cmpset_acq_int(&node->nd_input_queue.q_flags, t,
1969		    t + READER_INCREMENT)) {
1970	    		/* Successfully grabbed node */
1971			CTR4(KTR_NET, "%20s: node [%x] (%p) acquired item %p",
1972			    __func__, node->nd_ID, node, item);
1973			return (item);
1974		}
1975		cpu_spinwait();
1976	};
1977
1978	/* Queue the request for later. */
1979	ng_queue_rw(node, item, NGQRW_R);
1980
1981	return (NULL);
1982}
1983
1984/* Acquire writer lock on node. If node is busy, queue the packet. */
1985static __inline item_p
1986ng_acquire_write(node_p node, item_p item)
1987{
1988	KASSERT(node != &ng_deadnode,
1989	    ("%s: working on deadnode", __func__));
1990
1991	/* Writer needs completely idle node. */
1992	if (atomic_cmpset_acq_int(&node->nd_input_queue.q_flags, 0,
1993	    WRITER_ACTIVE)) {
1994	    	/* Successfully grabbed node */
1995		CTR4(KTR_NET, "%20s: node [%x] (%p) acquired item %p",
1996		    __func__, node->nd_ID, node, item);
1997		return (item);
1998	}
1999
2000	/* Queue the request for later. */
2001	ng_queue_rw(node, item, NGQRW_W);
2002
2003	return (NULL);
2004}
2005
2006#if 0
2007static __inline item_p
2008ng_upgrade_write(node_p node, item_p item)
2009{
2010	struct ng_queue *ngq = &node->nd_input_queue;
2011	KASSERT(node != &ng_deadnode,
2012	    ("%s: working on deadnode", __func__));
2013
2014	NGI_SET_WRITER(item);
2015
2016	NG_QUEUE_LOCK(ngq);
2017
2018	/*
2019	 * There will never be no readers as we are there ourselves.
2020	 * Set the WRITER_ACTIVE flags ASAP to block out fast track readers.
2021	 * The caller we are running from will call ng_leave_read()
2022	 * soon, so we must account for that. We must leave again with the
2023	 * READER lock. If we find other readers, then
2024	 * queue the request for later. However "later" may be rignt now
2025	 * if there are no readers. We don't really care if there are queued
2026	 * items as we will bypass them anyhow.
2027	 */
2028	atomic_add_int(&ngq->q_flags, WRITER_ACTIVE - READER_INCREMENT);
2029	if ((ngq->q_flags & (NGQ_WMASK & ~OP_PENDING)) == WRITER_ACTIVE) {
2030		NG_QUEUE_UNLOCK(ngq);
2031
2032		/* It's just us, act on the item. */
2033		/* will NOT drop writer lock when done */
2034		ng_apply_item(node, item, 0);
2035
2036		/*
2037		 * Having acted on the item, atomically
2038		 * downgrade back to READER and finish up.
2039	 	 */
2040		atomic_add_int(&ngq->q_flags, READER_INCREMENT - WRITER_ACTIVE);
2041
2042		/* Our caller will call ng_leave_read() */
2043		return;
2044	}
2045	/*
2046	 * It's not just us active, so queue us AT THE HEAD.
2047	 * "Why?" I hear you ask.
2048	 * Put us at the head of the queue as we've already been
2049	 * through it once. If there is nothing else waiting,
2050	 * set the correct flags.
2051	 */
2052	if (STAILQ_EMPTY(&ngq->queue)) {
2053		/* We've gone from, 0 to 1 item in the queue */
2054		atomic_set_int(&ngq->q_flags, OP_PENDING);
2055
2056		CTR3(KTR_NET, "%20s: node [%x] (%p) set OP_PENDING", __func__,
2057		    node->nd_ID, node);
2058	};
2059	STAILQ_INSERT_HEAD(&ngq->queue, item, el_next);
2060	CTR4(KTR_NET, "%20s: node [%x] (%p) requeued item %p as WRITER",
2061	    __func__, node->nd_ID, node, item );
2062
2063	/* Reverse what we did above. That downgrades us back to reader */
2064	atomic_add_int(&ngq->q_flags, READER_INCREMENT - WRITER_ACTIVE);
2065	if (QUEUE_ACTIVE(ngq) && NEXT_QUEUED_ITEM_CAN_PROCEED(ngq))
2066		ng_worklist_add(node);
2067	NG_QUEUE_UNLOCK(ngq);
2068
2069	return;
2070}
2071#endif
2072
2073/* Release reader lock. */
2074static __inline void
2075ng_leave_read(node_p node)
2076{
2077	atomic_subtract_rel_int(&node->nd_input_queue.q_flags, READER_INCREMENT);
2078}
2079
2080/* Release writer lock. */
2081static __inline void
2082ng_leave_write(node_p node)
2083{
2084	atomic_clear_rel_int(&node->nd_input_queue.q_flags, WRITER_ACTIVE);
2085}
2086
2087/* Purge node queue. Called on node shutdown. */
2088static void
2089ng_flush_input_queue(node_p node)
2090{
2091	struct ng_queue *ngq = &node->nd_input_queue;
2092	item_p item;
2093
2094	NG_QUEUE_LOCK(ngq);
2095	while ((item = STAILQ_FIRST(&ngq->queue)) != NULL) {
2096		STAILQ_REMOVE_HEAD(&ngq->queue, el_next);
2097		if (STAILQ_EMPTY(&ngq->queue))
2098			atomic_clear_int(&ngq->q_flags, OP_PENDING);
2099		NG_QUEUE_UNLOCK(ngq);
2100
2101		/* If the item is supplying a callback, call it with an error */
2102		if (item->apply != NULL) {
2103			if (item->depth == 1)
2104				item->apply->error = ENOENT;
2105			if (refcount_release(&item->apply->refs)) {
2106				(*item->apply->apply)(item->apply->context,
2107				    item->apply->error);
2108			}
2109		}
2110		NG_FREE_ITEM(item);
2111		NG_QUEUE_LOCK(ngq);
2112	}
2113	NG_QUEUE_UNLOCK(ngq);
2114}
2115
2116/***********************************************************************
2117* Externally visible method for sending or queueing messages or data.
2118***********************************************************************/
2119
2120/*
2121 * The module code should have filled out the item correctly by this stage:
2122 * Common:
2123 *    reference to destination node.
2124 *    Reference to destination rcv hook if relevant.
2125 *    apply pointer must be or NULL or reference valid struct ng_apply_info.
2126 * Data:
2127 *    pointer to mbuf
2128 * Control_Message:
2129 *    pointer to msg.
2130 *    ID of original sender node. (return address)
2131 * Function:
2132 *    Function pointer
2133 *    void * argument
2134 *    integer argument
2135 *
2136 * The nodes have several routines and macros to help with this task:
2137 */
2138
2139int
2140ng_snd_item(item_p item, int flags)
2141{
2142	hook_p hook;
2143	node_p node;
2144	int queue, rw;
2145	struct ng_queue *ngq;
2146	int error = 0;
2147
2148	/* We are sending item, so it must be present! */
2149	KASSERT(item != NULL, ("ng_snd_item: item is NULL"));
2150
2151#ifdef	NETGRAPH_DEBUG
2152	_ngi_check(item, __FILE__, __LINE__);
2153#endif
2154
2155	/* Item was sent once more, postpone apply() call. */
2156	if (item->apply)
2157		refcount_acquire(&item->apply->refs);
2158
2159	node = NGI_NODE(item);
2160	/* Node is never optional. */
2161	KASSERT(node != NULL, ("ng_snd_item: node is NULL"));
2162
2163	hook = NGI_HOOK(item);
2164	/* Valid hook and mbuf are mandatory for data. */
2165	if ((item->el_flags & NGQF_TYPE) == NGQF_DATA) {
2166		KASSERT(hook != NULL, ("ng_snd_item: hook for data is NULL"));
2167		if (NGI_M(item) == NULL)
2168			ERROUT(EINVAL);
2169		CHECK_DATA_MBUF(NGI_M(item));
2170	}
2171
2172	/*
2173	 * If the item or the node specifies single threading, force
2174	 * writer semantics. Similarly, the node may say one hook always
2175	 * produces writers. These are overrides.
2176	 */
2177	if (((item->el_flags & NGQF_RW) == NGQF_WRITER) ||
2178	    (node->nd_flags & NGF_FORCE_WRITER) ||
2179	    (hook && (hook->hk_flags & HK_FORCE_WRITER))) {
2180		rw = NGQRW_W;
2181	} else {
2182		rw = NGQRW_R;
2183	}
2184
2185	/*
2186	 * If sender or receiver requests queued delivery, or call graph
2187	 * loops back from outbound to inbound path, or stack usage
2188	 * level is dangerous - enqueue message.
2189	 */
2190	if ((flags & NG_QUEUE) || (hook && (hook->hk_flags & HK_QUEUE))) {
2191		queue = 1;
2192	} else if (hook && (hook->hk_flags & HK_TO_INBOUND) &&
2193	    curthread->td_ng_outbound) {
2194		queue = 1;
2195	} else {
2196		queue = 0;
2197#ifdef GET_STACK_USAGE
2198		/*
2199		 * Most of netgraph nodes have small stack consumption and
2200		 * for them 25% of free stack space is more than enough.
2201		 * Nodes/hooks with higher stack usage should be marked as
2202		 * HI_STACK. For them 50% of stack will be guaranteed then.
2203		 * XXX: Values 25% and 50% are completely empirical.
2204		 */
2205		size_t	st, su, sl;
2206		GET_STACK_USAGE(st, su);
2207		sl = st - su;
2208		if ((sl * 4 < st) || ((sl * 2 < st) &&
2209		    ((node->nd_flags & NGF_HI_STACK) || (hook &&
2210		    (hook->hk_flags & HK_HI_STACK)))))
2211			queue = 1;
2212#endif
2213	}
2214
2215	if (queue) {
2216		item->depth = 1;
2217		/* Put it on the queue for that node*/
2218		ng_queue_rw(node, item, rw);
2219		return ((flags & NG_PROGRESS) ? EINPROGRESS : 0);
2220	}
2221
2222	/*
2223	 * We already decided how we will be queueud or treated.
2224	 * Try get the appropriate operating permission.
2225	 */
2226 	if (rw == NGQRW_R)
2227		item = ng_acquire_read(node, item);
2228	else
2229		item = ng_acquire_write(node, item);
2230
2231	/* Item was queued while trying to get permission. */
2232	if (item == NULL)
2233		return ((flags & NG_PROGRESS) ? EINPROGRESS : 0);
2234
2235	NGI_GET_NODE(item, node); /* zaps stored node */
2236
2237	item->depth++;
2238	error = ng_apply_item(node, item, rw); /* drops r/w lock when done */
2239
2240	/* If something is waiting on queue and ready, schedule it. */
2241	ngq = &node->nd_input_queue;
2242	if (QUEUE_ACTIVE(ngq)) {
2243		NG_QUEUE_LOCK(ngq);
2244		if (QUEUE_ACTIVE(ngq) && NEXT_QUEUED_ITEM_CAN_PROCEED(ngq))
2245			ng_worklist_add(node);
2246		NG_QUEUE_UNLOCK(ngq);
2247	}
2248
2249	/*
2250	 * Node may go away as soon as we remove the reference.
2251	 * Whatever we do, DO NOT access the node again!
2252	 */
2253	NG_NODE_UNREF(node);
2254
2255	return (error);
2256
2257done:
2258	/* If was not sent, apply callback here. */
2259	if (item->apply != NULL) {
2260		if (item->depth == 0 && error != 0)
2261			item->apply->error = error;
2262		if (refcount_release(&item->apply->refs)) {
2263			(*item->apply->apply)(item->apply->context,
2264			    item->apply->error);
2265		}
2266	}
2267
2268	NG_FREE_ITEM(item);
2269	return (error);
2270}
2271
2272/*
2273 * We have an item that was possibly queued somewhere.
2274 * It should contain all the information needed
2275 * to run it on the appropriate node/hook.
2276 * If there is apply pointer and we own the last reference, call apply().
2277 */
2278static int
2279ng_apply_item(node_p node, item_p item, int rw)
2280{
2281	hook_p  hook;
2282	ng_rcvdata_t *rcvdata;
2283	ng_rcvmsg_t *rcvmsg;
2284	struct ng_apply_info *apply;
2285	int	error = 0, depth;
2286
2287	/* Node and item are never optional. */
2288	KASSERT(node != NULL, ("ng_apply_item: node is NULL"));
2289	KASSERT(item != NULL, ("ng_apply_item: item is NULL"));
2290
2291	NGI_GET_HOOK(item, hook); /* clears stored hook */
2292#ifdef	NETGRAPH_DEBUG
2293	_ngi_check(item, __FILE__, __LINE__);
2294#endif
2295
2296	apply = item->apply;
2297	depth = item->depth;
2298
2299	switch (item->el_flags & NGQF_TYPE) {
2300	case NGQF_DATA:
2301		/*
2302		 * Check things are still ok as when we were queued.
2303		 */
2304		KASSERT(hook != NULL, ("ng_apply_item: hook for data is NULL"));
2305		if (NG_HOOK_NOT_VALID(hook) ||
2306		    NG_NODE_NOT_VALID(node)) {
2307			error = EIO;
2308			NG_FREE_ITEM(item);
2309			break;
2310		}
2311		/*
2312		 * If no receive method, just silently drop it.
2313		 * Give preference to the hook over-ride method.
2314		 */
2315		if ((!(rcvdata = hook->hk_rcvdata)) &&
2316		    (!(rcvdata = NG_HOOK_NODE(hook)->nd_type->rcvdata))) {
2317			error = 0;
2318			NG_FREE_ITEM(item);
2319			break;
2320		}
2321		error = (*rcvdata)(hook, item);
2322		break;
2323	case NGQF_MESG:
2324		if (hook && NG_HOOK_NOT_VALID(hook)) {
2325			/*
2326			 * The hook has been zapped then we can't use it.
2327			 * Immediately drop its reference.
2328			 * The message may not need it.
2329			 */
2330			NG_HOOK_UNREF(hook);
2331			hook = NULL;
2332		}
2333		/*
2334		 * Similarly, if the node is a zombie there is
2335		 * nothing we can do with it, drop everything.
2336		 */
2337		if (NG_NODE_NOT_VALID(node)) {
2338			TRAP_ERROR();
2339			error = EINVAL;
2340			NG_FREE_ITEM(item);
2341			break;
2342		}
2343		/*
2344		 * Call the appropriate message handler for the object.
2345		 * It is up to the message handler to free the message.
2346		 * If it's a generic message, handle it generically,
2347		 * otherwise call the type's message handler (if it exists).
2348		 * XXX (race). Remember that a queued message may
2349		 * reference a node or hook that has just been
2350		 * invalidated. It will exist as the queue code
2351		 * is holding a reference, but..
2352		 */
2353		if ((NGI_MSG(item)->header.typecookie == NGM_GENERIC_COOKIE) &&
2354		    ((NGI_MSG(item)->header.flags & NGF_RESP) == 0)) {
2355			error = ng_generic_msg(node, item, hook);
2356			break;
2357		}
2358		if (((!hook) || (!(rcvmsg = hook->hk_rcvmsg))) &&
2359		    (!(rcvmsg = node->nd_type->rcvmsg))) {
2360			TRAP_ERROR();
2361			error = 0;
2362			NG_FREE_ITEM(item);
2363			break;
2364		}
2365		error = (*rcvmsg)(node, item, hook);
2366		break;
2367	case NGQF_FN:
2368	case NGQF_FN2:
2369		/*
2370		 * In the case of the shutdown message we allow it to hit
2371		 * even if the node is invalid.
2372		 */
2373		if (NG_NODE_NOT_VALID(node) &&
2374		    NGI_FN(item) != &ng_rmnode) {
2375			TRAP_ERROR();
2376			error = EINVAL;
2377			NG_FREE_ITEM(item);
2378			break;
2379		}
2380		/* Same is about some internal functions and invalid hook. */
2381		if (hook && NG_HOOK_NOT_VALID(hook) &&
2382		    NGI_FN2(item) != &ng_con_part2 &&
2383		    NGI_FN2(item) != &ng_con_part3 &&
2384		    NGI_FN(item) != &ng_rmhook_part2) {
2385			TRAP_ERROR();
2386			error = EINVAL;
2387			NG_FREE_ITEM(item);
2388			break;
2389		}
2390
2391		if ((item->el_flags & NGQF_TYPE) == NGQF_FN) {
2392			(*NGI_FN(item))(node, hook, NGI_ARG1(item),
2393			    NGI_ARG2(item));
2394			NG_FREE_ITEM(item);
2395		} else	/* it is NGQF_FN2 */
2396			error = (*NGI_FN2(item))(node, item, hook);
2397		break;
2398	}
2399	/*
2400	 * We held references on some of the resources
2401	 * that we took from the item. Now that we have
2402	 * finished doing everything, drop those references.
2403	 */
2404	if (hook)
2405		NG_HOOK_UNREF(hook);
2406
2407 	if (rw == NGQRW_R)
2408		ng_leave_read(node);
2409	else
2410		ng_leave_write(node);
2411
2412	/* Apply callback. */
2413	if (apply != NULL) {
2414		if (depth == 1 && error != 0)
2415			apply->error = error;
2416		if (refcount_release(&apply->refs))
2417			(*apply->apply)(apply->context, apply->error);
2418	}
2419
2420	return (error);
2421}
2422
2423/***********************************************************************
2424 * Implement the 'generic' control messages
2425 ***********************************************************************/
2426static int
2427ng_generic_msg(node_p here, item_p item, hook_p lasthook)
2428{
2429	int error = 0;
2430	struct ng_mesg *msg;
2431	struct ng_mesg *resp = NULL;
2432
2433	NGI_GET_MSG(item, msg);
2434	if (msg->header.typecookie != NGM_GENERIC_COOKIE) {
2435		TRAP_ERROR();
2436		error = EINVAL;
2437		goto out;
2438	}
2439	switch (msg->header.cmd) {
2440	case NGM_SHUTDOWN:
2441		ng_rmnode(here, NULL, NULL, 0);
2442		break;
2443	case NGM_MKPEER:
2444	    {
2445		struct ngm_mkpeer *const mkp = (struct ngm_mkpeer *) msg->data;
2446
2447		if (msg->header.arglen != sizeof(*mkp)) {
2448			TRAP_ERROR();
2449			error = EINVAL;
2450			break;
2451		}
2452		mkp->type[sizeof(mkp->type) - 1] = '\0';
2453		mkp->ourhook[sizeof(mkp->ourhook) - 1] = '\0';
2454		mkp->peerhook[sizeof(mkp->peerhook) - 1] = '\0';
2455		error = ng_mkpeer(here, mkp->ourhook, mkp->peerhook, mkp->type);
2456		break;
2457	    }
2458	case NGM_CONNECT:
2459	    {
2460		struct ngm_connect *const con =
2461			(struct ngm_connect *) msg->data;
2462		node_p node2;
2463
2464		if (msg->header.arglen != sizeof(*con)) {
2465			TRAP_ERROR();
2466			error = EINVAL;
2467			break;
2468		}
2469		con->path[sizeof(con->path) - 1] = '\0';
2470		con->ourhook[sizeof(con->ourhook) - 1] = '\0';
2471		con->peerhook[sizeof(con->peerhook) - 1] = '\0';
2472		/* Don't forget we get a reference.. */
2473		error = ng_path2noderef(here, con->path, &node2, NULL);
2474		if (error)
2475			break;
2476		error = ng_con_nodes(item, here, con->ourhook,
2477		    node2, con->peerhook);
2478		NG_NODE_UNREF(node2);
2479		break;
2480	    }
2481	case NGM_NAME:
2482	    {
2483		struct ngm_name *const nam = (struct ngm_name *) msg->data;
2484
2485		if (msg->header.arglen != sizeof(*nam)) {
2486			TRAP_ERROR();
2487			error = EINVAL;
2488			break;
2489		}
2490		nam->name[sizeof(nam->name) - 1] = '\0';
2491		error = ng_name_node(here, nam->name);
2492		break;
2493	    }
2494	case NGM_RMHOOK:
2495	    {
2496		struct ngm_rmhook *const rmh = (struct ngm_rmhook *) msg->data;
2497		hook_p hook;
2498
2499		if (msg->header.arglen != sizeof(*rmh)) {
2500			TRAP_ERROR();
2501			error = EINVAL;
2502			break;
2503		}
2504		rmh->ourhook[sizeof(rmh->ourhook) - 1] = '\0';
2505		if ((hook = ng_findhook(here, rmh->ourhook)) != NULL)
2506			ng_destroy_hook(hook);
2507		break;
2508	    }
2509	case NGM_NODEINFO:
2510	    {
2511		struct nodeinfo *ni;
2512
2513		NG_MKRESPONSE(resp, msg, sizeof(*ni), M_NOWAIT);
2514		if (resp == NULL) {
2515			error = ENOMEM;
2516			break;
2517		}
2518
2519		/* Fill in node info */
2520		ni = (struct nodeinfo *) resp->data;
2521		if (NG_NODE_HAS_NAME(here))
2522			strcpy(ni->name, NG_NODE_NAME(here));
2523		strcpy(ni->type, here->nd_type->name);
2524		ni->id = ng_node2ID(here);
2525		ni->hooks = here->nd_numhooks;
2526		break;
2527	    }
2528	case NGM_LISTHOOKS:
2529	    {
2530		const int nhooks = here->nd_numhooks;
2531		struct hooklist *hl;
2532		struct nodeinfo *ni;
2533		hook_p hook;
2534
2535		/* Get response struct */
2536		NG_MKRESPONSE(resp, msg, sizeof(*hl) +
2537		    (nhooks * sizeof(struct linkinfo)), M_NOWAIT);
2538		if (resp == NULL) {
2539			error = ENOMEM;
2540			break;
2541		}
2542		hl = (struct hooklist *) resp->data;
2543		ni = &hl->nodeinfo;
2544
2545		/* Fill in node info */
2546		if (NG_NODE_HAS_NAME(here))
2547			strcpy(ni->name, NG_NODE_NAME(here));
2548		strcpy(ni->type, here->nd_type->name);
2549		ni->id = ng_node2ID(here);
2550
2551		/* Cycle through the linked list of hooks */
2552		ni->hooks = 0;
2553		LIST_FOREACH(hook, &here->nd_hooks, hk_hooks) {
2554			struct linkinfo *const link = &hl->link[ni->hooks];
2555
2556			if (ni->hooks >= nhooks) {
2557				log(LOG_ERR, "%s: number of %s changed\n",
2558				    __func__, "hooks");
2559				break;
2560			}
2561			if (NG_HOOK_NOT_VALID(hook))
2562				continue;
2563			strcpy(link->ourhook, NG_HOOK_NAME(hook));
2564			strcpy(link->peerhook, NG_PEER_HOOK_NAME(hook));
2565			if (NG_PEER_NODE_NAME(hook)[0] != '\0')
2566				strcpy(link->nodeinfo.name,
2567				    NG_PEER_NODE_NAME(hook));
2568			strcpy(link->nodeinfo.type,
2569			   NG_PEER_NODE(hook)->nd_type->name);
2570			link->nodeinfo.id = ng_node2ID(NG_PEER_NODE(hook));
2571			link->nodeinfo.hooks = NG_PEER_NODE(hook)->nd_numhooks;
2572			ni->hooks++;
2573		}
2574		break;
2575	    }
2576
2577	case NGM_LISTNAMES:
2578	case NGM_LISTNODES:
2579	    {
2580		const int unnamed = (msg->header.cmd == NGM_LISTNODES);
2581		struct namelist *nl;
2582		node_p node;
2583		int num = 0, i;
2584
2585		NAMEHASH_RLOCK();
2586		/* Count number of nodes */
2587		for (i = 0; i < NG_NAME_HASH_SIZE; i++) {
2588			LIST_FOREACH(node, &V_ng_name_hash[i], nd_nodes) {
2589				if (NG_NODE_IS_VALID(node) &&
2590				    (unnamed || NG_NODE_HAS_NAME(node))) {
2591					num++;
2592				}
2593			}
2594		}
2595
2596		/* Get response struct */
2597		NG_MKRESPONSE(resp, msg, sizeof(*nl) +
2598		    (num * sizeof(struct nodeinfo)), M_NOWAIT);
2599		if (resp == NULL) {
2600			NAMEHASH_RUNLOCK();
2601			error = ENOMEM;
2602			break;
2603		}
2604		nl = (struct namelist *) resp->data;
2605
2606		/* Cycle through the linked list of nodes */
2607		nl->numnames = 0;
2608		for (i = 0; i < NG_NAME_HASH_SIZE; i++) {
2609			LIST_FOREACH(node, &V_ng_name_hash[i], nd_nodes) {
2610				struct nodeinfo *const np =
2611				    &nl->nodeinfo[nl->numnames];
2612
2613				if (NG_NODE_NOT_VALID(node))
2614					continue;
2615				if (!unnamed && (! NG_NODE_HAS_NAME(node)))
2616					continue;
2617				if (NG_NODE_HAS_NAME(node))
2618					strcpy(np->name, NG_NODE_NAME(node));
2619				strcpy(np->type, node->nd_type->name);
2620				np->id = ng_node2ID(node);
2621				np->hooks = node->nd_numhooks;
2622				KASSERT(nl->numnames < num, ("%s: no space",
2623				    __func__));
2624				nl->numnames++;
2625			}
2626		}
2627		NAMEHASH_RUNLOCK();
2628		break;
2629	    }
2630
2631	case NGM_LISTTYPES:
2632	    {
2633		struct typelist *tl;
2634		struct ng_type *type;
2635		int num = 0;
2636
2637		TYPELIST_RLOCK();
2638		/* Count number of types */
2639		LIST_FOREACH(type, &ng_typelist, types)
2640			num++;
2641
2642		/* Get response struct */
2643		NG_MKRESPONSE(resp, msg, sizeof(*tl) +
2644		    (num * sizeof(struct typeinfo)), M_NOWAIT);
2645		if (resp == NULL) {
2646			TYPELIST_RUNLOCK();
2647			error = ENOMEM;
2648			break;
2649		}
2650		tl = (struct typelist *) resp->data;
2651
2652		/* Cycle through the linked list of types */
2653		tl->numtypes = 0;
2654		LIST_FOREACH(type, &ng_typelist, types) {
2655			struct typeinfo *const tp = &tl->typeinfo[tl->numtypes];
2656
2657			strcpy(tp->type_name, type->name);
2658			tp->numnodes = type->refs - 1; /* don't count list */
2659			KASSERT(tl->numtypes < num, ("%s: no space", __func__));
2660			tl->numtypes++;
2661		}
2662		TYPELIST_RUNLOCK();
2663		break;
2664	    }
2665
2666	case NGM_BINARY2ASCII:
2667	    {
2668		int bufSize = 20 * 1024;	/* XXX hard coded constant */
2669		const struct ng_parse_type *argstype;
2670		const struct ng_cmdlist *c;
2671		struct ng_mesg *binary, *ascii;
2672
2673		/* Data area must contain a valid netgraph message */
2674		binary = (struct ng_mesg *)msg->data;
2675		if (msg->header.arglen < sizeof(struct ng_mesg) ||
2676		    (msg->header.arglen - sizeof(struct ng_mesg) <
2677		    binary->header.arglen)) {
2678			TRAP_ERROR();
2679			error = EINVAL;
2680			break;
2681		}
2682
2683		/* Get a response message with lots of room */
2684		NG_MKRESPONSE(resp, msg, sizeof(*ascii) + bufSize, M_NOWAIT);
2685		if (resp == NULL) {
2686			error = ENOMEM;
2687			break;
2688		}
2689		ascii = (struct ng_mesg *)resp->data;
2690
2691		/* Copy binary message header to response message payload */
2692		bcopy(binary, ascii, sizeof(*binary));
2693
2694		/* Find command by matching typecookie and command number */
2695		for (c = here->nd_type->cmdlist; c != NULL && c->name != NULL;
2696		    c++) {
2697			if (binary->header.typecookie == c->cookie &&
2698			    binary->header.cmd == c->cmd)
2699				break;
2700		}
2701		if (c == NULL || c->name == NULL) {
2702			for (c = ng_generic_cmds; c->name != NULL; c++) {
2703				if (binary->header.typecookie == c->cookie &&
2704				    binary->header.cmd == c->cmd)
2705					break;
2706			}
2707			if (c->name == NULL) {
2708				NG_FREE_MSG(resp);
2709				error = ENOSYS;
2710				break;
2711			}
2712		}
2713
2714		/* Convert command name to ASCII */
2715		snprintf(ascii->header.cmdstr, sizeof(ascii->header.cmdstr),
2716		    "%s", c->name);
2717
2718		/* Convert command arguments to ASCII */
2719		argstype = (binary->header.flags & NGF_RESP) ?
2720		    c->respType : c->mesgType;
2721		if (argstype == NULL) {
2722			*ascii->data = '\0';
2723		} else {
2724			if ((error = ng_unparse(argstype,
2725			    (u_char *)binary->data,
2726			    ascii->data, bufSize)) != 0) {
2727				NG_FREE_MSG(resp);
2728				break;
2729			}
2730		}
2731
2732		/* Return the result as struct ng_mesg plus ASCII string */
2733		bufSize = strlen(ascii->data) + 1;
2734		ascii->header.arglen = bufSize;
2735		resp->header.arglen = sizeof(*ascii) + bufSize;
2736		break;
2737	    }
2738
2739	case NGM_ASCII2BINARY:
2740	    {
2741		int bufSize = 20 * 1024;	/* XXX hard coded constant */
2742		const struct ng_cmdlist *c;
2743		const struct ng_parse_type *argstype;
2744		struct ng_mesg *ascii, *binary;
2745		int off = 0;
2746
2747		/* Data area must contain at least a struct ng_mesg + '\0' */
2748		ascii = (struct ng_mesg *)msg->data;
2749		if ((msg->header.arglen < sizeof(*ascii) + 1) ||
2750		    (ascii->header.arglen < 1) ||
2751		    (msg->header.arglen < sizeof(*ascii) +
2752		    ascii->header.arglen)) {
2753			TRAP_ERROR();
2754			error = EINVAL;
2755			break;
2756		}
2757		ascii->data[ascii->header.arglen - 1] = '\0';
2758
2759		/* Get a response message with lots of room */
2760		NG_MKRESPONSE(resp, msg, sizeof(*binary) + bufSize, M_NOWAIT);
2761		if (resp == NULL) {
2762			error = ENOMEM;
2763			break;
2764		}
2765		binary = (struct ng_mesg *)resp->data;
2766
2767		/* Copy ASCII message header to response message payload */
2768		bcopy(ascii, binary, sizeof(*ascii));
2769
2770		/* Find command by matching ASCII command string */
2771		for (c = here->nd_type->cmdlist;
2772		    c != NULL && c->name != NULL; c++) {
2773			if (strcmp(ascii->header.cmdstr, c->name) == 0)
2774				break;
2775		}
2776		if (c == NULL || c->name == NULL) {
2777			for (c = ng_generic_cmds; c->name != NULL; c++) {
2778				if (strcmp(ascii->header.cmdstr, c->name) == 0)
2779					break;
2780			}
2781			if (c->name == NULL) {
2782				NG_FREE_MSG(resp);
2783				error = ENOSYS;
2784				break;
2785			}
2786		}
2787
2788		/* Convert command name to binary */
2789		binary->header.cmd = c->cmd;
2790		binary->header.typecookie = c->cookie;
2791
2792		/* Convert command arguments to binary */
2793		argstype = (binary->header.flags & NGF_RESP) ?
2794		    c->respType : c->mesgType;
2795		if (argstype == NULL) {
2796			bufSize = 0;
2797		} else {
2798			if ((error = ng_parse(argstype, ascii->data, &off,
2799			    (u_char *)binary->data, &bufSize)) != 0) {
2800				NG_FREE_MSG(resp);
2801				break;
2802			}
2803		}
2804
2805		/* Return the result */
2806		binary->header.arglen = bufSize;
2807		resp->header.arglen = sizeof(*binary) + bufSize;
2808		break;
2809	    }
2810
2811	case NGM_TEXT_CONFIG:
2812	case NGM_TEXT_STATUS:
2813		/*
2814		 * This one is tricky as it passes the command down to the
2815		 * actual node, even though it is a generic type command.
2816		 * This means we must assume that the item/msg is already freed
2817		 * when control passes back to us.
2818		 */
2819		if (here->nd_type->rcvmsg != NULL) {
2820			NGI_MSG(item) = msg; /* put it back as we found it */
2821			return((*here->nd_type->rcvmsg)(here, item, lasthook));
2822		}
2823		/* Fall through if rcvmsg not supported */
2824	default:
2825		TRAP_ERROR();
2826		error = EINVAL;
2827	}
2828	/*
2829	 * Sometimes a generic message may be statically allocated
2830	 * to avoid problems with allocating when in tight memory situations.
2831	 * Don't free it if it is so.
2832	 * I break them appart here, because erros may cause a free if the item
2833	 * in which case we'd be doing it twice.
2834	 * they are kept together above, to simplify freeing.
2835	 */
2836out:
2837	NG_RESPOND_MSG(error, here, item, resp);
2838	NG_FREE_MSG(msg);
2839	return (error);
2840}
2841
2842/************************************************************************
2843			Queue element get/free routines
2844************************************************************************/
2845
2846uma_zone_t			ng_qzone;
2847uma_zone_t			ng_qdzone;
2848static int			numthreads = 0; /* number of queue threads */
2849static int			maxalloc = 4096;/* limit the damage of a leak */
2850static int			maxdata = 512;	/* limit the damage of a DoS */
2851
2852TUNABLE_INT("net.graph.threads", &numthreads);
2853SYSCTL_INT(_net_graph, OID_AUTO, threads, CTLFLAG_RDTUN, &numthreads,
2854    0, "Number of queue processing threads");
2855TUNABLE_INT("net.graph.maxalloc", &maxalloc);
2856SYSCTL_INT(_net_graph, OID_AUTO, maxalloc, CTLFLAG_RDTUN, &maxalloc,
2857    0, "Maximum number of non-data queue items to allocate");
2858TUNABLE_INT("net.graph.maxdata", &maxdata);
2859SYSCTL_INT(_net_graph, OID_AUTO, maxdata, CTLFLAG_RDTUN, &maxdata,
2860    0, "Maximum number of data queue items to allocate");
2861
2862#ifdef	NETGRAPH_DEBUG
2863static TAILQ_HEAD(, ng_item) ng_itemlist = TAILQ_HEAD_INITIALIZER(ng_itemlist);
2864static int allocated;	/* number of items malloc'd */
2865#endif
2866
2867/*
2868 * Get a queue entry.
2869 * This is usually called when a packet first enters netgraph.
2870 * By definition, this is usually from an interrupt, or from a user.
2871 * Users are not so important, but try be quick for the times that it's
2872 * an interrupt.
2873 */
2874static __inline item_p
2875ng_alloc_item(int type, int flags)
2876{
2877	item_p item;
2878
2879	KASSERT(((type & ~NGQF_TYPE) == 0),
2880	    ("%s: incorrect item type: %d", __func__, type));
2881
2882	item = uma_zalloc((type == NGQF_DATA) ? ng_qdzone : ng_qzone,
2883	    ((flags & NG_WAITOK) ? M_WAITOK : M_NOWAIT) | M_ZERO);
2884
2885	if (item) {
2886		item->el_flags = type;
2887#ifdef	NETGRAPH_DEBUG
2888		mtx_lock(&ngq_mtx);
2889		TAILQ_INSERT_TAIL(&ng_itemlist, item, all);
2890		allocated++;
2891		mtx_unlock(&ngq_mtx);
2892#endif
2893	}
2894
2895	return (item);
2896}
2897
2898/*
2899 * Release a queue entry
2900 */
2901void
2902ng_free_item(item_p item)
2903{
2904	/*
2905	 * The item may hold resources on it's own. We need to free
2906	 * these before we can free the item. What they are depends upon
2907	 * what kind of item it is. it is important that nodes zero
2908	 * out pointers to resources that they remove from the item
2909	 * or we release them again here.
2910	 */
2911	switch (item->el_flags & NGQF_TYPE) {
2912	case NGQF_DATA:
2913		/* If we have an mbuf still attached.. */
2914		NG_FREE_M(_NGI_M(item));
2915		break;
2916	case NGQF_MESG:
2917		_NGI_RETADDR(item) = 0;
2918		NG_FREE_MSG(_NGI_MSG(item));
2919		break;
2920	case NGQF_FN:
2921	case NGQF_FN2:
2922		/* nothing to free really, */
2923		_NGI_FN(item) = NULL;
2924		_NGI_ARG1(item) = NULL;
2925		_NGI_ARG2(item) = 0;
2926		break;
2927	}
2928	/* If we still have a node or hook referenced... */
2929	_NGI_CLR_NODE(item);
2930	_NGI_CLR_HOOK(item);
2931
2932#ifdef	NETGRAPH_DEBUG
2933	mtx_lock(&ngq_mtx);
2934	TAILQ_REMOVE(&ng_itemlist, item, all);
2935	allocated--;
2936	mtx_unlock(&ngq_mtx);
2937#endif
2938	uma_zfree(((item->el_flags & NGQF_TYPE) == NGQF_DATA) ?
2939	    ng_qdzone : ng_qzone, item);
2940}
2941
2942/*
2943 * Change type of the queue entry.
2944 * Possibly reallocates it from another UMA zone.
2945 */
2946static __inline item_p
2947ng_realloc_item(item_p pitem, int type, int flags)
2948{
2949	item_p item;
2950	int from, to;
2951
2952	KASSERT((pitem != NULL), ("%s: can't reallocate NULL", __func__));
2953	KASSERT(((type & ~NGQF_TYPE) == 0),
2954	    ("%s: incorrect item type: %d", __func__, type));
2955
2956	from = ((pitem->el_flags & NGQF_TYPE) == NGQF_DATA);
2957	to = (type == NGQF_DATA);
2958	if (from != to) {
2959		/* If reallocation is required do it and copy item. */
2960		if ((item = ng_alloc_item(type, flags)) == NULL) {
2961			ng_free_item(pitem);
2962			return (NULL);
2963		}
2964		*item = *pitem;
2965		ng_free_item(pitem);
2966	} else
2967		item = pitem;
2968	item->el_flags = (item->el_flags & ~NGQF_TYPE) | type;
2969
2970	return (item);
2971}
2972
2973/************************************************************************
2974			Module routines
2975************************************************************************/
2976
2977/*
2978 * Handle the loading/unloading of a netgraph node type module
2979 */
2980int
2981ng_mod_event(module_t mod, int event, void *data)
2982{
2983	struct ng_type *const type = data;
2984	int error = 0;
2985
2986	switch (event) {
2987	case MOD_LOAD:
2988
2989		/* Register new netgraph node type */
2990		if ((error = ng_newtype(type)) != 0)
2991			break;
2992
2993		/* Call type specific code */
2994		if (type->mod_event != NULL)
2995			if ((error = (*type->mod_event)(mod, event, data))) {
2996				TYPELIST_WLOCK();
2997				type->refs--;	/* undo it */
2998				LIST_REMOVE(type, types);
2999				TYPELIST_WUNLOCK();
3000			}
3001		break;
3002
3003	case MOD_UNLOAD:
3004		if (type->refs > 1) {		/* make sure no nodes exist! */
3005			error = EBUSY;
3006		} else {
3007			if (type->refs == 0) /* failed load, nothing to undo */
3008				break;
3009			if (type->mod_event != NULL) {	/* check with type */
3010				error = (*type->mod_event)(mod, event, data);
3011				if (error != 0)	/* type refuses.. */
3012					break;
3013			}
3014			TYPELIST_WLOCK();
3015			LIST_REMOVE(type, types);
3016			TYPELIST_WUNLOCK();
3017		}
3018		break;
3019
3020	default:
3021		if (type->mod_event != NULL)
3022			error = (*type->mod_event)(mod, event, data);
3023		else
3024			error = EOPNOTSUPP;		/* XXX ? */
3025		break;
3026	}
3027	return (error);
3028}
3029
3030#ifdef VIMAGE
3031static void
3032vnet_netgraph_uninit(const void *unused __unused)
3033{
3034	node_p node = NULL, last_killed = NULL;
3035	int i;
3036
3037	do {
3038		/* Find a node to kill */
3039		NAMEHASH_RLOCK();
3040		for (i = 0; i < NG_NAME_HASH_SIZE; i++) {
3041			LIST_FOREACH(node, &V_ng_name_hash[i], nd_nodes) {
3042				if (node != &ng_deadnode) {
3043					NG_NODE_REF(node);
3044					break;
3045				}
3046			}
3047			if (node != NULL)
3048				break;
3049		}
3050		NAMEHASH_RUNLOCK();
3051
3052		/* Attempt to kill it only if it is a regular node */
3053		if (node != NULL) {
3054			if (node == last_killed) {
3055				/* This should never happen */
3056				printf("ng node %s needs NGF_REALLY_DIE\n",
3057				    node->nd_name);
3058				if (node->nd_flags & NGF_REALLY_DIE)
3059					panic("ng node %s won't die",
3060					    node->nd_name);
3061				node->nd_flags |= NGF_REALLY_DIE;
3062			}
3063			ng_rmnode(node, NULL, NULL, 0);
3064			NG_NODE_UNREF(node);
3065			last_killed = node;
3066		}
3067	} while (node != NULL);
3068}
3069VNET_SYSUNINIT(vnet_netgraph_uninit, SI_SUB_NETGRAPH, SI_ORDER_FIRST,
3070    vnet_netgraph_uninit, NULL);
3071#endif /* VIMAGE */
3072
3073/*
3074 * Handle loading and unloading for this code.
3075 * The only thing we need to link into is the NETISR strucure.
3076 */
3077static int
3078ngb_mod_event(module_t mod, int event, void *data)
3079{
3080	struct proc *p;
3081	struct thread *td;
3082	int i, error = 0;
3083
3084	switch (event) {
3085	case MOD_LOAD:
3086		/* Initialize everything. */
3087		NG_WORKLIST_LOCK_INIT();
3088		rw_init(&ng_typelist_lock, "netgraph types");
3089		rw_init(&ng_idhash_lock, "netgraph idhash");
3090		rw_init(&ng_namehash_lock, "netgraph namehash");
3091		mtx_init(&ng_topo_mtx, "netgraph topology mutex", NULL,
3092		    MTX_DEF);
3093#ifdef	NETGRAPH_DEBUG
3094		mtx_init(&ng_nodelist_mtx, "netgraph nodelist mutex", NULL,
3095		    MTX_DEF);
3096		mtx_init(&ngq_mtx, "netgraph item list mutex", NULL,
3097		    MTX_DEF);
3098#endif
3099		ng_qzone = uma_zcreate("NetGraph items", sizeof(struct ng_item),
3100		    NULL, NULL, NULL, NULL, UMA_ALIGN_CACHE, M_WAITOK);
3101		uma_zone_set_max(ng_qzone, maxalloc);
3102		ng_qdzone = uma_zcreate("NetGraph data items",
3103		    sizeof(struct ng_item), NULL, NULL, NULL, NULL,
3104		    UMA_ALIGN_CACHE, M_WAITOK);
3105		uma_zone_set_max(ng_qdzone, maxdata);
3106		/* Autoconfigure number of threads. */
3107		if (numthreads <= 0)
3108			numthreads = mp_ncpus;
3109		/* Create threads. */
3110    		p = NULL; /* start with no process */
3111		for (i = 0; i < numthreads; i++) {
3112			if (kproc_kthread_add(ngthread, NULL, &p, &td,
3113			    RFHIGHPID, 0, "ng_queue", "ng_queue%d", i)) {
3114				numthreads = i;
3115				break;
3116			}
3117		}
3118		break;
3119	case MOD_UNLOAD:
3120		/* You can't unload it because an interface may be using it. */
3121		error = EBUSY;
3122		break;
3123	default:
3124		error = EOPNOTSUPP;
3125		break;
3126	}
3127	return (error);
3128}
3129
3130static moduledata_t netgraph_mod = {
3131	"netgraph",
3132	ngb_mod_event,
3133	(NULL)
3134};
3135DECLARE_MODULE(netgraph, netgraph_mod, SI_SUB_NETGRAPH, SI_ORDER_FIRST);
3136SYSCTL_NODE(_net, OID_AUTO, graph, CTLFLAG_RW, 0, "netgraph Family");
3137SYSCTL_INT(_net_graph, OID_AUTO, abi_version, CTLFLAG_RD, 0, NG_ABI_VERSION,"");
3138SYSCTL_INT(_net_graph, OID_AUTO, msg_version, CTLFLAG_RD, 0, NG_VERSION, "");
3139
3140#ifdef	NETGRAPH_DEBUG
3141void
3142dumphook (hook_p hook, char *file, int line)
3143{
3144	printf("hook: name %s, %d refs, Last touched:\n",
3145		_NG_HOOK_NAME(hook), hook->hk_refs);
3146	printf("	Last active @ %s, line %d\n",
3147		hook->lastfile, hook->lastline);
3148	if (line) {
3149		printf(" problem discovered at file %s, line %d\n", file, line);
3150#ifdef KDB
3151		kdb_backtrace();
3152#endif
3153	}
3154}
3155
3156void
3157dumpnode(node_p node, char *file, int line)
3158{
3159	printf("node: ID [%x]: type '%s', %d hooks, flags 0x%x, %d refs, %s:\n",
3160		_NG_NODE_ID(node), node->nd_type->name,
3161		node->nd_numhooks, node->nd_flags,
3162		node->nd_refs, node->nd_name);
3163	printf("	Last active @ %s, line %d\n",
3164		node->lastfile, node->lastline);
3165	if (line) {
3166		printf(" problem discovered at file %s, line %d\n", file, line);
3167#ifdef KDB
3168		kdb_backtrace();
3169#endif
3170	}
3171}
3172
3173void
3174dumpitem(item_p item, char *file, int line)
3175{
3176	printf(" ACTIVE item, last used at %s, line %d",
3177		item->lastfile, item->lastline);
3178	switch(item->el_flags & NGQF_TYPE) {
3179	case NGQF_DATA:
3180		printf(" - [data]\n");
3181		break;
3182	case NGQF_MESG:
3183		printf(" - retaddr[%d]:\n", _NGI_RETADDR(item));
3184		break;
3185	case NGQF_FN:
3186		printf(" - fn@%p (%p, %p, %p, %d (%x))\n",
3187			_NGI_FN(item),
3188			_NGI_NODE(item),
3189			_NGI_HOOK(item),
3190			item->body.fn.fn_arg1,
3191			item->body.fn.fn_arg2,
3192			item->body.fn.fn_arg2);
3193		break;
3194	case NGQF_FN2:
3195		printf(" - fn2@%p (%p, %p, %p, %d (%x))\n",
3196			_NGI_FN2(item),
3197			_NGI_NODE(item),
3198			_NGI_HOOK(item),
3199			item->body.fn.fn_arg1,
3200			item->body.fn.fn_arg2,
3201			item->body.fn.fn_arg2);
3202		break;
3203	}
3204	if (line) {
3205		printf(" problem discovered at file %s, line %d\n", file, line);
3206		if (_NGI_NODE(item)) {
3207			printf("node %p ([%x])\n",
3208				_NGI_NODE(item), ng_node2ID(_NGI_NODE(item)));
3209		}
3210	}
3211}
3212
3213static void
3214ng_dumpitems(void)
3215{
3216	item_p item;
3217	int i = 1;
3218	TAILQ_FOREACH(item, &ng_itemlist, all) {
3219		printf("[%d] ", i++);
3220		dumpitem(item, NULL, 0);
3221	}
3222}
3223
3224static void
3225ng_dumpnodes(void)
3226{
3227	node_p node;
3228	int i = 1;
3229	mtx_lock(&ng_nodelist_mtx);
3230	SLIST_FOREACH(node, &ng_allnodes, nd_all) {
3231		printf("[%d] ", i++);
3232		dumpnode(node, NULL, 0);
3233	}
3234	mtx_unlock(&ng_nodelist_mtx);
3235}
3236
3237static void
3238ng_dumphooks(void)
3239{
3240	hook_p hook;
3241	int i = 1;
3242	mtx_lock(&ng_nodelist_mtx);
3243	SLIST_FOREACH(hook, &ng_allhooks, hk_all) {
3244		printf("[%d] ", i++);
3245		dumphook(hook, NULL, 0);
3246	}
3247	mtx_unlock(&ng_nodelist_mtx);
3248}
3249
3250static int
3251sysctl_debug_ng_dump_items(SYSCTL_HANDLER_ARGS)
3252{
3253	int error;
3254	int val;
3255	int i;
3256
3257	val = allocated;
3258	i = 1;
3259	error = sysctl_handle_int(oidp, &val, 0, req);
3260	if (error != 0 || req->newptr == NULL)
3261		return (error);
3262	if (val == 42) {
3263		ng_dumpitems();
3264		ng_dumpnodes();
3265		ng_dumphooks();
3266	}
3267	return (0);
3268}
3269
3270SYSCTL_PROC(_debug, OID_AUTO, ng_dump_items, CTLTYPE_INT | CTLFLAG_RW,
3271    0, sizeof(int), sysctl_debug_ng_dump_items, "I", "Number of allocated items");
3272#endif	/* NETGRAPH_DEBUG */
3273
3274/***********************************************************************
3275* Worklist routines
3276**********************************************************************/
3277/*
3278 * Pick a node off the list of nodes with work,
3279 * try get an item to process off it. Remove the node from the list.
3280 */
3281static void
3282ngthread(void *arg)
3283{
3284	for (;;) {
3285		node_p  node;
3286
3287		/* Get node from the worklist. */
3288		NG_WORKLIST_LOCK();
3289		while ((node = STAILQ_FIRST(&ng_worklist)) == NULL)
3290			NG_WORKLIST_SLEEP();
3291		STAILQ_REMOVE_HEAD(&ng_worklist, nd_input_queue.q_work);
3292		NG_WORKLIST_UNLOCK();
3293		CURVNET_SET(node->nd_vnet);
3294		CTR3(KTR_NET, "%20s: node [%x] (%p) taken off worklist",
3295		    __func__, node->nd_ID, node);
3296		/*
3297		 * We have the node. We also take over the reference
3298		 * that the list had on it.
3299		 * Now process as much as you can, until it won't
3300		 * let you have another item off the queue.
3301		 * All this time, keep the reference
3302		 * that lets us be sure that the node still exists.
3303		 * Let the reference go at the last minute.
3304		 */
3305		for (;;) {
3306			item_p item;
3307			int rw;
3308
3309			NG_QUEUE_LOCK(&node->nd_input_queue);
3310			item = ng_dequeue(node, &rw);
3311			if (item == NULL) {
3312				node->nd_input_queue.q_flags2 &= ~NGQ2_WORKQ;
3313				NG_QUEUE_UNLOCK(&node->nd_input_queue);
3314				break; /* go look for another node */
3315			} else {
3316				NG_QUEUE_UNLOCK(&node->nd_input_queue);
3317				NGI_GET_NODE(item, node); /* zaps stored node */
3318				ng_apply_item(node, item, rw);
3319				NG_NODE_UNREF(node);
3320			}
3321		}
3322		NG_NODE_UNREF(node);
3323		CURVNET_RESTORE();
3324	}
3325}
3326
3327/*
3328 * XXX
3329 * It's posible that a debugging NG_NODE_REF may need
3330 * to be outside the mutex zone
3331 */
3332static void
3333ng_worklist_add(node_p node)
3334{
3335
3336	mtx_assert(&node->nd_input_queue.q_mtx, MA_OWNED);
3337
3338	if ((node->nd_input_queue.q_flags2 & NGQ2_WORKQ) == 0) {
3339		/*
3340		 * If we are not already on the work queue,
3341		 * then put us on.
3342		 */
3343		node->nd_input_queue.q_flags2 |= NGQ2_WORKQ;
3344		NG_NODE_REF(node); /* XXX safe in mutex? */
3345		NG_WORKLIST_LOCK();
3346		STAILQ_INSERT_TAIL(&ng_worklist, node, nd_input_queue.q_work);
3347		NG_WORKLIST_UNLOCK();
3348		CTR3(KTR_NET, "%20s: node [%x] (%p) put on worklist", __func__,
3349		    node->nd_ID, node);
3350		NG_WORKLIST_WAKEUP();
3351	} else {
3352		CTR3(KTR_NET, "%20s: node [%x] (%p) already on worklist",
3353		    __func__, node->nd_ID, node);
3354	}
3355}
3356
3357/***********************************************************************
3358* Externally useable functions to set up a queue item ready for sending
3359***********************************************************************/
3360
3361#ifdef	NETGRAPH_DEBUG
3362#define	ITEM_DEBUG_CHECKS						\
3363	do {								\
3364		if (NGI_NODE(item) ) {					\
3365			printf("item already has node");		\
3366			kdb_enter(KDB_WHY_NETGRAPH, "has node");	\
3367			NGI_CLR_NODE(item);				\
3368		}							\
3369		if (NGI_HOOK(item) ) {					\
3370			printf("item already has hook");		\
3371			kdb_enter(KDB_WHY_NETGRAPH, "has hook");	\
3372			NGI_CLR_HOOK(item);				\
3373		}							\
3374	} while (0)
3375#else
3376#define ITEM_DEBUG_CHECKS
3377#endif
3378
3379/*
3380 * Put mbuf into the item.
3381 * Hook and node references will be removed when the item is dequeued.
3382 * (or equivalent)
3383 * (XXX) Unsafe because no reference held by peer on remote node.
3384 * remote node might go away in this timescale.
3385 * We know the hooks can't go away because that would require getting
3386 * a writer item on both nodes and we must have at least a  reader
3387 * here to be able to do this.
3388 * Note that the hook loaded is the REMOTE hook.
3389 *
3390 * This is possibly in the critical path for new data.
3391 */
3392item_p
3393ng_package_data(struct mbuf *m, int flags)
3394{
3395	item_p item;
3396
3397	if ((item = ng_alloc_item(NGQF_DATA, flags)) == NULL) {
3398		NG_FREE_M(m);
3399		return (NULL);
3400	}
3401	ITEM_DEBUG_CHECKS;
3402	item->el_flags |= NGQF_READER;
3403	NGI_M(item) = m;
3404	return (item);
3405}
3406
3407/*
3408 * Allocate a queue item and put items into it..
3409 * Evaluate the address as this will be needed to queue it and
3410 * to work out what some of the fields should be.
3411 * Hook and node references will be removed when the item is dequeued.
3412 * (or equivalent)
3413 */
3414item_p
3415ng_package_msg(struct ng_mesg *msg, int flags)
3416{
3417	item_p item;
3418
3419	if ((item = ng_alloc_item(NGQF_MESG, flags)) == NULL) {
3420		NG_FREE_MSG(msg);
3421		return (NULL);
3422	}
3423	ITEM_DEBUG_CHECKS;
3424	/* Messages items count as writers unless explicitly exempted. */
3425	if (msg->header.cmd & NGM_READONLY)
3426		item->el_flags |= NGQF_READER;
3427	else
3428		item->el_flags |= NGQF_WRITER;
3429	/*
3430	 * Set the current lasthook into the queue item
3431	 */
3432	NGI_MSG(item) = msg;
3433	NGI_RETADDR(item) = 0;
3434	return (item);
3435}
3436
3437#define SET_RETADDR(item, here, retaddr)				\
3438	do {	/* Data or fn items don't have retaddrs */		\
3439		if ((item->el_flags & NGQF_TYPE) == NGQF_MESG) {	\
3440			if (retaddr) {					\
3441				NGI_RETADDR(item) = retaddr;		\
3442			} else {					\
3443				/*					\
3444				 * The old return address should be ok.	\
3445				 * If there isn't one, use the address	\
3446				 * here.				\
3447				 */					\
3448				if (NGI_RETADDR(item) == 0) {		\
3449					NGI_RETADDR(item)		\
3450						= ng_node2ID(here);	\
3451				}					\
3452			}						\
3453		}							\
3454	} while (0)
3455
3456int
3457ng_address_hook(node_p here, item_p item, hook_p hook, ng_ID_t retaddr)
3458{
3459	hook_p peer;
3460	node_p peernode;
3461	ITEM_DEBUG_CHECKS;
3462	/*
3463	 * Quick sanity check..
3464	 * Since a hook holds a reference on it's node, once we know
3465	 * that the peer is still connected (even if invalid,) we know
3466	 * that the peer node is present, though maybe invalid.
3467	 */
3468	mtx_lock(&ng_topo_mtx);
3469	if ((hook == NULL) || NG_HOOK_NOT_VALID(hook) ||
3470	    NG_HOOK_NOT_VALID(peer = NG_HOOK_PEER(hook)) ||
3471	    NG_NODE_NOT_VALID(peernode = NG_PEER_NODE(hook))) {
3472		NG_FREE_ITEM(item);
3473		TRAP_ERROR();
3474		mtx_unlock(&ng_topo_mtx);
3475		return (ENETDOWN);
3476	}
3477
3478	/*
3479	 * Transfer our interest to the other (peer) end.
3480	 */
3481	NG_HOOK_REF(peer);
3482	NG_NODE_REF(peernode);
3483	NGI_SET_HOOK(item, peer);
3484	NGI_SET_NODE(item, peernode);
3485	SET_RETADDR(item, here, retaddr);
3486
3487	mtx_unlock(&ng_topo_mtx);
3488
3489	return (0);
3490}
3491
3492int
3493ng_address_path(node_p here, item_p item, const char *address, ng_ID_t retaddr)
3494{
3495	node_p	dest = NULL;
3496	hook_p	hook = NULL;
3497	int	error;
3498
3499	ITEM_DEBUG_CHECKS;
3500	/*
3501	 * Note that ng_path2noderef increments the reference count
3502	 * on the node for us if it finds one. So we don't have to.
3503	 */
3504	error = ng_path2noderef(here, address, &dest, &hook);
3505	if (error) {
3506		NG_FREE_ITEM(item);
3507		return (error);
3508	}
3509	NGI_SET_NODE(item, dest);
3510	if (hook)
3511		NGI_SET_HOOK(item, hook);
3512
3513	SET_RETADDR(item, here, retaddr);
3514	return (0);
3515}
3516
3517int
3518ng_address_ID(node_p here, item_p item, ng_ID_t ID, ng_ID_t retaddr)
3519{
3520	node_p dest;
3521
3522	ITEM_DEBUG_CHECKS;
3523	/*
3524	 * Find the target node.
3525	 */
3526	dest = ng_ID2noderef(ID); /* GETS REFERENCE! */
3527	if (dest == NULL) {
3528		NG_FREE_ITEM(item);
3529		TRAP_ERROR();
3530		return(EINVAL);
3531	}
3532	/* Fill out the contents */
3533	NGI_SET_NODE(item, dest);
3534	NGI_CLR_HOOK(item);
3535	SET_RETADDR(item, here, retaddr);
3536	return (0);
3537}
3538
3539/*
3540 * special case to send a message to self (e.g. destroy node)
3541 * Possibly indicate an arrival hook too.
3542 * Useful for removing that hook :-)
3543 */
3544item_p
3545ng_package_msg_self(node_p here, hook_p hook, struct ng_mesg *msg)
3546{
3547	item_p item;
3548
3549	/*
3550	 * Find the target node.
3551	 * If there is a HOOK argument, then use that in preference
3552	 * to the address.
3553	 */
3554	if ((item = ng_alloc_item(NGQF_MESG, NG_NOFLAGS)) == NULL) {
3555		NG_FREE_MSG(msg);
3556		return (NULL);
3557	}
3558
3559	/* Fill out the contents */
3560	item->el_flags |= NGQF_WRITER;
3561	NG_NODE_REF(here);
3562	NGI_SET_NODE(item, here);
3563	if (hook) {
3564		NG_HOOK_REF(hook);
3565		NGI_SET_HOOK(item, hook);
3566	}
3567	NGI_MSG(item) = msg;
3568	NGI_RETADDR(item) = ng_node2ID(here);
3569	return (item);
3570}
3571
3572/*
3573 * Send ng_item_fn function call to the specified node.
3574 */
3575
3576int
3577ng_send_fn(node_p node, hook_p hook, ng_item_fn *fn, void * arg1, int arg2)
3578{
3579
3580	return ng_send_fn1(node, hook, fn, arg1, arg2, NG_NOFLAGS);
3581}
3582
3583int
3584ng_send_fn1(node_p node, hook_p hook, ng_item_fn *fn, void * arg1, int arg2,
3585	int flags)
3586{
3587	item_p item;
3588
3589	if ((item = ng_alloc_item(NGQF_FN, flags)) == NULL) {
3590		return (ENOMEM);
3591	}
3592	item->el_flags |= NGQF_WRITER;
3593	NG_NODE_REF(node); /* and one for the item */
3594	NGI_SET_NODE(item, node);
3595	if (hook) {
3596		NG_HOOK_REF(hook);
3597		NGI_SET_HOOK(item, hook);
3598	}
3599	NGI_FN(item) = fn;
3600	NGI_ARG1(item) = arg1;
3601	NGI_ARG2(item) = arg2;
3602	return(ng_snd_item(item, flags));
3603}
3604
3605/*
3606 * Send ng_item_fn2 function call to the specified node.
3607 *
3608 * If an optional pitem parameter is supplied, its apply
3609 * callback will be copied to the new item. If also NG_REUSE_ITEM
3610 * flag is set, no new item will be allocated, but pitem will
3611 * be used.
3612 */
3613int
3614ng_send_fn2(node_p node, hook_p hook, item_p pitem, ng_item_fn2 *fn, void *arg1,
3615	int arg2, int flags)
3616{
3617	item_p item;
3618
3619	KASSERT((pitem != NULL || (flags & NG_REUSE_ITEM) == 0),
3620	    ("%s: NG_REUSE_ITEM but no pitem", __func__));
3621
3622	/*
3623	 * Allocate a new item if no supplied or
3624	 * if we can't use supplied one.
3625	 */
3626	if (pitem == NULL || (flags & NG_REUSE_ITEM) == 0) {
3627		if ((item = ng_alloc_item(NGQF_FN2, flags)) == NULL)
3628			return (ENOMEM);
3629		if (pitem != NULL)
3630			item->apply = pitem->apply;
3631	} else {
3632		if ((item = ng_realloc_item(pitem, NGQF_FN2, flags)) == NULL)
3633			return (ENOMEM);
3634	}
3635
3636	item->el_flags = (item->el_flags & ~NGQF_RW) | NGQF_WRITER;
3637	NG_NODE_REF(node); /* and one for the item */
3638	NGI_SET_NODE(item, node);
3639	if (hook) {
3640		NG_HOOK_REF(hook);
3641		NGI_SET_HOOK(item, hook);
3642	}
3643	NGI_FN2(item) = fn;
3644	NGI_ARG1(item) = arg1;
3645	NGI_ARG2(item) = arg2;
3646	return(ng_snd_item(item, flags));
3647}
3648
3649/*
3650 * Official timeout routines for Netgraph nodes.
3651 */
3652static void
3653ng_callout_trampoline(void *arg)
3654{
3655	item_p item = arg;
3656
3657	CURVNET_SET(NGI_NODE(item)->nd_vnet);
3658	ng_snd_item(item, 0);
3659	CURVNET_RESTORE();
3660}
3661
3662int
3663ng_callout(struct callout *c, node_p node, hook_p hook, int ticks,
3664    ng_item_fn *fn, void * arg1, int arg2)
3665{
3666	item_p item, oitem;
3667
3668	if ((item = ng_alloc_item(NGQF_FN, NG_NOFLAGS)) == NULL)
3669		return (ENOMEM);
3670
3671	item->el_flags |= NGQF_WRITER;
3672	NG_NODE_REF(node);		/* and one for the item */
3673	NGI_SET_NODE(item, node);
3674	if (hook) {
3675		NG_HOOK_REF(hook);
3676		NGI_SET_HOOK(item, hook);
3677	}
3678	NGI_FN(item) = fn;
3679	NGI_ARG1(item) = arg1;
3680	NGI_ARG2(item) = arg2;
3681	oitem = c->c_arg;
3682	if (callout_reset(c, ticks, &ng_callout_trampoline, item) == 1 &&
3683	    oitem != NULL)
3684		NG_FREE_ITEM(oitem);
3685	return (0);
3686}
3687
3688/* A special modified version of untimeout() */
3689int
3690ng_uncallout(struct callout *c, node_p node)
3691{
3692	item_p item;
3693	int rval;
3694
3695	KASSERT(c != NULL, ("ng_uncallout: NULL callout"));
3696	KASSERT(node != NULL, ("ng_uncallout: NULL node"));
3697
3698	rval = callout_stop(c);
3699	item = c->c_arg;
3700	/* Do an extra check */
3701	if ((rval > 0) && (c->c_func == &ng_callout_trampoline) &&
3702	    (NGI_NODE(item) == node)) {
3703		/*
3704		 * We successfully removed it from the queue before it ran
3705		 * So now we need to unreference everything that was
3706		 * given extra references. (NG_FREE_ITEM does this).
3707		 */
3708		NG_FREE_ITEM(item);
3709	}
3710	c->c_arg = NULL;
3711
3712	return (rval);
3713}
3714
3715/*
3716 * Set the address, if none given, give the node here.
3717 */
3718void
3719ng_replace_retaddr(node_p here, item_p item, ng_ID_t retaddr)
3720{
3721	if (retaddr) {
3722		NGI_RETADDR(item) = retaddr;
3723	} else {
3724		/*
3725		 * The old return address should be ok.
3726		 * If there isn't one, use the address here.
3727		 */
3728		NGI_RETADDR(item) = ng_node2ID(here);
3729	}
3730}
3731